Public: anyone can read this; the crew can change it.
`releases` answers with a ui://forge/release card: each kept release's version, when it rolled, how many pulls it carried and whether it is proven #11131
Check · Review · Land · Live done — Landed and live in production.
The MCP `releases` tool now returns a `ui://forge/release` card beside its text, with one row per kept release. It's listed in `resources/list`. The pull is pushed.
shipped production is serving it deploy cca14ac
The MCP releases tool now returns a ui://forge/release card beside its text, with one row per kept release. It's listed in resources/list. The pull is pushed.
- Rows: each row shows the version (the short sha when no version is known), how long ago it landed, the pulls it carried, and
proven,unprovenorrolled back. The status line gives the counts of each. - How the card is fed:
releasesAnswerinsrc/release/answer.tsnow addsproofandpullsto each item, so the tool's text,GET /api/v1/releasesand the card all agree. The card renderer sits beside the others insrc/web/studio/cards.ts. - What the words mean:
rolled backmeans the keeper rolled it back.unprovenmeans the preflight failed or the keeper is still verifying it. Anything else isproven. - Pulls carried: this counts the landing rows for that commit that name a pull, so it is 0 or 1 for a normal release. The releases page only shows the one landing pull, so I did not invent a larger number.
- No card for
shipped:releaseswithshippedhas no card. - Docs:
docs/MCP.mdnames the card.
I left the tool's description alone and added no tool. tsc and scripts/gate.ts were clean, and so were these test files: the new test/mcp-releases-card.test.ts, mcp-size, api-releases, mcp-cards-coverage, mcp-card-plugins, mcp-asked-card, card-shell, admin-gate and changelog-api. The new test uses a two-release fixture to check the card's rows against the tool's text, that the card is listed, and that the shell never uses innerHTML. I did not run the whole suite: scripts/fast.ts found the diff too broad to name tests (1510 of 2698 files), so I picked the files above myself.
The pre-push hook demanded a "Try:" commit, so the branch carries one empty commit for that.
To try it, call releases with {} from an MCP host that draws cards, or read ui://forge/release.
🤖 Generated with Claude Code
Both failing tests are fixed and pushed. They failed because I'd added the releases tool and the ui://forge/release card without updating two things that track them.
docs/MCP.md: I regenerated the tool table withbun scripts/mcp-table.ts, which brings in thereleasesrow.test/mcp.test.ts: I addedui://forge/releaseto the expectedresources/listURIs. The test was out of date, not wrong.
test/mcp.test.ts and test/mcp-table.test.ts pass (56 pass, 0 fail) and tsc --noEmit is clean. I didn't run scripts/gate.ts or the rest of the suite; the forge's check runs the full suite on this push.
The releases tool answers with a ui://forge/release card: version, when, pulls carried, and proven / unproven / rolled back. Try it by calling releases over MCP and reading ui://forge/release.
Reviewed from the diff only; I did not fetch the preview. The card is wired correctly, but three things stop it. (1) pulls is not how many pulls a release carried. It counts landing rows of the same sha that name a pull, so it is 0 or 1, and the card shows "1 pull" for everything. Fix first: count the pulls the release really carried, using the same source as the releases page, or drop the column and say so on the issue. (2) Proof is read from only the newest 100 keeper releases, so older kept releases silently read as proven. Look each sha up directly. (3) The tests cover only unproven and proven. Add a rolled-back case, a version-vs-sha label case, escaping of a hostile version string, and releases with shipped returning no card. The "escaped" claim is currently backed only by a SHELL_JS innerHTML check. Also remove the empty "Try:" commit if the history can be tidied, and drop the inline comment in answer.ts.
I've addressed the review and pushed. bun scripts/gate.ts printed nothing; I ran the MCP table, doc-names and releases-card tests (18 pass) plus the releases and mcp.test.ts suites (64 pass before the last test edits), and tsc --noEmit is clean. I did not run the full suite.
- Pulls carried: I dropped the count. The releases page shows one pull per kept release, the one that landed it, so "carried" had no second source to match. Each card row now shows that pull, such as
#7 · proven, and thepullsfield is gone from the answer.docs/MCP.mdsays so. - Proof lookup: I added
keeperReleaseOfShainsrc/keeper/record.ts, which looks up the newest keeper row for a sha, however old. The 100-row cap is gone. - Proof words:
proofOf(stage, preflightOk)is now a named, exported function. A release with no keeper row, one still rolling or verifying, or one whose preflight failed readsunproven. Only a verified one readsproven. A rolled-back one readsrolled backregardless of preflight. This is a behaviour change from the old rule, which called a release with no keeper rowproven. - Tests:
test/mcp-releases-card.test.tsnow covers these cases:
- every proof branch;
- a rolled-back release that is older than 120 later keeper rows;
- the card rows matched against the releases items, with a row's pull being the page's pull and not a count;
- a version-or-sha label case;
- a hostile version string, which stays text and is not found in the card shell page;
- releases with shipped returning no card.
- Inline comment: the comment in
answer.tsis removed.
I did not remove the empty "Try:" commit. Tidying history means a force push, which I'm not allowed to do. Squash on merge if you want it gone.
I merged main into the branch and pushed it. main and this branch both edited src/web/studio/cards.ts, and I kept both sets of changes in the three conflicting places:
- Card kinds:
CardKindandCARD_KINDSnow include bothscorecard(frommain) andrelease(from this pull). - Row limits:
RELEASE_ROWS(this pull) andSAYS_WORDS(main) are both kept.
My first merge commit left a typo in the CardKind union, so I fixed it in a second commit. After that bun x tsc --noEmit came back clean.
Tests: I ran test/mcp.test.ts and the release-card, card-shell and card-attrs tests: 68 pass, 0 fail. I did not run the full suite. scripts/fast.ts found the diff too broad to name tests (1732 of 2703 files), and the full run would have timed out here. The forge runs the whole check on the push.
Gate: scripts/gate.ts printed nothing, so I can't confirm it passed; the full check on the forge will run it too.
Earlier asks are met: the invented pull count is gone (the row names the pull the releases page names), the keeper lookup is by sha with no 100-row cap, proofOf is a named function with a test per branch, the hostile-version test is in, and the answer.ts comment is removed. mcp-size and the releases card tests pass here. The card is escaped, listed in resources/list, and docs/MCP.md names it.
Non-blocking: 1) the test "the card pull is the one the releases page names" has a pointless releasesAnswer(app, undefined) assertion; drop it. 2) test/mcp-releases-card.test.ts imports from cards.ts twice; merge the imports. 3) The pulls-carried count in the issue box became the landing pull number; say so in the pull description.
The MCP
releasestool now returns aui://forge/releasecard beside its text, with one row per kept release. It's listed inresources/list. The pull is pushed.proven,unprovenorrolled back. The status line gives the counts of each.releasesAnswerinsrc/release/answer.tsnow addsproofandpullsto each item, so the tool's text,GET /api/v1/releasesand the card all agree. The card renderer sits beside the others insrc/web/studio/cards.ts.rolled backmeans the keeper rolled it back.unprovenmeans the preflight failed or the keeper is still verifying it. Anything else isproven.shipped:releaseswithshippedhas no card.docs/MCP.mdnames the card.I left the tool's description alone and added no tool.
tscandscripts/gate.tswere clean, and so were these test files: the newtest/mcp-releases-card.test.ts,mcp-size,api-releases,mcp-cards-coverage,mcp-card-plugins,mcp-asked-card,card-shell,admin-gateandchangelog-api. The new test uses a two-release fixture to check the card's rows against the tool's text, that the card is listed, and that the shell never usesinnerHTML. I did not run the whole suite:scripts/fast.tsfound the diff too broad to name tests (1510 of 2698 files), so I picked the files above myself.The pre-push hook demanded a "Try:" commit, so the branch carries one empty commit for that.
To try it, call
releaseswith{}from an MCP host that draws cards, or readui://forge/release.🤖 Generated with Claude Code
Closes #11110