Write the ask state when Claude is waiting on the user - #42
Open
auroracapital wants to merge 2 commits into
Open
Write the ask state when Claude is waiting on the user#42auroracapital wants to merge 2 commits into
auroracapital wants to merge 2 commits into
Conversation
The Notification branch set "done", under a comment saying "waiting for user input". Those are different things. `ask` is read by status-summary.sh and collect.sh but nothing ever wrote it, so a session waiting for permission was indistinguishable from one that had finished. Two notifications arrive on this event. "Claude needs your permission to use Bash" means the session is blocked on a person; "Claude is waiting for your input" is the idle reminder that follows a normal finish. Treating both as a blocker would relight every finished session about a minute after it ended, so the branch keys on the message and the idle reminder now leaves the existing state alone instead of overwriting it with "done". set_status also never considered `ask` when folding pane states into a session state, and returned early on the first `working` pane. A later pane waiting on the user could not be seen. It now scans every pane and ranks ask > working > wait.
tmux hands out pane ids from one counter shared by the whole server, not one
per session, so a pane's id gets reused by an unrelated pane in an unrelated
session once the original closes. A hook process that outlives its own pane -
a background job with $TMUX_PANE baked into its environment from start-up, or
a slow tool call whose completion races the pane closing - then writes a
stale status onto whatever now holds that id.
Observed 2026-08-15: pane %3 kept receiving "ask" for a pane that had gone
back to a plain shell, recurring every 13-15 minutes, with no Claude process
anywhere in that pane's tree. The existing two-strike expiry in the hookless
detector cleared it within about a minute each time, so it never stuck for
long, but the write itself was still wrong and briefly flagged the wrong pane
on every recurrence.
set_status now confirms #{pane_current_command} is "claude" for $TMUX_PANE
before writing its status and agent files. All four events this hook handles
(PreToolUse, Notification, Stop, UserPromptSubmit) fire from Claude's own
process before it hands control to a tool, so the pane's foreground command is
still "claude" at the moment each one runs; anything else means the id has
moved on. The session-level status is still derived from whatever pane files
legitimately exist, so a skipped write here does not lose the aggregate
state - it just refuses to manufacture a new one for a pane that no longer
means what its id used to.
Tested in isolation: a pane still showing "claude" writes as before, a pane
now showing a plain shell is skipped, and the session-level status derives
correctly in both cases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
askis read in several places but nothing writes it, so a session waiting for the user cannot be told apart from one that has finished.Two things cause that.
The Notification branch sets
done. The comment above it says "Claude is waiting for user input", which is not whatdonemeans. Claude Code sends two different notifications on this event:Claude needs your permission to use Bashmeans the session is blocked on a person.Claude is waiting for your inputis the idle reminder that follows a normal finish.Treating both as a blocker would relight every finished session about a minute after it ended, so this branches on the message. Permission-shaped messages set
ask. The idle reminder leaves the existing state alone rather than overwriting it withdone.set_statusnever consideredaskwhen folding pane states into a session state, and it returned early on the firstworkingpane, so a later pane waiting on the user was never reached. It now scans every pane and ranksaskaboveworkingabovewait. A session with one pane waiting on a person and five panes busy still needs a person.The message match is deliberately loose (
permission,approve,confirm,needs your) because the notification text is not a stable API. An unmatched message changes nothing, so a wording change upstream degrades to today's behaviour rather than to a false alarm.Tested by driving the hook with both payloads and checking the resulting state files, and by running a real permission prompt and an idle timeout in tmux.
🤖 Generated with Claude Code