This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SplitCommander is a keyboard-first, two-pane file manager for macOS with directory comparison. Built with Tauri v2 (Rust backend) and Svelte 5 + TypeScript (frontend). Currently read-only (comparison only, no write operations).
# Install frontend dependencies
npm install
# Run in development mode (launches Tauri dev window)
npm run tauri dev
# Build for production
npm run tauri build
# Run Rust tests (27 tests covering model, scanner, comparator, ignore, security, export)
cd src-tauri && cargo test
# Run a single Rust test
cd src-tauri && cargo test test_name
# Check Rust compilation
cd src-tauri && cargo check
# Lint Rust
cd src-tauri && cargo clippy
# Build frontend only
npx vite build
# Type-check Svelte/TS
npm run check- Rust backend (
src-tauri/src/): filesystem scanning, comparison engine, event emission, JSON export - Svelte 5 frontend (
src/): UI rendering, receives events from Rust via Tauri event system
- Commands (UI → Rust):
set_root,start_compare,cancel_compare,get_diffs,get_summary,export_report - Events (Rust → UI):
scan-progress,compare-done,compare-error
Three-phase comparison pipeline:
- Scan (
scan.rs): Walk both roots with jwalk (parallel), buildHashMap<String, EntryMeta>, emit progress events - Metadata compare (
compare.rs): Diff classification → OnlyLeft, OnlyRight, TypeMismatch, Same, MetaDiff - Deep verify (
hash.rs): BLAKE3 hashing (planned for v0.2)
Key modules:
model.rs— EntryKind, EntryMeta, DiffKind, DiffItem, CompareMode, CompareSummary (allserde(rename_all = "camelCase"))scan.rs— parallel directory walking with jwalk, cancellation via AtomicBool, progress callbackscompare.rs— Structure mode (presence+type) and Smart mode (presence+type+size+mtime)ignore.rs— glob rules + macOS noise preset (.DS_Store, ._, .Spotlight-V100, etc.)security.rs— root confinement via canonicalize + starts_withexport.rs— JSON report generation with chrono timestampscommands.rs— Tauri command handlers, AppState with Mutex-protected fieldsevents.rs— event payload types and name constants
- Svelte 5 runes for reactive state (
$state,$derived,$effect) lib/stores/compare.svelte.ts— central CompareStore class with all state and actionslib/types.ts— TypeScript mirrors of Rust model types- Components: TopBar, FilePane (with manual virtual scrolling), DiffBadge, DiffDetails, BottomBar, ProgressIndicator
- FilePane implements manual windowing (ROW_HEIGHT-based) for 200k+ file lists
- Read-only until explicit write mode toggle
- Filesystem access in Rust only: UI stays unprivileged
- Case-insensitive path keys (macOS): lowercased HashMap keys, original case preserved separately
- Symlinks: not followed; compared by target text
- Directories always Same in Smart mode (size/mtime not meaningful for dirs)
- Every long operation accepts a cancellation token (AtomicBool)
- Progressive results: scan progress streams via events, diffs retrieved after compare-done
- Dark theme: CSS custom properties for consistent theming