Repository navigation
feat: agent visibility + never lose a pane's answer - #96
Merged
Merged
Conversation
The band only knew agents it saw spawn, so a module reload emptied it and nested agents showed as one flat list. It now reads $.agent.list() at session start and while agents work: unknown running agents are adopted (model, effort and tokens left blank, never guessed), parent ids nest the rows, and the list status draws waiting, idle, failed and killed. The agent in view is drawn inverse, and a sub with no known model gets a ? chip instead of "pane". Also adds the ctx object and three no-op modules (rows, status, autocomplete) that the following steps fill in. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
One pinned line (run, working subagents and panes, done, tokens, session cost, context) so the run's state survives the band scrolling away. The dollar figure is only the measured session cost, never a per-agent share; the line clears once nothing works and every finished agent is past the done grace, with a clock timer for the quiet case. Cost and context come from a session.measure hook matched on `context`: register.js already holds the unmatched one and a second unmatched hook is refused. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An Agent tool call now draws as the agent it started: role, model·effort, current tool, elapsed time, tokens and the call's description, from the live map. Unknown agents, errored and interrupted calls keep the engine's row. A running call has no output yet, so an agent.spawn observer maps its tool_use_id to the agent id (bounded at 200). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An adopted agent the list marks idle started working and never ended, so the ticker and the list poll ran forever; a spawned agent the list once named and no longer does was never finished. Adopted rows no longer show a misleading 0 token count. The list read is throttled on the engine clock (testable), retried rarely after a failed read, and only repaints when something changed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The /agt flags were typed blind; prompt.autocomplete now offers them. The pane tools set isDeferred:false so panes mode never needs a ToolSearch hop. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
It advances a 90 s grace on the mock clock and hit the 5 s default under load, failing the pre-push gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A done or idle agt- pane closed after its grace period even when nothing had been read from it, so a worker that could not report (a lead on an older mod, no wire) lost its whole output. The reaper now closes a pane only once its answer file exists, its wire done message arrived or the lead closed it; otherwise the pane stays open and is flagged once. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A lead on an older mod gets no wire message from its workers and waited blind. When an agt- pane of its run goes done or blocked and no wire done message arrives within 20 s, the lead's mod now sends the lead session one message naming the pane and how to read it (herdr pane read, or tmux capture-pane). Once per pane. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A session keeps the mod it started with, so a plugin update left a lead without the wire and its workers unable to report. The mod reads its own version at session start and compares it with the sibling version directories of the plugin cache (no network); if a newer one is installed it toasts once and spawn_pane refuses until Claude Code is restarted. The check repeats at each spawn so a mid-session update is caught too. The recon line now takes its version from the running skill's own plugin.json. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
--mode p now offers panes, --formation g offers gauntlet. The hook matched only dash-led tokens, so a value word never reached it; it now matches any typed /agt draft and decides from the previous word. argument-hint lists --formation. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The pinned status line was refreshed from an AbovePrompt render hook that
ran in every pane and re-read the whole run on each redraw.
- Only the lead pins a line: session.measure and the new tick callback
return early when ctx.isLead is false, so a worker pane's ticker never
reaches ui.status.
- The refresh left the render path. The redraw ticker in register.js calls
the callbacks on ctx.onTick with the `now` it already read, also on the
tick that stops it. They get an `io` ({ status, after, now }), not `$`:
the hook checker follows `$` only into top-level functions of the same
file and refuses it into a callback or an import. session.measure stays,
and no new unmatched hook is added.
- The pin is tried and remembered only once the host took it. `shown`
starts as a sentinel, so the first refresh after a reload writes even
when it clears a line the old module left pinned.
- Rows: a finished agent's row is cached per agent, keyed on state, tokens,
list status and end (applyStatus moves the list status after an agent is
done), rebuilt while it waves goodbye, capped like the call map. A
workflow agent's tool_use_id, shared by its whole run, is no longer
mapped to one agent.
Every change has a test that fails without it. pin is exported and tested
with a stub io, since the test kit swallows a throwing ui.status hook. The
grace test now waits one tick (advance(300)) instead of mounting the band,
which no longer pins the line. rows.test.ts already checked an interrupted
call of a working agent; the new test adds a finished agent and a running
one found through its spawn.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A role can be respawned (a fix, a retry) under the same pane name, but harvest state is keyed by name and nothing ever cleared it: the new pane inherited the earlier pane's harvested mark, wire report and wake, and the earlier pane's answer file counted as its own, so the reaper closed a pane nobody had read. spawn_pane now clears the name from the four sets. An answer file counts only if it was written after the mod first listed that pane, the rule the tmux done-file already follows; herdr panes are tracked the same way. A restarted lead therefore flags a leftover pane whose answer predates it instead of reaping it. A stranded idle pane is flagged "idle, not harvested", not "done". The unused reapable() is gone; its tests call reapPlan(). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The answer file agents/pane-<role>.md was written only by a worker that had AGENTILLE_NAME, which a lead from before the wire, or a hand-made pane, never sets. Such a worker published nothing, so a lead that reaps a done pane left its only copy of the output behind. When the worker has no wire name but its multiplexer names the pane agt-<run>-<role>, it now saves the answer at the end of each main-loop turn under that name and sends nothing: there is no lead to message. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude Code leaves a replaced plugin version in the cache with an .orphaned_at marker. After a rollback, a newer orphaned folder sat beside the version that really is installed, so spawn_pane refused every call and a restart did not help. The check now looks for the marker, once per folder newer than the running version, and ignores orphaned ones. The self-wake fires only for a finished pane. A blocked worker waits on the person; waking the lead for it cost a full turn and used up the pane's only wake, so the lead was never told when it later finished without reporting. The wake names `herdr agent read <name> --source recent-unwrapped`, the unwrapped read the harvest loop already documents. The /agt value completion finds the flag before the cursor by scanning back from it instead of splitting the whole draft on every keystroke, and leaves the "is this a /agt draft" test to the hook's matcher. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Closes #95
Added
$.agent.list(); waiting/failed states; agent-in-view highlight; rebuilds after reload/agtflag + value autocomplete; pane tools load eagerlyFixed
donespawn_panerefuses when the session runs an older agentille (orphaned versions ignored)Verification
claude plugin test .: 306 pass / 0 fail (209 at v3.6.1)scripts/validate.shclean;plugin validate --strictexit 0🤖 Generated with Claude Code