A cut-off save that wasn't actually cut off, then a new onboarding flow that abstracts the words "token" and "mint" out of the user-facing experience. One file changed. One commit shipped.
C
by Claude (Opus 4.7, 1M context) · for Minjune Song · session ran from the article-rescue ask through the connect-flow ship
00TL;DR
1file edited (worker.ts)
5targeted edits
+161 / −82lines net
1new public route
1commit (ad16840e)
0schema migrations
01The article wasn't actually broken
Session opened with a forwarded transcript: claude.ai had been continuing Thariq Shihipar's Unreasonable Effectiveness of HTML as a v2 with seven interactive demos, and the message log appeared to truncate mid-byline (<div class="byline-). The ask: finish what got cut off.
Before rebuilding 60KB of HTML, I checked the cabinet's version history. v2 was already there:
v1 · initial publish28,675 B
2026-05-10 05:32 UTC · the safe, stately first cut
v2 · show, don't tell61,059 B
2026-05-10 05:46 UTC · drag-drop kanban, animated SVG, easing picker
The display layer had truncated the visible tool call. The POST /api/save went through anyway — the cabinet had the full 61KB payload with all seven demos.
A cut-off transcript isn't a cut-off save. Always check the destination, not the camera.
02The connect-flow refactor
You asked for two things, in two messages:
Replace the post-mint screen with a shareable URL a user can paste into Claude Code — like the teenyapp /agent/<token>/agents.md pattern. The agent fetches it, reads the embedded instructions + token, and starts using the app as a memory bank.
And while we're at it: stop saying mint and agent token. Just say connect your agent.
Both ship as one change. Toggle:
post-mint modal · same screen, different framing
Your new token
Save this — it won't be shown again. Use it as a Bearer token when calling /api/save.
The framing flip is small but load-bearing. Before, the user has to know what a Bearer token is, where to put it, and that there's a separate doc to read. After, they paste one link and the agent figures the rest out — by reading a markdown file the cabinet generates on the fly with the credentials baked in.
03The new route
The whole flow leans on one new endpoint: GET /agent/:token/agents.md. It validates the token's shape, looks it up, touches last_used, and returns a personalized markdown file with the bearer baked into every curl example.
// Agent instructions for a specific token. Designed to be pasted into Claude Code:// the URL contains both the credentials and the instructions, so the agent can// fetch it once and start using the cabinet as an HTML memory bank.userApp.get('/agent/:token/agents.md', async (c) => {
const token = c.req.param('token')
const headers = { 'content-type': 'text/markdown; charset=utf-8' }
if (!token || !/^agt_[a-f0-9]{48}$/.test(token)) {
returnnewResponse('# Not found\n\nInvalid token format.\n', { status: 404, headers })
}
const tokR = await db.rawSQL({
q: 'SELECT name FROM tokens WHERE token = ? LIMIT 1',
v: [token],
}).run()
const tok = tokR[0]
if (!tok) returnnewResponse('# Not found\n\nThis token does not exist...', { status: 404, headers })
// Touch last_used so the user can see this connection is active.await db.rawSQL({ q: `UPDATE tokens SET last_used = CURRENT_TIMESTAMP WHERE token = ?`, v: [token] }).run()
const md = `# HTML Cabinet — your shareable HTML memory bank
...
> **Connection name:** ${tok.name}
...
curl -X POST ${BASE_URL}/api/save \
-H 'Authorization: Bearer ${token}'
...`returnnewResponse(md, { status: 200, headers })
})
The token regex (/^agt_[a-f0-9]{48}$/) matches the format produced by generateToken(): 24 random bytes hex-encoded with the agt_ prefix. Anything else is rejected before the DB lookup, so the route is cheap to hammer.
04Try the cabinet's read API
This page is a doc in the cabinet — saved via the very flow described above. Click below to fetch its public version metadata. Same path Claude would use to recall this artifact in a future session.
Ping /api/docs/:slug/versions
live
GET https://html.app.teenyapp.com/api/docs/session-2026-05-09-connect-flow/versions
05Timeline
The actual order of operations. Click any step to expand.
Discovered v2 of Thariq's article was already savedstep 1
User pasted the cut-off claude.ai transcript and asked to finish what got truncated. Instead of immediately rebuilding from ~/Downloads/html.txt, hit the cabinet's version history endpoint. v2 was there at 61KB with the exact "show, don't tell" message claude.ai had drafted. The transcript display had truncated mid-byline; the underlying POST /api/save succeeded.
User confirmed: "v2 already exists, check"step 2
Re-checked /api/docs/unreasonable-effectiveness-of-html/versions. Confirmed v2 byte size matched the previously-drafted message. No reproduction needed.
New ask: change the post-mint screenstep 3
User wanted the modal to show a shareable URL like the teenyapp /agent/<token>/agents.md pattern, so a user can paste it into Claude Code as a memory bank pointer.
Refinement: "abstract out 'mint' and 'agent token' too"step 4
Renamed the primary CTA from Mint an agent token to Connect your agent. Modal headings became Connect your agent → Your agent is connected. Three-step explainer on the homepage rewritten around the link-paste flow.
Saved worker.ts locally, made 5 targeted editsstep 5
Pulled the file via GET /api/v1/projects/html/files?path=worker.ts. Edits: (a) header route comment, (b) tokenModalHTML() rewrite, (c) homepage hero copy, (d) three-step explainer, (e) entire /how-to page rewrite + new /agent/:token/agents.md route + agent_url field on /api/tokens response.
First PUT failed — body was JSON-wrappedstep 6
Sent the file as {"content": "..."}. The endpoint stored that literal string as the file content, breaking the build at virtual:worker.ts:1:10. Recovered by sending raw bytes with Content-Type: text/plain and the If-Match header from the previous etag.
Build green · committed ad16840e3154step 7
Bundle reported {"bundle":{"ok":true,"output":[]}}. Posted the commit with message "connect-flow: agent link replaces raw token; new /agent/:token/agents.md route".
Verified end-to-endstep 8
Minted a fresh token via POST /api/tokens — response now includes agent_url. Fetched /agent/<token>/agents.md — got 200 with personalized markdown ("Connection name: verify-connect-flow"). Hit a fake token — got 404 with markdown body.
You asked for this. Saving the session reportstep 9
You minted a fresh connection ("teest"), pasted its agent_url, and asked me to save a report of everything I did. I fetched the agents.md as the actual test of the new flow, extracted the bearer, and POSTed this HTML back via /api/save. The page you're reading is itself a verification that the connect flow works.