acpmux: the agent chat's branch follows a checkout mid-session

Merged
TE
16d ago
+305-10

The agent chat's header (Environment line) and Inspector showed the branch a chat started on (#23270 mapped acpmux's gitBranch), so a checkout mid-session left them stale. Now acpmux keeps it live.

  • acpmux (hub/git_watch.rs): one non-recursive notify watcher over the git directory that holds each attached session's HEAD (a linked worktree's own one under .git/worktrees/). A checkout, switch or branch rename rewrites HEAD there. The event thread coalesces a burst (200 ms quiet) and signals one task, which reads the git state off the runtime (git_state.rs, file reads only, no git process). A changed branch appends a git mux record, which watchers hear as _acpmux/session_changed kind git. Attach and detach move the watch, so only chats some client holds are watched; nothing polls.
  • Every session summary now carries gitBranch, the branch checked out now (the last read, else the one it started on). meta.git_branch still records the start branch, for the stats and the pull-request link (hq#1920). Session detail's gitHead is still the start HEAD.
  • webviews: no source change. session_changed already merges the summary, and the summary mapping reads gitBranch.
  • A git record bumps the chat's updatedAt, as a tools or rules change does.

Changelog

Fixed: The agent chat's Environment line and Inspector follow a branch checkout mid-session.

Test

  • ./scripts/verify-cmux-tui-hosted.sh --filter git_state runs git_state_of_a_held_chat_follows_a_checkout_mid_session. It attaches a client, runs git checkout -b second, and expects a session_changed kind git with gitBranch: "second" within 3 s (the goal is about 1 s; the margin is for loaded runners). Then a detached HEAD gives null.
    • Red on base: test-only commit bb2d394cb371 (no git change is ever sent).
    • Green on head: hosted run linked in a comment below.
  • webviews/test/chat-summary-git-branch.test.ts: a session_changed kind git mid-session moves the branch the chat shows, and a detached HEAD clears it.

Observed / Not run

  • Not run locally: cosmic-gray runs no cargo or bun. The hosted Rust run and CI's webviews tests cover them.

🤖 Generated with Claude Code

Agent session: cosmic-gray


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

The agent chat's Environment line and Inspector now follow a branch checkout mid-session instead of only showing the branch the chat started on.

  • acpmux watches each attached session's git HEAD file; a checkout, switch, or rename emits a git session_changed event with the new branch in the summary's gitBranch.
  • The start branch stays in meta.git_branch for stats and the pull-request link; a detached HEAD reports a null branch.
  • Clients holding a chat hear the change without waiting for a turn to end, and attach/detach moves the watch so only held chats are watched.