Skip to content

Releases: vdavid/cmdr

Cmdr v0.22.0

22 May 23:11
ec3fef6

Choose a tag to compare

Added

  • Redesign Search dialog: re-thought UX, better filters, recent-searches history, persistent state across close+reopen,
    "Show all in main window", per-row context menu, clickable path pills, source-side copy/move/delete from snapshots
    (62aef440,
    ac4c6340,
    b9ca1e6f,
    2c10bba7,
    807e456e,
    1f03ff49,
    f4eea79d,
    e52c6dec,
    d94187bd,
    c79c1112,
    4770a93f,
    e7afc8b3,
    1b1fc5ab,
    71c9485b,
    f3f45084,
    3ea1b45e,
    5c35d9ea,
    9b8f9dd7)
  • Select and copy in the file viewer. Works with files until 100 MB. Goes around our virtual scrolling.
    Double/triple-click for word/line, right-click menu (6f717829,
    1e061820,
    8d6f85c0,
    46f278bb,
    e329bb39,
    1445c2d7)
  • Eject ejectable volumes (USB, SMB, DMG) from the picker and the breadcrumb right-click menu
    (2a7e256f)
  • Replace the human-friendly size units toggle with a 5-way size unit picker (dynamic / bytes / kB / MB / GB)
    (78a7f367)
  • Show climbing bytes and dirs during MTP/SMB scan previews (was "0 / N / 0" until done)
    (c2b5a040)
  • Reuse scan-preview cache for local delete and cross-FS move so the dialog skips straight to the active phase
    (9445e61a)
  • Center child windows on the main window; file viewers cascade
    (8cd06bf4)
  • Tint zebra stripes with the pane bg so per-volume tinting actually shows through
    (b84e761e)
  • Toast confirms zoom changes and points at ⌘0 to reset (37f94410)
  • Show a Space hint on "Toggle selection" in the right-click menu
    (a24613d9)
  • Blue info toasts, new colorless default level for low-importance feedback, and reclassify routine confirmations and
    soft refusals (dabf0e3a,
    51e30112)

Fixed

  • Fix SMB share mis-loading local paths after a volume switch (stale onPathChange poisoned the new volume)
    (3e613ca6)
  • Fix volume copy dialog wedging open after SMB/MTP cancel (0fbafebb)
  • Process selected files in pane sort order, not Cmd+click order
    (39fc8d2e)
  • Cursor lands on the new folder, not the row below (38ebdc87)
  • Fix Full view ".." row hiding behind the header after PageDown/PageUp
    (6ddb4273)
  • Fix viewer ⌘A in ByteSeek-no-index mode freezing on a 9e15-iter loop
    (e29312bd)
  • Land range_read cancellation within ~64 KB, not 16 MB (0e758b46)
  • Fix Escape on viewer context menu closing the whole window
    (4464f766)
  • Honor prefers-reduced-motion in viewer drag autoscroll (aec327b8)
  • Surface silent-band viewer copy failures as a warn toast (41398aca)
  • Polish viewer copy dialogs: ⌘A routes to the right size tier, Enter triggers the primary action, Tab skips ×
    (b6542e7b)

Non-app

  • Build git test fixtures via gix instead of CLI shell-outs; 91 tests went from tens of seconds to ~1.7 s
    (532722c8)
  • Trim slow tests under the 8 s nextest cap, drop the 30 s cap_bundle_* exception, make
    index_mtime_change_invalidates_cache deterministic (f4c0b5ad,
    9e23ff2a,
    44429405)
  • Re-enable three previously-skipped E2E tests; the culprit was a Node fixture-helper dangling-symlink bug
    (915c5f33)
  • Settings-style chrome and a live SMB diagnostics dashboard in the dev Debug window
    (6bd0f15c,
    e7660b3a)

Cmdr v0.21.0

20 May 22:44
326ef00

Choose a tag to compare

Added

Fixed

  • Fix transfer dialog showing "✓ 0 files" when pre-flight scan beat the FE listeners
    (8525835c)
  • Fix stale path events corrupting the breadcrumb after switching a pane to Network
    (a3e15f45)
  • Fix Quick Look toast/content import cycle (b3d67fe6)

Non-app

  • Move rust-toolchain.toml to the workspace root so every crate pins one toolchain (fixes v0.20.0's
    rustup target add drift) (41e999ab)
  • Add workflows-rustup check forbidding rustup target/component add in workflows
    (c68630ee)

Cmdr v0.20.0

20 May 11:25
4b99a40

Choose a tag to compare

Added

  • Cmd+click toggles selection (c6adee74)
  • Bind Insert to toggle selection in Total Commander style
    (719e4f9b)
  • Modify Shift+Arrow/Page/Home/End behavior to align more with other file managers
    (47932132)
  • Switch selection to red. Clears WCAG AA across all backgrounds!
    (9028722c,
    02b295da,
    069bc400,
    14a36dd8)
  • Tint each pane's background by volume type (local/SMB/MTP)
    (3f5629d3)
  • Improve MCP: replace fire-and-forgets with wound-trips (48a9701c,
    3c1b0dc9,
    e12285d1,
    df11caef)
  • New MCP resources: cmdr://logs + filters, cmdr://state filters, recentErrors, upgrade_smb_to_direct, SMB
    connection state (e597d24d,
    640c3330)
  • SMB volumes auto-upgrade from OS-mount to direct smb2 sessions
    (640c3330)
  • Propagate MTP cancel all the way to the USB layer; dialog stays at "Cancelling…" until the device settles. No more
    30-second wedges! (0de4c6b7,
    1696355d,
    f894e60e,
    b4018891)
  • Copy/move/delete pre-flight scans reuse watcher-backed listings. Skip a 17s MTP re-list when the folder is already
    open in another pane! (9d434638,
    ba20ca3e,
    49187230,
    fdebd329,
    b90b9003)
  • SMB streaming writes no longer hold the client mutex (smb2 0.9). Concurrent writes pipeline over one session
    (3d0d5db7,
    06bc5da7,
    ed4b6886)
  • Bump SMB watcher to smb2 0.10 to stop losing events between polls
    (432d13ff)
  • Localize macOS pane names in onboarding and error dialogs (points at what System Settings actually shows)
    (bad5d926)
  • Coalesce directory-diff events with soft-refresh in the FE. No more empty-pane flicker on bulk ops!
    (54674854,
    13b486a8)
  • Honest transfer-complete toasts: report copied vs skipped separately
    (5cdf989e)
  • Friendly message for SMB STATUS_DELETE_PENDING (was misleading "disk needs attention")
    (a560243b)
  • Polish the license nudge: clearer copy and layout (95007952)
  • Add fallback UI colors on macOS Monterey, achieving macOS 12.x compat!
    (5792b10e)
  • Improve accent-fg to match WCAG AA+ against all colors, and add cursor outline
    (d00ba5b4)
  • Properly pluralize all words ("1 file"/"10 files") everywhere
    (eb360370)

Fixed

  • Fix MTP destination pane staying stale after cross-volume writes
    (873f1102)
  • Fix SMB/MTP listing cache going stale when the watcher misses an event
    (1dea24e1,
    ab98ee88)
  • Fix MTP delete not emitting write-cancelled when cancel landed mid-iteration
    (e21ca6d3)
  • Fix transfer dialog wedging at "Cancelling…" when Cancel raced ahead of the operationId IPC
    (2b2a5ec6)
  • Fix MCP open_under_cursor on the Network view (0aec8fbd)
  • Fix Linux startup hanging on a half-configured D-Bus (probes now bounded by a 500 ms timeout)
    (91afacbf,
    85580df9)
  • Fix refresh_listing short-circuiting on local volumes during the FSEvents symlink race
    (57ef1034)
  • Fix two SMB shares with the same case-folded name on different servers colliding on the same volume ID
    (f2414556)
  • Fix opening a guest SMB share popping the kernel smbfs credential dialog
    (92119464)
  • Fix TransferErrorDialog being see-through in the transient branch
    (f01af359)
  • Fix error dialogs rendering OS strings with markdown bleed-through (STATUS<em>DELETE</em>PENDING)
    (dbd7a2ac)
  • Fix Brief mode cursor stripe briefly spanning the entire pane while column widths load
    (d676efa5)
  • Fix Move dialog hiding the Size progress bar (bytes_total was 0)
    (8856e012)
  • Fix conflict-resolution radios reading "Skip all" / "Ask for each" when only one conflict exists
    (4eac76b4)
  • Fix focused-button Enter firing the dialog's default action instead of the focused button
    (079a0ce1)
  • Fix free-space numbers tier-coloring as red on healthy disks
    (8219a06c)
  • Fix the AI offer prompting Intel Macs for a local-model download they can't run
    (52f3cd81)
  • Fix every tokio task crashing when stderr becomes a broken pipe
    (31d97e06)
  • Fix Linux compile errors in errno.rs and mcp/resources.rs
    (90b0afee)
  • Fix Linux compile errors in system_strings.rs (macOS-only loctable items)
    (e852f04a)
  • Fix clippy::unnecessary_sort_by on Linux volume sorting (1.95 picked it up)
    (03faf480)

Non-app

  • Cap every Rust test at 8 s (matches the Playwright convention), with documented exceptions
    (eb67f389)
  • Stop gating desktop-e2e-linux on desktop-rust in CI (66a2e501)
  • Harden the checker against supply-chain attacks: --locked everywhere, pinned tool versions, new
    workflows-hardening + govulncheck checks (7d771ca8)
  • Declare rustfmt and clippy as required rust-toolchain.toml components
    (a23222eb)
  • Trigger Rust CI on rust-toolchain.toml changes (0f8c9ffb)
  • Dev override VITE_CMDR_FORCE_OLD_WEBKIT=1 pnpm dev to test the old-WebKit fallback on modern Macs
    (17537510)
  • 14-day release-age gate via Renovate (3-day override for security advisories)
    (8bd5af1e)
  • Shared pluralize helper for log/error/UI strings, plus a pluralize-noun check
    (0ae2ee92,
    ec277ba8,
    e070fc34)
  • Force file-backed secret store under CMDR_E2E_MODE=1 (no more Keychain prompts in unattended E2E)
    (ecb495fc)
  • New btn-restyle check (forbids .btn-* overrides); accent-matrix in the contrast check
    (51f31939,
    0e885f5d)
  • Codify 100-char Rust comment width; reflow existing comments
    (b76b9277,
    610f66f6)
  • Vendor smb-consumer-maxreadsize and pin the SMB streaming-write no-deadlock invariant (200 × 1 MB at concurrency 8)
    (1ae6eec7,
    e8259eef,
    e750920b)
  • Ticketed acquire/release logs on the SmbVolume client mutex
    (2e4aeb9d)
  • E2E focus hygiene: viewer/settings windows skip OS focus, Escape-binding tests use synthetic dispatch
    (be21bebe,
    0dfdcb2a)
  • Defensive disk-poll + refresh in the MTP→local copy E2E (9693b283)
  • Stamp the running E2E test name into the main window's OS title
    (1181e0c1)
  • Document the UTM Ubuntu VM loop for iterating Linux-only tests
    ([...
Read more

Cmdr v0.19.0

16 May 12:05
4494134

Choose a tag to compare

Added

  • Reorganize Settings into Appearance, Behavior, File systems, Updates, AI, Network, Privacy, and Advanced
    (c3003a05)
  • Add "Overwrite all smaller" and "Overwrite all older" conflict actions
    (2dfd17b8)
  • ⌘⇧T reopens closed tabs; double-click the tab bar opens a new tab
    (65417fbe,
    d7a85a33)
  • Move AI API keys to the OS keychain, with 300 ms debounced save
    (42bc5eaf,
    10f8525b)
  • Command palette recents on empty query (last 10, LRU, grouped, self-heals stale IDs)
    (d3406299,
    a2971aba)
  • Type to jump to a file in the explorer (0b9f943f)
  • Sort-column shortcuts ⌘3–6 (Brief) and ⌘F3–F6 (Full) (74e827e5)
  • Brief mode: backend-computed per-column widths, plus a max-column-width slider
    (d84d5c2a,
    f7907107,
    f9e40fc4,
    e18bdbf4)
  • Volume picker wraps cursor at top and bottom (206ec7d9)
  • USB link-speed indicator in the volume switcher (637b152e)
  • Stream MTP source-scan progress in the copy dialog (no more 0/0/0 freeze)
    (fef1aafd)
  • Bulk-skip pre-known conflicts under Skip-all for copy and move
    (b365076d)
  • MTP→SMB copy: kill the 2-min stall, faster source scan (1ae5c198)
  • Honest copy ETA on long single-file streams: stop decaying files_rate
    (4737acbc)
  • Format sub-1 files/s readouts instead of rounding to 0 (ff7a72f9)
  • Strip em-dashes from user copy and docs; rephrase microcopy to sound more human
    (971e35c4,
    c39ecdc7,
    a16afb0c,
    adab08fa)

Fixed

  • Fix MTP delete freezing instead of showing live scan progress
    (4e005f95)
  • Fix Cancel-copy losing the rollback on the APFS clonefile fast path
    (9c2e6244)
  • SMB upgrade no longer races mDNS in dev (be1350d7)
  • "Connect directly" SMB login dialog now shows the actual server name
    (0d84e4e7)
  • Bulk-skip no longer pollutes the throughput estimator, and only fires for top-level file conflicts
    (55d3ca46,
    c3be95c1)
  • Per-iter Skip on volume copy credits byte progress (e7f657df)
  • Show duration settings in their declared unit (66571349)
  • Brief column-width slider enables inside the Settings window
    (591e090b)
  • Brief mode horizontal scrollbar drag no longer vibrates at 60 Hz
    (b80789e1)
  • Restore focus when a ModalDialog closes and when the command palette closes
    (35413fa3,
    6c45e12d)
  • File viewer surfaces SearchStatus::Cancelled to the FE on cancel
    (14ba2735)
  • Separate MCP ports for prod (19224) and dev (19225) so dev no longer collides with the installed app
    (f0524658)
  • setSetting is idempotent on unchanged values (c49636d8)
  • Pane state: clear network host on leaving the network volume; skip FilePane MCP sync on Network
    (602fcb94,
    a1d19947)

Non-app

Cmdr v0.18.0

11 May 22:32
c47df27

Choose a tag to compare

Added

  • Suppress the 5–10 native macOS TCC popups that stacked behind the FDA onboarding prompt, deep-link to the Full Disk
    Access pane, version-aware copy, Tahoe +-button tip, and a multi-trigger probe that catches kernel short-circuits
    (3c708d35,
    16918218,
    f32dfc55,
    791edff0)
  • Flag TCC-restricted folders live in the sidebar and file list: italic + (i) icon, <no perms> Size, generic folder
    icon for FDA-gated favorites, failed listings stay in nav history
    (7baa9317,
    6581f5ad,
    df6cd794,
    762d7b9a)
  • Defer the AI offer toast until onboarding ends so it stops piling on the FDA prompt
    (265c72d9)
  • Color modified dates by age with per-segment tiers (year, month, day, time each get their own color); App palette is
    now the default (c73fcf54,
    d98459b6,
    be2333c2)
  • Color sizes at every previously-plain site (tooltips, breadcrumb, transfer/delete dialogs, viewer footer, AI progress,
    search results); light-mode palette retuned to clear WCAG AA against every background
    (265c5a0e,
    31128012)
  • Show real scan progress in copy/delete dialogs with running tallies, throughput, current directory, and a real
    progress bar; hardlinks deduped by inode so totals match the indexer
    (03215d25)
  • Honest ETA when files outnumber bytes: tracks both axes, picks the slower; no more "~0 s remaining" while the
    small-file tail drains (16b49a04)
  • Stream folder-name suggestions in the New folder dialog: first option in under 500 ms instead of after the full reply
    (d681c8de)
  • Add multi-provider AI via the genai crate (GPT-5, o-series, Anthropic, Gemini, xAI, Groq, DeepSeek, OpenRouter,
    Ollama); fixes GPT-5 400 on temperature and *-pro/*-codex 404 on chat completions
    (0c45a469)
  • Cap updater hangs at 30 s and surface the real cause (DNS error, TCP deadline) instead of generic "error sending
    request" (e5be1467)
  • Per-row crash email with build mode and short ID, schema migrations, newest-first sort
    (e89a63a3)
  • Stable client-side ID for error reports across dialog, toast, and Discord; env-prefixed R2 keys; [DEV]/[PROD]
    Discord prefix (77260827,
    e1810361)
  • Guard read-only volumes up front for F7/F8/F2 so MTP read-only SD cards warn before you type anything
    (d9212b83)
  • Provider-enriched friendly errors on the write path: MacDroid folders get "Managed by MacDroid…" on move failures;
    dialog renders markdown + category icon, retry shown only when meaningful
    (e9452032,
    51dff4c1,
    5bcacfef)
  • Route every dir-into-dir cross-volume conflict through the resolver so Stop/Skip/Overwrite/Rename works for folders
    too; pin Overwrite-means-merge as an architectural guarantee
    (7ecf9d37,
    2f4e377d)
  • Bump smb2 to 0.8.0 with typed STATUS_OBJECT_NAME_COLLISION and FILE_IS_A_DIRECTORY so merging into an existing SMB
    directory works after a partial copy; fast-path WARNs demoted to debug
    (7dd9cfc8,
    623f8c17)
  • Move MCP defaults to ports 19224 (prod) and 19225 (dev) so a dev build no longer collides with the installed app
    (c9fad17e)
  • Polish getcmdr.com hero: "Download for macOS" button, viewport-responsive illustration mask, muted link style,
    tightened copy (606c724e)

Fixed

  • Fix F8 (and other dialogs) dying after a volume switch: Option fields started serializing as JSON null instead of
    being omitted after the typed-IPC migration; swept === undefined checks across 11 sites
    (f2019aff,
    46bd6d0e,
    eef042d3)
  • Fix one or two rows ellipsizing the Modified column under non-100% text size (sub-pixel glyph-advance drift)
    (a7a7915e)
  • Fix light/dark theme briefly flipping at startup when the persisted choice differed from the system preference
    (f689da01)
  • Stop the dev runtime silently overwriting committed bindings.ts on every pnpm dev launch
    (6e39d68d)
  • Silence the get_file_at FE/BE drift warning that fired legitimately during async listing refreshes
    (0b51a331)
  • Accept null for optional crash-report fields so reports written by older app versions still upload after upgrade
    (3c12ff2f)
  • Stop re-anchoring focus inside selectVolumeByIndex/navigateToPath, which dropped keystrokes mid-sequence in fast
    multi-select (6074cd21)

Non-app

  • Migrate the full IPC surface to typed bindings via tauri-specta; an ESLint rule and a Go check block raw invoke()
    and lockfile drift (f1e58011,
    dc5f0b47)
  • Ban classifying errors by string-matching message/stderr/title with a Go check and ESLint rule; sweep across
    SMB, git, friendly errors, and updater (c764962a)
  • Pin pnpm 11.0.9 in mise.toml and move overrides to pnpm-workspace.yaml; unblocks CI's E2E-Linux
    (cee0aa08,
    c41d2e0d)
  • Track recurring upkeep in docs/maintenance.md with a log going back to 2025-12-25
    (49a119bd)

Cmdr v0.17.0

06 May 21:25
cf94f30

Choose a tag to compare

Added

  • Add dynamic text size slider in Settings (75–150%, ⌘+/⌘-/⌘0 shortcuts)
    (a326bca6,
    ca78382d,
    e207effb)
  • Add "Open with" and system Services to menus (71e6061b)
  • Add iCloud Drive cloud actions to context menu (01bc0dae)
  • Split Brief/Full menu items to per-pane View > Left/Right submenus
    (7f4d123d)
  • Add networking toggle, lazy mDNS, no more local-network prompt at launch
    (d2ae5170)
  • Faster external drive detection, fixes USB-C dock invisibility
    (6527d850)
  • Drag & drop matches Finder (same-volume Move, cross-volume Copy, modifier overrides)
    (64db140f)
  • Drag & drop "+" badge tracks the actual op, no flicker (cf8e3818,
    dcfe439e)
  • Drag files into terminals (Warp etc.) (97d10675)
  • Add Trash/Delete toggle to delete dialog (778296dd)
  • Always show Copy/Move toggle in transfer dialog (450363e6)
  • Default to Full mode on fresh installs (57ba47c1)
  • File list typography polish: aligned dates, aligned headers, fade selection, clamped Ext
    (474f7414,
    e9aec7bd,
    88f56367,
    c5698998)
  • Add size-color palette setting (Rainbow / Accent / None) (5fe0d77e)
  • Restore double-click-to-zoom on macOS title bar (f95441dc)
  • Focus search when Settings opens (cb88685d)
  • Hand cursor on License dialog support and Buy links (554b3801)
  • Show real .git/* files alongside virtual categories in git portal
    (33219321)
  • Per-file Modified dates inside git portal snapshots (3cead878)
  • Cache git status per index change, near-instant repeat navs
    (19f0e98e)
  • Error-report preview now lands under 200 ms on big log dirs (was 30+ s)
    (f24f255c)
  • Send error reports in dev too, tagged [DEV] (63ebabf6)
  • Persistent "Save bundle to disk" toast with Reveal in Finder
    (0debff1c)
  • getcmdr.com comments follow live theme changes (7333b13c)

Fixed

  • Fix Intel DMG download 404 (19f797da)
  • Fix crash on virtual git portal toggle; empty git roots no longer render as 1970-01-01
    (b266737e)
  • Fix folder size column losing value after rename (b1d032c1,
    d7e08e16)

Non-app

  • Big dead-code cleanup, 355 lines across 22 files (a6b46131)
  • Bump GitHub Actions to Node 24 (2f02fa7e)
  • Replace claude-md-staleness with claude-md-reminder (fires in-loop, not weeks later)
    (60e30be5)
  • Big CHANGELOG cleanup: shorten long items and document style guidelines.
    (8f3daa0a)

Cmdr v0.16.0

01 May 22:06

Choose a tag to compare

Added

  • SMB live reconnect. When the smb2 session for a network share drops, Cmdr now stays in the folder and runs a
    5-attempt backoff cycle (2/4/8/16/30 s, 60 s total) right inside the pane. Both panes on the same share share a single
    cycle; success re-runs loadDirectory automatically; give-up swaps to the existing unreachable banner with a working
    Disconnect button. The session rebuilds in place — same SmbVolume, same volumeId, same Full Disk Access
    permissions, no re-auth — because connection params now cache for the volume's lifetime. Concurrent operations wait on
    a single-flight reconnect lock instead of dog-piling the server. Auth failure re-pulls credentials from the secret
    store and retries once before giving up. Unmount mid-cycle short-circuits cleanly so a fresh session never lands in an
    orphaned volume. The reconnect view shows an attempt counter and a progress bar driven by requestAnimationFrame, and
    three buttons with disambiguating tooltips: Retry now, Cancel, Disconnect
    (d96bc4b4,
    0c1d3680).

  • Disconnect actually disconnects. Previously the Disconnect button in SmbReconnectingView and the gave-up
    unreachable banner behaved like a fancy Cancel. Now it runs a real per-volume unmount: diskutil unmount on macOS
    (FSEvents picks up the unmount and tears down VolumeManager), smb2-session drop on Linux. If diskutil returns
    "Resource busy" because Finder has the volume open, the user sees an actionable toast instead of silent failure
    (c5a410aa).

  • Check for updates from inside the app. Two new affordances, both reading the same shared update state:

    • Settings > Updates: a "Check for updates" button at the top of the section, disabled while a check is in flight,
      with status text below cycling through Checking…No updates found. Current version: vX.Y.Z
      Update found, downloading vX.Y.Z (current: vA.B.C)…Installing vX.Y.Z (current: vA.B.C)…. On error, a "Send
      error report" link opens the error reporter pre-populated with the failure context.
    • Cmdr menu > Check for updates… (right after "Enter license key…"): same status flow, surfaced as a toast that
      supersedes itself as the phase changes and dismisses cleanly when the persistent restart toast takes over.

    The macOS update path now exposes a separate installing substate — the custom updater runs download_update and
    install_update as two distinct Tauri invokes, so the UI can say "Installing" instead of a misleading "Downloading"
    during the sync-into-bundle step (00470b96).

  • Human-friendly size units toggle. New Settings > Listing > Human-friendly size units switch. Default ON shows
    1.02 MB-style values; OFF shows raw bytes with thousands separators for precise comparison. Affects the Full list
    size column and the SelectionInfo size readout. Tooltips that already showed both formats are unchanged on purpose,
    and so are volume/disk space, dialogs, search results, and the drive-indexing section
    (c8cc1008).

  • Symlink-aware size hint. Folders containing symlinks anywhere in their tree now show a small info icon next to the
    size with the tooltip "This folder contains symlinks. Symlinked content is not counted in the total to avoid double
    counting." Cmdr's recursive size aggregation matches du and Finder by intentionally skipping symlink targets, so a
    folder of only symlinks reports 0 bytes — surfacing that fact removes a frequent "huh?" moment. The flag
    (recursive_has_symlinks) propagates bottom-up alongside size totals; the index schema bumped to v10 to carry it
    (0d83a7b2).

  • AI download toast: clear close affordance. The X on the "Downloading AI model…" toast now has the tooltip "Close
    this notification — the download will continue in the background", and clicking it actually keeps the toast hidden for
    the rest of the download run — previously ai-toast-sync re-added it within ~200 ms because the next
    ai-download-progress event re-ran its $effect. Cancel still cancels
    (97f1cee3).

  • Rename: skip warning for equivalent file extensions. Renaming foo.jpgfoo.jpeg (or htm/html,
    yml/yaml, tif/tiff, mpg/mpeg, mid/midi, aif/aiff, qt/mov, md/markdown/txt) no longer
    trips the "you're changing the file type" confirmation. Cross-group changes still warn
    (55592ba4).

Fixed

  • Brief network blips no longer kick you out of the folder. A few seconds of bad WiFi on a NAS share used to trigger
    the directory-eviction poll and "navigate to nearest valid parent" mid-session. The pathExists Tauri command now
    returns a structured TimedOut<bool> result and is SMB-aware (a Disconnected SmbVolume reports timed-out
    instantly, no syscall timeout fires). The eviction logic in FilePane only walks up on a real not-found
    (48ac9bf8).
  • Update toast no longer interrupts onboarding. New isOnboarded flag (default false) gates the "restart to
    update" toast during first-launch onboarding. Same gate covers the FDA-revoked re-prompt path. Background download
    still runs — only the toast surface is deferred — so the update is ready the moment onboarding finishes
    (ffeb7d96).
  • Indexer no longer triggers macOS permission popups during onboarding. Recursive scan from / was being kicked off
    in setup() regardless of FDA state, stacking iCloud/Photos/etc. native dialogs over our in-app explanation modal.
    The indexer now waits until the user has either granted FDA (and restarted, where the launch-time OS check passes the
    gate) or explicitly clicked Deny (59aca717).
  • SMB reconnect: runaway subscribe loop after hot reload. Both panes stuck on "Loading…" with thousands of
    subscribe/unsubscribe pairs per second from the reconnect manager. Caused by SvelteMap.get reads inside a Svelte
    $effect becoming tracked deps that the manager's own writes invalidated, looping forever. Map-mutating methods now
    run inside untrack() so caller $effects don't pick up internal reads
    (91bc2e46).
  • SMB reconnect: onSuccess could fire twice in one cycle. Both runAttempt's success branch and the
    smb-connection-changed listener could call handleDirect, double-triggering loadDirectory in FilePane. The
    handler is now guarded by a baseline-shape check and is safely idempotent
    (3f6b1b0d).

Non-app

  • Release script now stages oxfmt auto-fixes alongside the version bumps (via git add -u after the bump-stage
    plus a second oxfmt --ci pass), so any pre-release .claude/commands/*.md reformats end up in the release commit
    instead of failing CI on the release tag (d523e236).
  • Three pre-existing eslint warnings the SMB work surfaced when running the full check matrix end-to-end — unused
    helper, async-without-await, redundant optional chaining — fixed so CI is green again
    (5e4eb307).
  • Tier-3 a11y test for UpdateCheckToastContent; new module-level CLAUDE.md section in file-explorer/network/ that
    ties together the four moving parts of the SMB live-reconnect dance (BE event → volume-store patch → reconnect manager
    → FilePane effect) so the next agent doesn't have to reverse-engineer it
    (e8656bb9,
    a3638ee7).
  • Skip the flaky git-portal toggle E2E (the toggle round-trip was too racy for the 30 s Playwright budget); Rust unit
    tests cover the underlying behavior. Retire when we have a "wait for portal state to settle" hook
    (129c27ce).

Cmdr v0.15.0

29 Apr 09:37

Choose a tag to compare

Added

  • Git browser. Cmdr now treats every git repo as first-class. Five things you can do that you couldn't before:
    • See branch + dirty state at a glance. Open a folder inside a git clone and the breadcrumb shows a pill with the
      current branch, ahead/behind counts vs upstream, and a dirty indicator. Detached HEAD shows the short SHA; brand-new
      repos show "no commits yet". The pill updates live as you commit, fetch, or branch from a terminal, no polling, no
      refresh button.
    • Browse history as folders. Step into .git and see branches/, tags/, commits/, stash/, worktrees/,
      submodules/, plus a raw/ escape hatch for the real .git internals. Drill into branches/main/ (or
      commits/<sha>/) and you're browsing the working tree at that point in history. Refs with slashes like
      feature/foo render as one entry, not nested folders. Breadcrumb segments inside the portal use a dedicated
      git-portal color so it's clear you're in history-land.
    • Pluck a single file from another branch or commit. Drag a file out of the history pane into the working tree.
      Cmdr preserves the bytes and the executable bit. No git checkout, no risk of touching anything else. Type or paste
      any SHA directly to reach unreachable commits, even in shallow clones.
    • Open linked worktrees and submodules with one keypress. Each shows as a redirect entry; opening it jumps
      straight to its working dir, which is itself a git portal. Turtles all the way down.
    • Show per-file git status in Full mode. Optional column with single-glyph codes (M, A, D, ?, !) and
      long-form aria-labels for screen readers. Off by default; enable in Settings > General > Git
      (314e9ae2,
      897df2c7,
      1ebcfa1c).
  • Meaningful Modified and Size columns inside the git portal. Every virtual entry carries a real timestamp (branch
    tip date, tag date, commit date, stash creation date, snapshot date for files inside a tree). The Size column borrows
    loose semantics so each row says something useful: +12 / -3 ahead/behind for branches, 5 files for commits,
    on main for stashes and worktrees, short SHAs for tags and submodules, item counts for category roots. Tooltips and
    aria-labels carry the long-form sentence (31aec35c).
  • Friendly errors for the git browser. Whatever goes wrong (the repo's damaged, the worktree's orphaned, the commit
    is beyond a shallow boundary, the .git folder isn't readable, the file's too big to load from history, another git
    command holds the index), Cmdr shows a warm, plain-language explanation in the error pane plus a concrete next step,
    not a raw stack trace (19d5b075,
    af64689f).
  • Toggle each piece independently. Three switches in Settings > General > Git: show the repo chip, show the
    status column, and show the virtual portal. Disabling the portal lets .git browse like any other folder; the toggle
    invalidates open listings live so already-visible panes refresh on the spot
    (19d5b075,
    af64689f).

Fixed

  • Virtual .git/<category>/... paths no longer kick the user back to the parent after a few seconds. The frontend's
    externally-deleted-directory poll and the backend's notify watcher both used to assume the listed path exists on
    disk; both now skip the seven virtual git categories and rely on the per-repo .git/HEAD and refs/ watchers for
    invalidation (bfcbfa48).

Non-app

  • Release process docs now require a runner sanity check 30 s after pushing the tag, watch the standalone CI run in
    parallel, and verify the public surface (DMG count, latest.json version) once the release run reports complete.
    Lifted from the prvw release flow.

Cmdr v0.14.0

26 Apr 19:05

Choose a tag to compare

Added

  • Error reports. When something goes wrong, you can now ship a redacted diagnostic bundle (manifest + recent
    debug-level log tail) to the maintainer with one click. Two flows: Help > Send error report… (or the new button on
    error toasts) opens a preview dialog so you see exactly what's about to be sent, and clicking Send is the consent;
    no setting required. Optionally, opt in to auto-send via the new updates.errorReports setting (default off) — when
    enabled, user-visible errors fire a debounced auto-send and a toast lets you view the bundle or change settings. Every
    bundle goes through the shared path-shape-preserving redactor (Documents/<file>.pdf style). Reports are anonymous —
    the short ERR-XXXXX ID is the only correlation handle.
  • Log storage cap setting. New advanced.maxLogStorageMb (default 200 MB, range 0–5000) controls how much disk
    space the rotated log files use. The file target now defaults to debug level so error reports carry useful
    context. Set to 0 to disable log storage entirely (and with it, the ability to send error reports).
  • Per-output log level filtering. Stdout stays at INFO with optional RUST_LOG-style per-module overrides while the
    on-disk file chain always captures DEBUG, so error reports carry useful context without flooding the terminal. The
    developer.verboseLogging toggle now flips the stdout threshold at runtime (Info ↔ Debug) without losing records
    mid-swap. Replaces tauri-plugin-log with a hand-rolled fern Dispatch tree + file-rotate for native size+count
    rotation (319d5d37).

Fixed

  • Auto-dispatcher race when an error fired before the Tauri AppHandle was wired up — the debounce window opened with
    no handle to send the report, so the bundle never shipped. Late-arriving handles now pick up active windows correctly
    (f069a712).
  • Size column icons now align flush with the cell's right edge instead of drifting a pixel inwards
    (1d5f661a).

Non-app

  • Bumped 24 npm packages (patch + minor; TypeScript held at 5.9). pnpm dedupe collapsed duplicate postcss and
    @playwright/test versions, fixing stylelint false positives in inline style="..." attributes and a
    Page-type mismatch in website-typecheck. Split resolveValidPath into a new path-resolution.ts to break an
    app-status-store.tspath-navigation.ts import cycle. Per-test unique paths fix a rust-tests-linux collision
    under higher parallelism (b1a53acb).
  • New error-report endpoint on the api server with R2 presigned-URL handoff, daily eviction sweep, and a dedicated
    ERROR_REPORT_META KV namespace separate from LICENSE_CODES
    (1a2ea1c0,
    f78f76af).
  • Shared PII redactor for both crash files and error-report bundles — single source of truth so log lines redact
    identically wherever they're inspected. Adds a per-bundle salted-hash mode (<dir:abc123> / <file:abc123>) for
    in-bundle correlation without cross-bundle linkability, plus an mtp_owner pattern that strips <Owner>'s <Model>
    shapes while preserving the model string for diagnostic context
    (1d719f36,
    b64e2c2c).
  • desktop-rust-log-error-macro check fails CI on any raw log::error! outside the macro definition itself, so every
    error site routes through the Flow B auto-dispatcher
    (79bc2a28).
  • changelog-commit-links check now also verifies every linked SHA is reachable from HEAD, catching commits that got
    dropped from history (rebase, force-push, etc.) before they ship
    (72375de6).
  • releasing.md documents the caffeinate -dimsu requirement during release builds — the self-hosted runner lives on
    the dev Mac and any sleep drops the runner connection mid-build
    (9f27228d).
  • Bumped rustls-webpki 0.103.12 → 0.103.13 for routine security maintenance
    (9ff7583d).

Cmdr v0.13.0

23 Apr 05:11

Choose a tag to compare

Added

  • SMB copies are ~30× faster on high-latency links. A 100 × 10 KB copy from a NAS over Tailscale (~60 ms RTT)
    dropped from ~28 s (~280 ms/file) to 947 ms (9.5 ms/file) over four layered speedups: drop redundant is_directory
    stat probes in the copy pipeline (Fix 1, 94090555), send
    CREATE+READ+CLOSE / CREATE+WRITE+FLUSH+CLOSE as a single compound frame for small reads/writes (Fix 3,
    9d6df0e9), unblock session-level concurrency by cloning
    smb2::Connection per download (Fix 2, 4009b9ba), and pipeline the
    pre-copy scan-phase stats over one SMB session (Fix 4, 77ea6e81).
    Effective concurrency 16× on the 100-file workload. Full analysis in docs/notes/phase4-rtt-investigation.md.
  • network.smbConcurrency setting (Phase 4.3) — controls how many concurrent SMB operations run per session for batch
    copies. Default 10, range 1–32. Applies immediately without restart
    (7fdd85e3,
    aa331c4e,
    f46d45e4).
  • Current folder's total on the .. row — shows recursive size, file count, and dir count for the folder you're in (not
    the parent), with the same tooltip and size-mismatch indicators as any directory row
    (36212ede).
  • Full mode shrink-wraps Ext / Size / Modified columns to give the name column every spare pixel. Width changes animate
    over 300 ms, dir switches snap. The .. row's huge recursive size only counts toward column width while actually
    on-screen (7325c8f8).
  • Brief mode shrink-wraps each column to its widest visible filename, capped at maxFilenameWidth and floored at
    MIN_COLUMN_WIDTH. 300 ms width transitions, nav snaps (c336dbba).
  • Filename tooltip on truncation — hover a clipped filename in Brief or Full mode to see the full name. In Brief mode,
    directories combine the full name with the existing dir-size tooltip
    (f37d7e51).
  • Volume tooltip on tabs — every tab now shows {volume name} — {full path} on hover, so you can tell at a glance
    whether a tab is local, external, or on a cloud volume (b6663988).

Fixed

  • Security: smb2 bumped to 0.7.2, which fixes an off-by-2 in the DFS referral V2 response parser that let any
    DFS-enabled server (malicious or buggy) crash cmdr with a crafted referral. Caught by cargo-fuzz
    (7e7eaf76).
  • Canceling a small SMB upload now actually cancels — the compound write fast-path used to silently drain the source,
    send the WRITE, and only then honor the cancel flag (which it ignored entirely). Now checks cancellation per chunk
    during drain and aborts before any bytes touch the wire; progress callbacks fire during the drain instead of only once
    post-write (f948731c).
  • Clicking a file already under the cursor no longer eats the drag — the click started the click-to-rename timer and
    returned early before drag tracking could arm. Grabbing the cursor item (alone or as part of a selection) now drags
    correctly; rename timer cancels once the drag threshold is crossed
    (cccf0095).
  • ⌘C now copies selected text instead of files when there's a non-collapsed text selection. The global shortcut dispatch
    was intercepting ⌘C unconditionally, blocking native text copy in panes like the error pane where user-select: text
    is set (47f03b20).
  • Drag & drop blocks dropping a folder onto itself or into its own descendants, with "Can't drop here" feedback instead
    of letting the drag through and producing a backend error. The .. row accepts drops as a normal parent-folder target
    (b7c3d960).
  • Frontend hot reload is reliable again after swapping UnoCSS for unplugin-icons — UnoCSS's dev plugin was regenerating
    virtual:uno.css on every Svelte save, triggering SvelteKit's root-layout TDZ crash (sveltejs/kit#15287). Icons now
    import as tree-shaken inline SVG components via ~icons/lucide/{name}
    (00906566).

Changed

  • Breaking (internal API): The Volume trait no longer exposes export_to_local and import_from_local. Every
    cross-volume copy now flows through open_read_stream + write_from_stream (or the APFS clonefile fast path when
    both sides are LocalPosixVolume on the same volume). Adding a new volume backend takes two streaming methods instead
    of four, and concurrency (Phase 4.2) plugs into one dispatch point. Only in-tree consumer was volume_copy.rs; no
    external crates depended on the removed methods. See docs/notes/phase4-volume-copy-unification.md.
  • Cross-volume batch copies now run up to N streams in parallel instead of one-at-a-time. N is
    min(source.max_concurrent_ops(), dest.max_concurrent_ops(), 32)SmbVolume returns 10 (tunable via
    network.smbConcurrency), LocalPosixVolume returns physical-core-ish clamped to 4..=16, MtpVolume returns 1,
    InMemoryVolume returns 32. Batches of 1–2 items stay sequential. New trait method
    Volume::max_concurrent_ops() -> usize (default 1) lets each backend advertise its parallelism. Abort-on-first-error
    and cancel-under-concurrency preserve existing semantics; partial-file cleanup walks every in-flight task's
    destination.
  • Volume::scan_for_copy_batch now returns BatchScanResult { aggregate, per_path }, so the copy engine populates its
    source_hints map from one trait call instead of re-probing each source. SmbVolume overrides to pipeline all
    per-path stats over one SMB session via FuturesUnordered on cloned Connections
    (77ea6e81).
  • Volume::open_read_stream_with_hint(path, size_hint) added to the trait (default falls through to
    open_read_stream). SmbVolume uses it to pick the compound read fast-path when the caller knows the file fits in
    one READ (9d6df0e9).
  • smb2 dependency moved from git source to crates.io (96f4bbd3),
    then bumped through 0.7.1 (adds Tree::download for concurrent streaming reads on a cloned Connection,
    0ec95a79) and 0.7.2 (DFS referral parse fix,
    7e7eaf76).

Non-app

  • Docker SMB integration tests now run on every push. New desktop-rust-integration-tests check starts the core SMB
    containers, runs the 26 smb_integration_* tests, and stops the containers on exit. Closes the gap that let the
    compound-write cancel/progress bug sit undetected on main for four days
    (257269bb).
  • Byte-level blake3 hash verification on every existing SMB copy test — destination bytes now compared to source, not
    just size or return value. Three tests previously only verified metadata; four large-file tests upgraded from
    multi-megabyte Vec<u8> equality to streaming hash with hex-pair mismatch output
    (fd5a2d84).
  • 100-way concurrent copy cross-contamination guard — 100 files with unique blake3(b"cmdr-fix8-" || i) content copied
    through the real copy_volumes_with_progress pipeline (same path production uses), per-index verified. Catches buffer
    reuse across tasks, wrong-buffer-to-wrong-path routing, and MessageId demux swaps on cloned Connections that
    identical-content tests can't see (97062e64).
  • SMB copy soak harness — smb_soak_copy_loop test plus scripts/soak-smb.sh wrapper and workflow_dispatch-only CI
    job. 30-min Docker-based run completed 41,984 iterations with zero drift in wall-clock, memory, file descriptors, or
    SMB credits (3a9b58f2,
    6a9e046d).
  • Settings live-apply is now a documented MUST rule — every setting applies immediately without restart. Rule lives in
    both Rust and TS settings CLAUDE.md files with explicit recipes for adding new settings. Restart-required is now
    formally a bug (cd1958ba).
  • Deflaked two intermittently-failing tests (test_dir_name collision under parallel nextest execution,
    hidden-file-toggle Playwright E2E race), bumped multi-chunk SMB stream test sizes past the 8 MB max_read_size Samba
    negotiates, and added env_logger as a dev-dep so SMB wire-trace logging works in integration and bench tests
    (a48a323e,
    f7823a0b,
    009b851e,
    75f856e8).
  • changelog-commit-links check validates every https://github.com/vdavid/cmdr/commit/<sha> URL in CHANGELOG.md
    resolves to a real commit, via a single git cat-file --batch-check process — catches typos, truncated SHAs, and
    prefixes ambiguous with trees before they land. Runs in the desktop-svelte, website, and api-server CI jobs (each does
    a full-depth checkout so historical SHAs resolve). Surfaced and fixed 8 bad links in the 0.12.0 and earlier sections
    along the way ([d488dfa](https://github.com/vdavid...
Read more