acpmux: the agent chat's branch follows a checkout mid-session
Merged
TE
16d ago+305+305+012345678901234567890123456789-10-10-01234567890123456789
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-recursivenotifywatcher 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 agitmux record, which watchers hear as_acpmux/session_changedkindgit. 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_branchstill records the start branch, for the stats and the pull-request link (hq#1920). Session detail'sgitHeadis still the start HEAD. - webviews: no source change.
session_changedalready merges the summary, and the summary mapping readsgitBranch. - A
gitrecord bumps the chat'supdatedAt, as atoolsorruleschange 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_staterunsgit_state_of_a_held_chat_follows_a_checkout_mid_session. It attaches a client, runsgit checkout -b second, and expects asession_changedkindgitwithgitBranch: "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
gitchange is ever sent). - Green on head: hosted run linked in a comment below.
- Red on base: test-only commit bb2d394cb371 (no
webviews/test/chat-summary-git-branch.test.ts: asession_changedkindgitmid-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
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.
acpmuxwatches each attached session's git HEAD file; a checkout, switch, or rename emits agitsession_changedevent with the new branch in the summary'sgitBranch.- The start branch stays in
meta.git_branchfor 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.