diff --git a/CHANGELOG.md b/CHANGELOG.md index bf5ea9e2..1829f8c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 ` 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 diff --git a/Cargo.lock b/Cargo.lock index af3f9f1c..93bc618f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4390,7 +4390,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "spyc" -version = "2.2.0-rc.4" +version = "2.2.0" dependencies = [ "ansi-to-tui", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index b43d3623..fe885e5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"