Skip to content

feat(watch): show plan mode as its own session status - #35

Merged
pfriedrix merged 1 commit into
masterfrom
feature/plan-mode-status
Aug 6, 2026
Merged

feat(watch): show plan mode as its own session status#35
pfriedrix merged 1 commit into
masterfrom
feature/plan-mode-status

Conversation

@pfriedrix

Copy link
Copy Markdown
Owner
  • lcc start launches every session in plan mode, so active was true on both sides of the only line that matters — whether the agent has been approved to touch files. A row now reads ◈ plan until it is, and the marker going away is the useful half.
  • Needs no new hook: Claude Code already puts permission_mode on PreToolUse, UserPromptSubmit and Stop. Verified against a real 2.1.223 session rather than inferred — watch_hooks.zig's payload fixture is now a captured payload, and Notification/SubagentStart/SessionEnd genuinely carry no mode, which is why the daemon holds the last one it was told.
  • This does break the module header's rule that lcc reads no payload fields. There is no matcher that selects on permission mode, so the exception is contained instead of avoided: an absent or unrecognised value is a no-op, freezing the last mode rather than clearing it.

Review notes

  • plan is projected at the point a status is reported, not applied as a transition — nothing fires when a plan is approved, so a state would put "which mode am I in" inside apply and "does this decay" inside decay. watch_status.present holds the precedence, and waiting outranks plan mode: the approval prompt at the end of a plan is a permission prompt.
  • status gains "plan" as a value; no JSON key was renamed or dropped. A caller switching on active/idle sees plan for a planning session, which is the point.
  • The running daemon is an older build and will not send the new field until it restarts — lcc open already flags that as outdated_build.

`lcc start` launches every session with `--permission-mode plan`, so the
dashboard showed the same `active` on both sides of the line that matters:
whether the agent has been approved to touch files. A row now reads `plan`
until it is.

Claude Code reports the mode itself, on `PreToolUse`, `UserPromptSubmit` and
`Stop` — three of the six events already registered — so this needs no new
hook. Reading `permission_mode` out of the payload does break the rule the
module header states, that the matcher does the discrimination and lcc reads
no fields; there is no matcher that selects on the mode, so the exception is
contained instead: an absent or unrecognised value is a no-op, freezing the
last mode reported rather than clearing it.

Plan mode is projected at the point a status is reported rather than applied
as a transition. It is a mode, not an event — nothing fires when a plan is
approved, the next hook simply carries a different mode — so modelling it as
a state would put "which mode am I in" inside `apply` and "does this decay"
inside `decay`, for something neither of them drives. `waiting` outranks it:
the approval prompt at the end of a plan is a permission prompt, and that is
the one signal the dashboard exists for.
@pfriedrix
pfriedrix merged commit bd7f8b9 into master Aug 6, 2026
1 check passed
@pfriedrix
pfriedrix deleted the feature/plan-mode-status branch August 6, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant