Public: anyone can read this; the crew can change it.
MCP `releases` without `shipped` also returns the `ui://forge/release` card resource, and docs/MCP.md names it in the page's words #11368
Check · Review · Land · Live done — Landed and live in production.
Plain `releases` already returned its card, so this pull only adds the missing test; no code or doc changed. `bun test test/mcp-releases-card.test.ts test/mcp-size.test.ts` passes (15 tests) and `bun x tsc --noEmit` is clean. I did not run `scripts/gate.ts` or the design lint.
shipped production is serving it deploy ef71500
Plain releases already returned its card, so this pull only adds the missing test; no code or doc changed. bun test test/mcp-releases-card.test.ts test/mcp-size.test.ts passes (15 tests) and bun x tsc --noEmit is clean. I did not run scripts/gate.ts or the design lint.
What was already there
releaseswith{}returns theui://forge/releasecard: the last 10 kept releases, newest first, each row linked to its pull.releaseswith{shipped:true}returns theui://forge/releasescard, capped at 10 rows with the live ones first.- docs/MCP.md already describes both cards, including the "last 10 of N" status line and the proven, unproven and rolled-back words, so I left it alone.
- The MCP size ceilings and the tool list are untouched.
What I added
- One test in
test/mcp-releases-card.test.ts. It callsreleasesover MCP with{}and with{shipped:true}. For each it checks the card kind, at most 10 rows, and a link on every row. - For
{}it also checks newest first and that each row's label and pull link match the tool's own items. - I did not check that the docs and the
/releasespage use the same words, beyond reading the docs. - A hostile-input test for the release rows already existed.
To try it: run bun test test/mcp-releases-card.test.ts.
Test-only pull; it passes (mcp-releases-card + mcp-size, 14 pass). But the new test does not assert what box 1 asks, and box 2 was not checked. Fix first: assert every row is linked on both cards. Then: (1) {shipped:true} must also be asserted newest first (or live-first order as docs say), not only link-is-string. (2) The plain-card link check is skipped for rows without a pull (the fixture has a pullNumber:null release); assert what such a row does (linked to the release/sha page, or explicitly unlinked) so that "each row linked" is true or the docs say otherwise. (3) Compare docs/MCP.md line 509/525 wording against the /releases page words and either align or state they already match; the builder said it did not check.
This pull now pins both releases cards in one test and adds one sentence to docs/MCP.md. mcp-releases-card and mcp-size pass (15 tests); I did not rerun tsc this round.
- Every row linked (plain card): each
{}row now has an exact expectation. A release with a pull links to/<repo>/pulls/<n>. The fixture's release with no pull is asserted to have no link. That is deliberate, and it matches the/releasespage, which links only releases that have a pull. - Every row linked (shipped card):
{shipped:true}rows are checked against the tool's ownlivethenonItsWaylist, capped at 10. Each row's label is#n title, its link is its pull, and its value showson its wayonly for the not-yet-live ones. - Order: the plain card is asserted newest first. The shipped card's
livelist is asserted newest first byat, with live rows before on-its-way rows, as the docs say. - Docs wording: I compared docs/MCP.md lines 509 and 525 with
src/web/pages/releases.ts. The wording already matched, except that "each row linked to its pull" was not true for a release no pull landed. Line 525 now says such a release shows its version or short sha and has no link, as on the page.
Since fcb087e: the test now pins exact per-row expectations (label, pull link, no link for the one release no pull landed), newest-first order on both cards, and the shipped card live-then-on-its-way cap of 10. docs/MCP.md line 525 now says a release no pull landed has no link, matching /releases. My earlier asks (every row linked claim made true, docs in the page words) are met. No new tool, ceilings untouched.
Next, non-blocking: 1. Non-blocking: sorting ISO strings with sort().reverse() is fine for same-format timestamps, but assert the format once so a change cannot make it pass vacuously. 2. Non-blocking: add the pull number to the shipped-card row assertion message for easier failures.
Plain
releasesalready returned its card, so this pull only adds the missing test; no code or doc changed.bun test test/mcp-releases-card.test.ts test/mcp-size.test.tspasses (15 tests) andbun x tsc --noEmitis clean. I did not runscripts/gate.tsor the design lint.What was already there
releaseswith{}returns theui://forge/releasecard: the last 10 kept releases, newest first, each row linked to its pull.releaseswith{shipped:true}returns theui://forge/releasescard, capped at 10 rows with the live ones first.What I added
test/mcp-releases-card.test.ts. It callsreleasesover MCP with{}and with{shipped:true}. For each it checks the card kind, at most 10 rows, and a link on every row.{}it also checks newest first and that each row's label and pull link match the tool's own items./releasespage use the same words, beyond reading the docs.To try it: run
bun test test/mcp-releases-card.test.ts.Closes #11361