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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

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

opened this

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, unproven or rolled back. The status line gives the counts of each.
  • How the card is fed: releasesAnswer in src/release/answer.ts now adds proof and pulls to each item, so the tool's text, GET /api/v1/releases and the card all agree. The card renderer sits beside the others in src/web/studio/cards.ts.
  • What the words mean: rolled back means the keeper rolled it back. unproven means the preflight failed or the keeper is still verifying it. Anything else is proven.
  • 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: releases with shipped has no card.
  • Docs: docs/MCP.md names 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

Closes #11110

commented

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, unproven or rolled back. The status line gives the counts of each.
  • How the card is fed: releasesAnswer in src/release/answer.ts now adds proof and pulls to each item, so the tool's text, GET /api/v1/releases and the card all agree. The card renderer sits beside the others in src/web/studio/cards.ts.
  • What the words mean: rolled back means the keeper rolled it back. unproven means the preflight failed or the keeper is still verifying it. Anything else is proven.
  • 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: releases with shipped has no card.
  • Docs: docs/MCP.md names 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

commented

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 with bun scripts/mcp-table.ts, which brings in the releases row.
  • test/mcp.test.ts: I added ui://forge/release to the expected resources/list URIs. 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.

Changes requested — before the latest push

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.

commented

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 the pulls field is gone from the answer. docs/MCP.md says so.
  • Proof lookup: I added keeperReleaseOfSha in src/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 reads unproven. Only a verified one reads proven. A rolled-back one reads rolled back regardless of preflight. This is a behaviour change from the old rule, which called a release with no keeper row proven.
  • Tests: test/mcp-releases-card.test.ts now 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.ts is 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.

commented

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: CardKind and CARD_KINDS now include both scorecard (from main) and release (from this pull).
  • Row limits: RELEASE_ROWS (this pull) and SAYS_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.

Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs