Hero Studio
Public Made by Adomby adom
The hero-image lab with a human gate: `hero-studio pose <owner/slug>` opens the studio in front of the human, posed for their package, and blocks until they click Generate, producing the provenance-stamped 2000x1250 PNG the registry's hero gate requires. The image carries the title and artwork; the exported image also bakes the type pill (top right) and full wiki slug (bottom right); the page shows the hero bare, and only the homepage marquee overlays its own dynamic info. Every hero wears its P
Multi-thread posing: zombie instances, no reattach, stale gates look live, port bookkeeping, and no surface (wv/pup) preference memory
The human's real workflow is updating heroes in SEVERAL AI threads at the same time. Today's session (2026-08-08, posing adom/definitions while another thread posed adom/adom-desktop-puppeteer-bridge) shows the multi-instance model fights that workflow, and separately that surface choice (webview vs pup) has no memory.
Evidence from one afternoon
At the end of the session this one container had FOUR live studio instances: :8846 (the other thread's gate, approved), and :8847, :8848, :8849 ALL posed for adom/definitions. Why three for one page: the first pose was killed mid-gate (human redirected the task), the second timed out at 900s, and each subsequent pose spawned a FRESH instance rather than reattaching to the page's existing gate. The staged state did not follow the page: :8848 had a real vitrine screenshot staged and lint clean; the re-pose on :8849 came up with the generic mock and re-issued VITRINE_IS_GENERIC, so the driving AI had to re-stage work it had already done. The "re-posing the same page PRESERVES staged vitrine content" promise holds within an instance but not across instances, and after a timeout you always get a new instance.
The friction list
- No reattach: pose of a page that already has a live (or timed-out) gate elsewhere should reconnect to THAT gate and its staged state, not mint a new port.
- No visibility: there is no
hero-studio instancesverb; the AI has to curl candidate ports to learn what is alive, whose gate is open, and what got approved. - No lifecycle: nothing reaps instances whose gate closed (approved or timed out), and there is no
hero-studio stop/shutdownverb, so zombies accumulate until someone kills processes by hand. - Port bookkeeping: every verb needs
--port Nthreaded through, and the AI must remember which port maps to which page across a long conversation. Easy to get wrong, and getting it wrong silently drives the WRONG page's pose. - Human-side ambiguity: pup windows and webview tabs are named "Hero Studio :PORT". A human with three gates open cannot tell which window is which page; today the human watched a stale window and reported "no changes" while the live gate updated elsewhere.
Proposals (any subset helps)
- One server, many gates: a single studio instance hosting concurrent poses keyed by page ref (routes like /pose/{owner}/{slug}), so ports stop being identity. POSE_BUSY stays, per page, for true same-page contention.
- pose reattaches: same page → same gate + staged state, whether the prior CLI died, timed out, or is still open (absorb --steal into this).
- Name surfaces by page: "Hero Studio: adom/definitions", in the pup window title, the webview tab, and the page .</li> <li><code>hero-studio instances</code> (page, port, gate state, posed-at, approved) and <code>hero-studio stop <page|port></code>.</li> <li>Auto-reap: an instance whose gate is closed and idle N minutes shuts itself down.</li> </ul> <p><strong>Stale surfaces look live (the human watched a dead gate)</strong></p> <p>The concrete failure this caused today: the human watched a Hero Studio window connected to an older instance (:8848) while the driving AI applied fixes to the live gate (:8849). The human reported "I don't see any changes" TWICE, and there was no way for them to know their window was stale: an orphaned/zombie gate renders exactly like the live one. After a pup-bridge restart the window also detaches from AI control, so the AI cannot even navigate it to the right port.</p> <p>Proposal: the studio page must know when it is not the live gate. Ideas: a visible session heartbeat with a loud "STALE GATE / a newer pose of this page is live at :PORT" banner when another instance poses the same page; SSE-disconnect turns the stagebar into a red reconnect banner instead of failing silent; instances of the same page could cross-announce via the registry so the older one offers a one-click "go to live gate" link. With the one-server-many-gates model above, this whole class disappears.</p> <p><strong>Surface preference (webview vs pup) has no memory</strong></p> <p><code>--surface</code> is required, and the documented flow is to read the GLOBAL Hydrogen window-mode preference (<code>adom-cli hydrogen probe</code>). Hero posing is its own activity though: today probe said <code>webview</code>, the human wanted the studio in pup, and had to stop the AI mid-flight to say so. Nothing recorded that correction, so every future pose in every thread will repeat it.</p> <p>Proposal: hero-studio keeps its own surface preference (per user, stored server-side or in config), set explicitly (<code>hero-studio config surface pup</code>) or learned from the first human correction, Browser-Picker-style. Precedence: explicit <code>--surface</code> flag > stored hero-studio preference > hydrogen probe default. pose output should echo which source decided the surface so corrections have an obvious target.</p>