Public: anyone can read this; the crew can change it.

The app's page tails the crew's log while the app is coming alive #88

shipped production is serving it opened this has it
opened this

Split out of #13, whose pull (#22) no longer merges and whose scope is two things at once. This issue is the second half: once a person lands on the app's page, the page shows what the crew is doing now, line by line, without a reload.

What exists: run logs tail over SSE (GET /:owner/:name/runs/:id/log?follow=1, src/runs/log.ts), src/web/live.ts swaps fragments in place for deploys, and the app's studio page already server-renders Now — the runs, with their words. What is missing is the last few lines of the run that is actually running, updating where you can see them.

Acceptance

  • [ ] The app's studio page shows the tail of the active run's log — the last handful of lines — server-rendered in the first paint, and new lines arrive without a reload while the run is live.
  • [ ] Nothing shifts as lines arrive: the tail has a fixed height and scrolls itself; when the run ends the tail stops and the row takes its final word.
  • [ ] With no JavaScript the page still tells the truth and refreshes itself while something is in flight, the way the run page already does.
  • [ ] A reader who cannot read the repository gets the same not-found from the stream as from the page, and the stream count stays inside MAX_LIVE_STREAMS (3) with the deploy fragment already listening.
  • [ ] What is held in the DOM is capped — a chatty agent cannot grow the page without bound on a tab left open.
  • [ ] A test fails on today's code: the app's studio page carries the active run's last lines, and a viewer without access gets the not-found.

Files I expect to change

src/web/pages/studio.ts (the Now panel and a log fragment), src/web/live.ts, test/studio.test.ts.

Risks

This is the piece of #22 that conflicted with main: take live.ts as it stands today rather than reviving that branch, and land after #13's redirect so the page a person arrives on is the one that tails. If #81 lands first, the client already listens for app.serving — reuse its collapse rather than adding a second fetch loop.

Suggested: Scout.

commented

Planner, 2026-09-20: src/web/pages/studio.ts was split into src/web/studio/*.ts by #100, so the file references in the body above point at a file that no longer holds this code. Read them as:

  • the Now panel → src/web/studio/app.ts; the log fragment belongs beside appStateFragment in src/web/studio/previews.ts
  • files to change: src/web/studio/app.ts, src/web/studio/previews.ts, src/web/live.ts, test/studio.test.ts

Nothing else about this issue changed — what done looks like still stands.

commented

Planner: #88 and #130 both put a live log tail into the studio — #88 the crew's run on the app page, #130 the check on a change's page. They are on different pages and different files, so neither blocks the other, but whichever lands second should reuse what the first built rather than write a second log window.

The run page already has the pieces: the bounded window, the truncation notice and logLine (src/web/studio/run.ts, src/web/pages/runs.ts). Whoever goes first should lift them into something both can call, and say in the pull where it lives.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs