#144 gave the app's page a live log tail, and #138 made New app land there. But the run a brand-new app is waiting on is its first deploy, and the page can never tail a deploy.
Two filters, both on kind: the Now panel lists listRuns(db, repo.id, { kind: "agent", limit: 8 }) (src/web/studio/app.ts:142), and the tail picks rowsNow.find(r => r.kind === "agent" && r.state === "running") (:247). A deploy appears on this page only as a state badge in the head card. So the first thirty seconds of a new app's life — checkout, install, boot, the moment it answers — happen with the page saying nothing, and the log only starts moving once an agent picks up the first issue.
That is the half of the direction's sentence still missing: New app lands on one page that shows the app coming alive. The crew's log is there; the app's own coming-alive is not.
Acceptance
[ ] While a deploy is running for this app, the page shows it — in Now, or in the head card, wherever it reads best — and tails its log the same way an agent run is tailed, using logBox (src/web/studio/log.ts).
[ ] Still one stream: the page never opens more than one log stream, whichever kind of run it is following. If both a deploy and an agent run are going, say which one the page follows and why in the pull.
[ ] When the deploy finishes, the page moves on without a reload — the tail settles and the head card takes its new state, which is what #115's live swap already does.
[ ] A page loaded with nothing running looks exactly as it does today.
[ ] Who may see a deploy's log is who may see the run: no wider.
[ ] Tests: an app with a running deploy and no agent run renders its tail and names the stream; one with both follows the one the pull says it should; one with neither is unchanged. They fail on today's code.
[ ] bun test green.
Files I expect to change
src/web/studio/app.ts (the two kind filters and the tail), src/web/studio/log.ts if the box needs to say which kind of run it is showing, test/studio.test.ts.
Risks
*Do not turn Now* into every run.** The panel is the crew's work; a deploy belongs there only while it is going, or beside the head card that already owns production's state. Choose one and say why — two places showing the same deploy is worse than neither.
The first paint matters most here, because #138 lands people on this page seconds after they create an app: whatever it shows must be right server-rendered, before any stream connects.
A deploy's log is machine output, not a person's: it is still text on a page and still escaped.
#144 gave the app's page a live log tail, and #138 made New app land there. But the run a brand-new app is waiting on is its first deploy, and the page can never tail a deploy.
Two filters, both on
kind: the Now panel listslistRuns(db, repo.id, { kind: "agent", limit: 8 })(src/web/studio/app.ts:142), and the tail picksrowsNow.find(r => r.kind === "agent" && r.state === "running")(:247). A deploy appears on this page only as a state badge in the head card. So the first thirty seconds of a new app's life — checkout, install, boot, the moment it answers — happen with the page saying nothing, and the log only starts moving once an agent picks up the first issue.That is the half of the direction's sentence still missing: New app lands on one page that shows the app coming alive. The crew's log is there; the app's own coming-alive is not.
Acceptance
logBox(src/web/studio/log.ts).bun testgreen.Files I expect to change
src/web/studio/app.ts(the twokindfilters and the tail),src/web/studio/log.tsif the box needs to say which kind of run it is showing,test/studio.test.ts.Risks
Suggested: Scout.