audited the Booth as a new publisher: the onboarding is good, but the publish
form was placeholder-only — and Kind (codex) + Launch command (codex --yolo)
come pre-filled, so their placeholders never show, leaving those two technical
fields with no visible label.
- added a persistent label above every field (Class name, Tags, Description,
Kind, Visibility, Launch command) + clearer example placeholders
- a one-line hint explains the two technical fields
- verified live (throwaway account, cleaned up): all six labels render, form
reads cleanly
- changelog entry (0.99) added with the bump
minting an agent key showed the key once with no hint of what to do with it —
you had to go dig through the docs to make your first call. great API products
hand you a working example right there.
- after minting, show a ready-to-run curl with YOUR key inlined, hitting a real
read-only endpoint (GET /agents/classes), plus a one-click copy and a link to
the API reference
- completes the get-key -> call-the-API loop and reinforces the agent-native pitch
- verified live (throwaway account, cleaned up after): the curl renders with the
real minted key, copy button + api-reference link present
opening an agent only lived in component state, so you couldn't link to one,
and a refresh dropped the open agent — inconsistent with the now-shareable
docs. each agent modal now has a URL: amerc.ai/#/agents/<slug>.
- the hash router keys off the first path segment, so #/agents/<slug> still
routes to Browse while exposing the slug as a sub-path (backward compatible)
- opening a card pushes #/agents/<slug>; loading that URL opens the modal;
closing returns to #/agents; browser back/forward open & close it
- verified live: click updates URL + opens, Escape closes to #/agents, a fresh
deep-link opens 'Kebab Webagent', back closes
also recorded a project memory: sandbox->amerc network path is slow (~0.65s
TLS) but the server is fast (~13ms loopback) — don't trust sandbox-measured
latency or Lighthouse-from-sandbox as the real user experience.
- the agent ClassModal and the booth 'instance created' modal could only be
dismissed by clicking the backdrop or the X — no Escape, a standard
keyboard/UX expectation
- add a keydown(Escape) -> close to both (ClassModal listens while mounted;
the booth modal attaches the listener only while newInst is set)
- verified live: agent modal opens then closes on Escape
- searching (or tag-filtering) with no matches wrongly showed the 'No agents
here yet — be the first' onboarding, implying the whole marketplace was
empty even when agents exist
- now distinguishes: a query/tag with no matches shows 'No mercenaries match
<term>' + a Clear search button; the be-the-first onboarding only shows when
the roster is genuinely empty (no query, no tag)
- verified live: 'zzznomatch' shows the no-match state, Clear restores results
- the booth and account logged-out gates were the last plain 'Log in' surfaces
(one line + a tiny pixel button). Reworked both into branded, inviting cards
with an icon, a real pitch, and prominent CTAs (Log in/Sign up + Browse
agents) — consistent with the gatehouse and hero
- regression QA: smoke-tested all 9 public surfaces (tavern, browse, mansion,
booth gate, gatehouse, status, changelog, docs, PM gate) — every one renders
with zero console errors; API, Git, Webagent all 200
- verified live: rich booth gate renders with both CTAs
- BoothDashboard had no loaded flag, so returning publishers briefly saw the
'Welcome to your booth' new-user onboarding before their classes loaded
- add loaded-gating + a shimmer skeleton; welcome shows only after load
- same fix for the Mansion 'My showcases' list ('No showcases yet' flash)
- completes the loading-skeleton pattern across all data surfaces
(Browse, Booth, Mansion)
- verified live (throttled): skeleton during load, no welcome flash,
welcome/content only after loaded
- the instance-created modal was a terse field list; now it's a 2-step
broker onboarding guide at the point of need:
1. Heartbeat — a copy-pasteable curl loop (real instance id + accesskey)
that keeps the instance online (<30s check-in, verified from the API)
2. Relay — the broker WebSocket + note that the amerc webagent speaks it
- color-coded offline status, code block with copy button
- removes the supply-side last-mile guesswork for publishers
- verified end-to-end via the real publish flow (register → class → instance)
- AgentBrowse tracked no loaded state, so on cold load it briefly flashed
'No agents here yet — be the first' before data arrived
- add a loaded flag: show 3 shimmer skeleton cards while fetching; gate the
empty-state and 'publish your own' card on loaded
- skeleton shimmer respects prefers-reduced-motion
- also verified (after a stale-Chrome scare) there is NO auth bug: cookieless
/api/auth/me returns null, fresh logged-out load shows Login (no admin nav),
and the public-agent Use flow works without login
- verified live: skeletons during load, no flash, real card+add-card after
- storefront header 'The mercenary roster' with a value-prop subtitle
- emoji category chips (uses TAG_EMOJI) so tags read as a directory
- always-present dashed 'Publish your own' card in the grid — the roster
never looks empty and it actively drives supply into My Booth
- verified live: header, emoji chips, and add-card all render
- remove dead 3D code: App/GemhallScene/SplashScene/ModelScene (unreferenced
since the 2D pivot) + the three dep and its empty manualChunk
- drop public/models (68MB of unused KayKit/poly-pizza GLBs)
- dist drops ~36MB -> 2.9MB; deploy now extracts to a staging dir and swaps
atomically (preserving .well-known), so users never see a mixed/stale state
and stale chunks no longer accumulate (28 -> 7 assets on the server)
- booth: welcoming first-run onboarding (3 steps to go live) replacing the
bare 'no classes yet' hint
- verified live: 2D home renders, 0 failed requests, booth welcome shows
- 'Embed this agent on any website' is now a prominent block with one-click Copy
(+ copyToast) instead of a buried <details>; usage hint included
- Web PTY mode points to the Backstage/后台 terminal tab
- core loop verified: browse -> Use -> live connected chatbox + embed snippet
- new #/account: profile card (avatar initials + role badge + quick links),
change-password, and agent keys consolidated in one place
- topbar username now opens Account; separate logout button
- password change moved out of the tavern signed-in panel into a proper settings surface
- agent detail modal header gets the class avatar
- My Booth 'My classes' rows get avatar + online-pulse indicator (matches Browse)
- online instance status dots pulse; consistent visual language across the app
- amerc-api: owner column migration + /api/keys GET/POST/DELETE (user-scoped)
- My Booth: 'My agent keys' card — mint, list, revoke, with Bearer usage hint
- unblocks any user wiring their own agent to amerc docs/netdisk/platform (was admin-only)