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

The studio's app row is one function in its own module #111

shipped production is serving it opened this has it
opened this

The studio draws an app as a row in exactly one place, and that place is sixty lines in the middle of studioHome.

src/web/studio/home.ts:74-131 builds each row inline: the production environment's state, the latest run read through runWord, who ran it, how many asks the app has, the tone, and the row({ … }) itself. It is good code in the wrong file — home.ts is one of the busiest files on this branch, and #71 (/apps is the shelf) was parked because main moved under it eight times and the branch could not be brought up to date, conflicting on this very file. The public shelf (studioLanding, src/web/pages/site.ts:536) already draws its own tiles a second way, and a third page wants the same row.

Pure extraction, no behaviour change: this is the move that lets the /apps shelf (the rewrite of #71) land in one run instead of losing a race with main.

Acceptance

  • [ ] A new src/web/studio/shelf.ts exports one function that takes the viewer's context and a list of app repositories and returns their rows — the gathered reads (latestAgentRunsForRepos, getUsersByIds, decisionsFor, runtime.status) move with it, so the caller hands over repositories and gets rows.
  • [ ] studioHome calls it and is that much shorter; the Your apps card, its head, its buttons and its empty state stay exactly where they are.
  • [ ] The rendered bytes of / in studio mode are unchanged for a viewer with apps — a test that snapshots the app row before and after would pass either way.
  • [ ] The module's doc comment says what a shelf row is: name, one line, whether it is live, what the crew last did, the asks pill, the way in.
  • [ ] bun test green, and the existing studio home tests still cover the row through the new function.

Files I expect to change

src/web/studio/shelf.ts (new), src/web/studio/home.ts, test/studio.test.ts if a test names the old private shape.

Risks

runWord is async and reads git, so the rows are gathered with Promise.all: keep that, and keep the reads grouped — one query for the latest runs of every app, not one per app, exactly as today. Who sees what must not move: the ownerFacts check that hides who ran it travels with the row.

Suggested: Scout.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs