# FilePilot (CLI prototype) This is a working prototype of FilePilot's bulk rename engine: regex-based find/replace renaming and sequential renumbering of files, both with a collision-safe dry-run-by-default workflow (nothing touches disk until you pass --apply, and an entire rename batch is validated for name collisions before a single file is renamed). FilePilot's full product concept is a dual-pane file manager with an instant launcher/search, live previews, and configurable rename rule chains; NONE of that is implemented here. Instant launcher/search is covered by the sibling tool FindPilot. See ../plan.md for the full product plan and roadmap. ## Build from source Requires Go 1.24+, no external dependencies. go build -o filepilot . Cross-compile for another platform: GOOS=windows GOARCH=amd64 go build -o filepilot.exe . GOOS=darwin GOARCH=arm64 go build -o filepilot . ## Usage filepilot rename --match "REGEXP" --replace "TEMPLATE" [--recursive] [--apply] filepilot sequence --pattern "photo-{n}.jpg" [--start 1] [--pad 3] [--sort name|mtime] [--apply] filepilot help ### rename Regex find/replace on file basenames. --match STRING Go regexp matched against each file's BASE NAME (not full path). Only immediate children of are considered unless --recursive is given. --replace STRING Replacement template using Go's regexp ReplaceAllString syntax: $1, $2, ${name} refer to capture groups from --match. --recursive Walk the entire subtree of instead of just its immediate children. --apply Actually perform the renames. Without this flag, filepilot only prints the planned renames (dry run). For each file whose basename matches --match, FilePilot computes the new basename by applying --replace, keeping the file in the same directory. Files whose computed new name is identical to their old name are skipped as no-ops. Before renaming anything, FilePilot builds the full list of planned (old path -> new path) renames and validates it: - if two different source files would produce the same new path, that is a COLLISION - if a planned new path already exists on disk as a file that is not part of the rename batch itself, that is also a COLLISION If any collision is found, FilePilot prints every collision it found, exits nonzero, and renames NOTHING. Only after validation passes with zero collisions does it either print the dry-run plan (no --apply) or perform every rename (--apply). Example: filepilot rename ./photos --match "IMG_(\d+)\.JPG" --replace "photo_$1.jpg" filepilot rename ./photos --match "IMG_(\d+)\.JPG" --replace "photo_$1.jpg" --apply ### sequence Renumbers a batch of files sequentially - the classic "renumber this photo dump" use case. --pattern STRING Output name template. The literal token "{n}" is replaced with the zero-padded counter for each file; everything else in the pattern is kept as-is. The file extension is NOT auto-appended - include it explicitly in the pattern, e.g. "photo-{n}.jpg". --start INT Starting counter value (default 1). --pad INT Zero-pad width for the counter (default 3, so counter 7 with pad 3 becomes "007"). --sort STRING Order files are numbered in: "name" (alphabetical basename, default) or "mtime" (modification time, ascending). --apply Actually perform the renames. Without this flag, filepilot only prints the planned renames (dry run). Only files directly inside are considered (non-recursive). Files are sorted per --sort, then each is assigned the next counter value starting at --start, zero-padded to --pad digits, substituted for "{n}" in --pattern. The same collision-detection-before-any-rename safety as the rename command applies: a sequence plan will not realistically collide with itself (counters are unique per file), but a collision with a pre-existing file outside the batch is still possible and will abort the whole batch before anything is renamed. Example: filepilot sequence ./photos --pattern "photo-{n}.jpg" --start 1 --pad 3 --sort mtime filepilot sequence ./photos --pattern "photo-{n}.jpg" --start 1 --pad 3 --sort mtime --apply ## Prebuilt binaries See ../downloads/ for prebuilt binaries (Windows/macOS/Linux) and CHECKSUMS.txt for their SHA-256 hashes. These are unsigned indie builds - Windows SmartScreen and macOS Gatekeeper will warn on first run, which is expected until a code-signing certificate is in place.