Skip to content

The plan page resumes the agent that wrote the plan (#1511) - #1717

Merged
suleimansh merged 1 commit into
mainfrom
1511-resume-planning
Aug 26, 2026
Merged

The plan page resumes the agent that wrote the plan (#1511)#1717
suleimansh merged 1 commit into
mainfrom
1511-resume-planning

Conversation

@suleimansh

@suleimansh suleimansh commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #1511.

What

A ticket's plan page now knows who wrote the plan and offers Resume agent, which opens that agent's session — the composer there already continues a finished agent in place (same session, same branch, local or web), so the conversation picks up with the plan and the ticket in the agent's context. While the author is still running the button reads Open agent and the note says the plan is being written. A plan with no recorded author shows neither.

The ## Agent section the ticket proposed is not added. Correction to what I first wrote on the issue: the agent can learn its own id — Claude Code exports CLAUDE_CODE_SESSION_ID into the agent's shell (checked on 2.1.246), and the drain-written plan for this ticket had already found that. The reasons for not writing the section are the remaining ones: it would need a prompt change and rely on the agent remembering to do it (a forgetful agent = a silently missing section), it is Claude-Code-specific while the records cover every driver, and it would commit a machine-local resume command into the repo. The framework's own records already carry the link, on the data branch, for every driver — so the button reads those.

How

  • src/tickets.ts planAgentFor(agents, file): the newest agent whose intent contains the plan ask (Create tickets/<stem>.plan.md) — the plan column's attended start verbatim, or a pinned queue drain's prompt carrying the entry. Not attributed: a single unpinned drain (its intent is the stock "first open entry" prompt), an implementation run linking the ticket, another ticket's plan.
  • src/dashboard-rpc/reads.ts onPlanAgent(projectId, file){ agentId, status } | null, over readAllAgents; unknown project → null. Exported through dashboard-rpc/index.ts and stubbed in dashboard/rpc/reads.ts.
  • dashboard/components/TicketPlanPage.tsx: polls it (10s, like the plan text), renders the author row above the markdown with a tooltip; new onOpenAgent prop, wired in App.tsx to selectAgent.

Tests

  • tickets.test.ts: newest matching ask wins (attended sentence and drain prompt both match); another plan, an implementation link, no ask, and an unplanned ticket do not.
  • reads.test.ts: unknown project → null.
  • TicketPlanPage.test.tsx: known author → "Resume agent", clicking it opens that agent; running author → "Open agent" only; no author → no control; the existing three still pass.
  • Broken on purpose: oldest-wins sort fails the matcher test; removing the row fails the two plan-page tests.

Specs

src/tickets.SPEC.md + tickets.test.SPEC.md, src/dashboard-rpc/reads.SPEC.md + reads.test.SPEC.md, dashboard/components/TicketPlanPage.SPEC.md + TicketPlanPage.test.SPEC.md, FEATURES-SPEC.md (Tickets).

🤖 automated · Fable 5, effort high

A plan is written by an agent, and the way to discuss it is that agent's own session — the
composer there continues the same conversation, with the plan and the ticket already in its
context. The plan page now finds that agent from the framework's records (the newest whose ask
was the plan: the plan-ask sentence, given directly or carried in a pinned queue drain) and
offers "Resume agent", which opens its session; one still running is offered as "Open agent".

The plan file carries no marker of its author. The `## Agent` section the ticket proposed cannot
be written by the agent itself — the driver only learns the session id from the run's output
stream after it starts — so the link is made from what the framework already records instead.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@suleimansh

Copy link
Copy Markdown
Contributor Author

Dogfooded on the real dashboard (:4200 restarted on this branch's build, no agents running at the time):

  • onPlanAgent(gemstack, 2026-08-05_continue-planning-resume-agent.md){ agentId: "2026-08-24T12-35-05-830Z", status: "done" } — the pinned drain that wrote that plan on 2026-08-24.
  • The plan page shows the author row above the plan with Resume agent; the tooltip reads as written.
  • Clicking it opens /gemstack-st99l0/2026-08-24T12-35-05-830Z: the planner's session (a cloud run), composer reading "Agent ended — your next message continues it", with the session's teleport command and "Open the session" link in the header.
  • The "Update tickets/" runs, whose prompt merely mentions .plan.md, are not matched — the matcher wants the plan ask itself.

🤖 automated · Fable 5, effort high

@suleimansh suleimansh mentioned this pull request Aug 26, 2026
@suleimansh
suleimansh merged commit 5bacc48 into main Aug 26, 2026
2 checks passed
@suleimansh
suleimansh deleted the 1511-resume-planning branch August 26, 2026 12:27
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.

Resume planning

1 participant