Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 234 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,240 @@

All notable changes to spyc. Entries from v1.57.0 onward are generated from the conventional-commit history by [git-cliff](https://git-cliff.org) (config in `cliff.toml`); regenerate the pending section with `make changelog` and cut a release with `make release-prep` then `make release-tag` (see `docs/RELEASE_ENGINEERING.md`). Entries at v1.56.0 and earlier are the original hand-written log, kept verbatim.

## [2.2.0] - 2026-10-15

### Features
- **markdown**: Outline folding and heading motions in the pager (#439)
- **build**: Spyc-vt-sys — pinned libghostty-vt FFI with vendored archives (#459)
- **pane**: Swap the pane's terminal engine to libghostty-vt (#465)
- **pane**: Startup tabs from .spycrc.toml + fit every tab in the bar (#482)
- **activity**: Transparent activity HUD, with `:activity solid` for the old bands (#497)
- **config**: A project's startup tabs open after you approve that exact list (#496)
- **mcp**: Get_spyc_context answers for the calling agent's own pane (#507)
- **activity**: List MCP connections and the tabs they're bound to (#508)
- **pane**: ^a F forks the active tab's conversation into a new tab (#516)
- **config**: Prompt templates type a named message into the pane (#517)
- **status**: The status bar shows only the column state that differs from rest (#521)
- **keymap**: `.spycrc.toml` binds any action by name, and `unmap` silences a key (#527)
- **jump**: J offers the newest path the pane printed (#529)
- **cli**: `spyc -c <cmd>` runs a `:` command once spyc has started (#534)
- **pane**: Answer a child's terminal queries with what is true of the pane (#486) (#594)
- **pane**: ^a s ends a directory path in / (#599)
- **prompts**: A directory in a prompt template ends in / (#600)
- **pane**: :why-status explains the active tab's dot in the pager (#609)
- **pane**: An agent launched in a shell tab can reach spyc and name its tab (#612)
- **pane**: A shell tab follows the agent running in its foreground (#613)
- **pane**: An agent key on [[pane.tab]] names the agent a wrapper command runs (#616)
- **codex**: Show image attachments in the pane gallery (#617)
- **wiring**: Spyc --install-agents wires claude and agy into their own user configuration (#625)
- **wiring**: Spyc --install-agents wires codex too, with hooks that never move (#626)
- **mcp**: Spyc --mcp serves only the agents spyc launched (#627)
- **wiring**: Spyc takes out the project copies older spycs left for an agent wired in user scope (#632)
- **wiring**: Agents are wired into spyc in their own configuration, once each, and never per project (#634)
- **codex**: Add bounded rollout metrics collector and reducer (#647)
- **agent**: A `waiting` dot for an agent whose background work will wake it (#651)
- **claude**: Bounded transcript metrics reducer (#653)
- **claude**: Follow a live transcript with a bounded reader and watch (#655)
- **codex**: Show an opt-in native session HUD (#656)
- **claude**: Show the agent HUD for Claude Code tabs (#657)
- **agent**: Lay the agent HUD out in aligned, coloured columns (#660)
- **agent**: Collapse the HUD's tools row and open its dump on double-click (#662)
- **claude**: Plan usage and context % on the agent HUD, via the statusline (#664)
- **agent**: Mark each top tool with its own failures, cap branch width (#665)
- **claude**: A todo cell on the agent HUD, from TaskCreate/TaskUpdate (#666)
- **agent**: Breathe the working dot in 16 eased steps instead of 4 colours (#673)
- **agent-hud**: Native strip for Antigravity (agy) tabs (#674)

### Bug Fixes
- **graveyard**: Point the size warning at `:graveyard`, purge to trash without Finder automation, and stop the chrome copy echo rewriting its own row — plus double-click a chrome row to copy the whole line (#434)
- **markdown**: Render what the parser already knew — fences, front matter, alerts, table alignment (#436)
- **clipboard**: The detach test raced thread scheduling, not the helper (#440)
- **apt**: Stop the signed index asserting a hash Release can never have (#443)
- **config**: Restore [colors], and exempt the verbatim-import class (#451)
- **pane**: Honour a child's SGR 2, which cell_style dropped (#457)
- **git**: Rebuild the column whose status changed, not the focused one (#455)
- **docs**: A slash between two words is prose, not a path (#456)
- **pane**: The hook-consent prompt no longer eats the first message to an agent (#464)
- **pane**: Keep the background of a cell erased under SGR (#470)
- **ci**: Let a CodeQL analysis finish instead of cancelling it on every merge (#472)
- **capture**: Render `ssh -v` output instead of blank pager lines (#476)
- **pane**: Enable DEC mode 2027 so emoji clusters cost what display_width budgets (#485)
- **config**: Only ~/.spycrc.toml may declare startup tabs (#494)
- **vsplit**: Keep the process cwd on the focused column, so a removed worktree can't strand it (#498)
- **release**: Publish spyc-vt-sys before spyc, and package both crates on every PR (#499)
- **worktree**: A remove_worktree that fails partway no longer strands the worktree (#500)
- **pane**: ^a s anchors paths on the receiving pane's cwd, not PROJECT_HOME (#501)
- **render**: A VS16 emoji no longer shifts the rest of its row one column right (#503)
- **vsplit**: Actions in column b no longer read or write column a (#502)
- **codex**: Run codex panes with --no-daemon so their hooks reach spyc (#510)
- **mcp**: Two spycs in one directory each keep their own agents (#509)
- **pane**: A drag-select copies the cell it ended on (#511)
- **skill**: An update offer between equal versions says what changed (#513)
- **inventory**: A read-only file can be yanked again (#515)
- **config**: Shipped keymap examples parse, so uncommenting one keeps the config (#518)
- **mcp**: A restored session's agents are anchored on its own root, not the launch dir (#525)
- **keymap**: A user binding no longer takes over the second key of a `g` chord (#528)
- **render**: A prompt or flash is no longer hidden behind a full-screen `V` or `D` (#530)
- **worktree**: A commit in the repo can no longer prune a worktree spyc is creating (#532)
- **gf**: A path relative to the worktree root or PROJECT_HOME resolves (#531)
- **codex**: Render current rollout conversations and tools (#540)
- **codex**: Preserve launch options through restore and fork (#541)
- **agent-status**: Preserve semantic activity and clarify Codex hook readiness (#542)
- **agent-status**: Sanitize hook traces and expose bounded event diagnostics (#543)
- **agent-status**: Migrate duplicate Codex hook reporters (#546)
- **codex**: Recover native questions and resolve worktree hook sources (#548)
- **codex**: Retire answered approvals before question recovery (#549)
- **codex**: Preserve working through automatic approval review (#550)
- **pty**: Keep the UI responsive and preserve large file piping (#551)
- **codex**: Detect approval waits despite wrapping and redraws (#560)
- **hooks**: Preserve status metadata in large hook payloads (#561)
- **codex**: Preserve user hook trust positions when pruning (#566)
- **codex**: Recover after questions preceded by an agent block (#567)
- **hooks**: Preserve borrowed reporters on teardown (#570)
- **activity**: Retire interrupted and exited agent reports (#571)
- **codex**: Render recorded shell argv in transcripts (#572)
- **session**: Restore valid tabs without losing refused Codex entries (#573)
- **hooks**: Release the hook-lease lock explicitly so a spawned child can't hold it (#574)
- **hooks**: Preserve legacy Codex symlinks and file permissions (#575)
- **hooks**: Preserve unrelated Codex reporter flag mentions (#578)
- **session**: A restored session no longer deletes itself on save, and empty quits take no picker slot (#583)
- **session**: A claude tab is never saved with another tab's conversation (#584) (#588)
- **pane**: Honour a child's synchronized output, so brew's download list no longer flickers (#591)
- **shell**: % expands relative to the directory the command runs in (#601)
- **codex**: Bind session lifecycle to each pane’s effective home (#602)
- **mcp**: Create_worktree finds the agent's repo when the user browses outside one (#605)
- **session**: Restored tabs keep their pane id, and status hooks find a restarted spyc (#606)
- **mouse**: Allow Ctrl-drag pane copying during live output (#603)
- **session**: An agy tab is never saved with another conversation (#607)
- **session**: Agy's -c takes no value, so a saved command keeps the argument after it (#608)
- **mcp**: Hooks and proxies codex's shared daemon spawns no longer name another tab (#614)
- **pane**: Fork and :hooks on! act on a shell tab's agent, not its shell (#615)
- **mcp**: A proxy codex's shared daemon spawns finds its spyc by its cwd, not the socket it inherited (#618)
- **mcp**: Every agent's MCP entry names the spyc on PATH, so a codex workspace allowlist accepts it (#621)
- **codex**: Exclude input chrome from pane navigation (#624)
- **pager**: `l` moves the cursor right in the `!?` history editor (#646)
- **prompt**: Tab completes `.`, `..`, `~` and relative paths the way they're typed (#644)
- **ui**: `[SCROLL]` stays whole on the pane divider beside a long cwd (#650)
- **agent**: Keep the :agent hud choice across -r and config reloads (#661)
- **agent**: Read a session file once per append on Linux (#663)
- **statusline**: Two tests raced a slow runner, not the forwarder or the wrapper (#667)
- **build**: Make the vendored libghostty-vt archives reproducible (#668)
- **agent-status**: Hold a waiting reported mid-turn until the turn ends (#671)
- **codex**: Show attention for visible async questions (#672)
- **list**: Count pages from the top so a jump never hides the cursor (#681)
- **agent-hud**: Keep the first column steady and set row headings apart (#682)
- **agent**: The working dot breathes orange to gold, never red (#685)

### Performance
- **watch**: Skip the gitignore filter when no fs events are pending (#564)
- **mcp**: Shrink shared server instructions (#581)

### Refactors
- **pane**: Extract the terminal-engine seam, vt100 behind it (#461)
- **pane**: Split engine_ghostty into engine + test half (#487)
- **state**: Columns are addressed by handle, and a guard holds it (#504)
- **pane**: Delete the claude crash-recovery prompt nothing could open (#524)
- **ui**: Move the side-by-side diff layout into diff_render/split.rs (#554)
- **lib**: Move the terminal plumbing and the fuzz facade out of lib.rs (#555)
- **mcp**: Move the tools/list catalogue into mcp/tool_schemas.rs (#556)
- **config**: Move config loading into config/load.rs (#557)
- **app**: Move run_effects into app/effect/executor.rs (#562)
- **app**: Lift App::run's pre-recv phases into app/pre_recv.rs (#563)
- **pager**: Move the file → PagerView builder into pager_handler/file_view.rs (#565)
- **archive**: Split app/archive.rs into command / screen / edits children (#577)
- **ui**: Bring nine functions just over 100 lines under the limit (#580)
- **pane**: A tab's agent has one source, TabInfo::agent() (#611)
- **hooks**: Spyc --status-trace reaches reporters through a state flag, so hook commands never change (#622)
- **pager**: The `!?` history editor is one key decision and a few small steps, tested through the popup (#642)
- **agent**: Share the bounded session-file reader and watcher (#654)

### Documentation
- Correct two false claims, and finish F7's AGENTS.md trim (#429)
- **roadmap**: Retarget the strategy layer on 2.2 and the 2.3 Projects arc (#430)
- **changelog**: Under squash merge the PR title IS the changelog entry (#435)
- **roadmap**: Reframe the thesis on the working set, open the 3.0 horizon (#448)
- Canadian English across the repo, with a guard to hold it (#449)
- **pane**: VT engine spike — vt100 vs wezterm-term vs libghostty-vt (#450)
- **roadmap**: The VT engine lands in 2.2, contingent on a measurement gate (#454)
- **roadmap**: The engine gate passes at the shipping pin (#460)
- **spike**: Isolate the formatter's viewport offset, and PR 15's fuzz criterion (#463)
- Gate the merge recipe on mergeStateStatus, not the check list (#471)
- Plan clickable which-key menus instead of right-click context menus (#478)
- **roadmap**: 2.2 status on main, and the release waits for the full scope (#493)
- **agents**: The merge recipe drops --delete-branch, so remove_worktree does the teardown (#505)
- **agents**: Check a squash-merged branch landed by its own files, not the whole tree (#512)
- **projects**: Draft PROJECTS_PLAN.md, the 2.3 design (#520)
- **plan**: Reconcile V2_2_PLAN.md with what 2.2 shipped; the tag waits for PROJECTS_PLAN.md authored, not approved (#526)
- **projects**: A reviewer TL;DR atop PROJECTS_PLAN.md; mirroring, discovery and CounterTop are deferred, not permanently out (#535)
- **codex**: Plan support parity and require isolated worktrees (#539)
- **codex**: Record merged A3 recovery acceptance (#568)
- **git**: Propose a 2.3 review workspace and assess Gitoxide (#569)
- **demo**: Land the markdown and agent demo harnesses as works in progress (#473)
- **demo**: Film the agents clip through tui-test with stand-in agents (#597)
- **demo**: Run the markdown tui-test clips on tui-test 0.1.0, under a private HOME (#598)
- **roadmap**: Add the UX 2.0 plan as a 2.3 draft (#604)
- **projects**: PROJECTS_PLAN.md approved, with the owner's three decisions recorded (#620)
- **codex**: Establish HUD sources and approve compact/full layouts (#633)
- **claude**: Establish the Claude Code HUD's sources (#652)
- **release**: The 2.2 release notes, and a README that knows what 2.2 does (#687)

### Build & Tooling
- **deps**: Bump uuid from 1.24.0 to 1.24.1 in the cargo-minor-patch group (#432)
- **apt**: Deploy the apt repo as a Pages artifact, not a gh-pages branch (#441)
- **deps**: Bump the cargo-minor-patch group with 3 updates (#445)
- **deps**: Bump gix from 0.86.0 to 0.87.1 (#446)
- Lint the workflows in the PR gate (#447)
- Take CodeQL off the PR path (#467)
- **changelog**: Group ci: commits instead of dropping them silently (#468)
- Reclaim the Actions cache budget (#469)
- **deps**: Bump the cargo-minor-patch group across 1 directory with 6 updates (#475)
- **deps**: Bump the cargo-minor-patch group with 5 updates (#480)
- **deps**: Bump zstd from 0.13.3 to 0.14.0 (#481)
- **deps**: Bump the cargo-minor-patch group with 5 updates (#489)
- **release**: Cut an rc with release-prep/release-tag; an rc tag no longer splits the cycle's changelog (#537)
- **coverage**: Raise the line-coverage floor from 35% to 84% (#636)
- **deps**: Bump the cargo-minor-patch group with 7 updates (#629)
- **deps**: Bump syn from 2.0.117 to 3.0.2 (#638)
- **deps**: Bump zip from 8.6.0 to 9.0.2 (#637)
- **make**: Prune dead build output from a shared target dir, and make clean refuses there (#639)
- **profile**: Dev and test builds carry line tables only, not full debug info (#649)

### Tests
- **pane**: Fuzz the pane's byte-processing and recovery path (#462)
- **pane**: One seam contract, run against both engines (#466)
- **pane**: A fake agent's argument list is never read half-written (#519)
- **guards**: A file-size ratchet — 1,000 non-test lines, 3,000 in all (#552)
- **archive**: Split the archive harness tests by theme (#558)
- **agent-status**: Make the hook-reporter test's socket read blocking (#559)
- **session**: Keep the restore fixture from moving the test process into a temp dir (#576)
- **guards**: A function-length ratchet at 100 lines of code (#579)
- **session**: Red cases for restore points lost to pruning, empty quits and the picker spacer (#582)
- **state**: Unit tests never write into the real state dir (#585)
- **harness**: Fake agents share one script, so macOS scans it once instead of per test (#586)
- **session**: Red cases for a claude tab saved with another tab's conversation (#584) (#587)
- **pane**: Red cases for a child's synchronized update painted half-drawn (#590)
- **shell**: A test-spawned pane runs /bin/sh, so the developer's rc can't leak processes (#592)
- **pane**: Red cases for a pane that answers no terminal query (#486) (#593)
- **hook-reporter**: Run the fresh spyc binary once before timing it, so macOS's first-run scan can't miss the deadline (#595)
- **pane**: Guard the large-pipe test on progress, not total time (#596)
- **pane**: The consent-prompt test reads the fake agent's whole line, not a half-written file (#623)
- **shell**: The `!` capture and background-task drains are tested against real commands (#640)
- **prompt**: Tab completion is tested through the prompts, with its decision split out pure (#641)
- **ui**: The pane divider is tested across its states, with its layout split into parts (#643)
- **agent-status**: Red cases for a waiting reported mid-turn shown at once (#670)
- **list**: Red cases for a page that hides the cursor after a jump (#680)
- **clipboard**: Run copy-command stubs through /bin/sh (#683)

### Miscellaneous
- **ci**: Bump taiki-e/install-action from 2.85.13 to 2.86.5 in the github-actions group (#431)
- **ci**: Bump the github-actions group with 3 updates (#444)
- **build**: Give the panic net a rationale that is still true (#458)
- **ci**: Bump taiki-e/install-action from 2.87.0 to 2.87.5 in the github-actions group (#474)
- **ci**: Bump taiki-e/install-action from 2.87.5 to 2.87.11 in the github-actions group (#479)
- **ci**: Bump taiki-e/install-action from 2.87.11 to 2.87.15 in the github-actions group (#488)
- **ci**: Bump taiki-e/install-action from 2.87.15 to 2.87.22 in the github-actions group across 1 directory (#536)
- **ci**: Bump taiki-e/install-action from 2.87.22 to 2.87.27 in the github-actions group across 1 directory (#628)

## [2.1.1] - 2026-08-18

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exclude = ["fuzz", "spikes/vt-engine", "spikes/vt-engine/sizeprobe"]

[package]
name = "spyc"
version = "2.2.0-rc.4"
version = "2.2.0"
edition = "2024"
description = "A Rust TUI file commander where the AI agent in the side pane can query the file commander itself"
license = "BSD-3-Clause"
Expand Down
Loading