feat(features,web): an agent reads as its own page by its id, on a plan or with none
Merged
DA
4d ago+436+436+012345678901234567890123456789-30-30-01234567890123456789
Step 7 of the automations plan (docs/proposals/automations-scope.md). It is stacked on #2688 (account Inbox carries planless items).
What changes
GET /api/agents/{id}reads one agent as its own page.- It answers
{ agent: CodingAgentPage }for any agent the account reaches through its workspace, an agent an automation started with no plan as much as one on a plan. - The page is the summary the tabs draw, plus
planId(null for a planless agent),automationId,workspaceId, andrepository. - This is what the desktop agent page (step 8) will read.
- The path already rewrote to
agents/agent(the PATCH), so GET joins it and the rewrite table doesn't change.
- It answers
- Planless agents get a page schema, not a nullable
planIdon the existing summary. The proposal said "optionalplanId". About 28 places in the desktop read a summary'splanIdand rely on it, and every existing route, list, and old build expects a plan there. SocodingAgentSummarySchemastays exactly as it is, andcodingAgentPageSchemacarries the nullable plan for the one read that can answer a planless agent. Planless agents stay out of every summary-answering route (reachedAgentrefuses them, as #2663 made it), and a newreachedAnyAgentadmits them for the page. status.tsbuilds the summary and the page from one set of fields, so the two can't drift. The summary's key order is unchanged.- Wire goldens.
codingAgentPageSchemaandcodingAgentPageAnswerSchemaare new, recorded withLUKE_UPDATE_FIXTURES=1. No existing golden changes.
The proposal also listed a planless list for an automation's runs. An automation's run already names its agent (codingAgentId on GET /api/automations/{id}/runs), and the page reads that agent by id, so no second list is needed; step 11's runs panel uses the two together.
Tests
coding-agents-app.test.ts: an agent reads as its page by id, first on its plan (plan, workspace, and repository named) and then, once left planless as an automation's run leaves one, withplanIdandautomationIdnull, its workspace, and its status. An account outside the workspace reads 404. This fails without the change (GET was method-not-allowed).
pnpm check:affected passes. This change is server and wire only; CI cannot verify the Mac UI, and ./scripts/verify.sh was not run (LUKE-159 stands in before the first release).
š¤ Generated with Claude Code
Summary by cubic
Adds GET /api/agents/{id} so an agent reads as its own page, whether it works on a plan or has none.
- GET joins PATCH on the existing agent rewrite and answers
{ agent: CodingAgentPage }: the summary fields plusplanId(nullable),automationId,workspaceId, andrepository. - Planless agents stay out of every summary-answering route; a new
reachedAnyAgentadmits them to the page route, whilereachedAgentkeeps refusing them. status.tsbuilds the summary and the page from one shared set of fields so they can't drift.- Adds
codingAgentPageSchemaandcodingAgentPageAnswerSchemawire schemas and goldens, with no existing golden changes.