FRE-359 verdict B dropped the agent count instead of correcting it: the page
said thirteen while `AgentSpec.all` held eighteen, and the /agents table listed
13 of those rows. The count is a fact, not a claim, so this states it and makes
the table match the registry again.
- Landing island bullet and the marquee chip say 18 agents.
- /agents: title/description/ogTitle/H1 at eighteen, and the five missing rows
are on the page — Kimi, GitHub Copilot CLI, Crush, Cursor, Amp — with events
and gating taken from hook/setup.go, hook/normalize.go,
hook/normalize_hosts.go, Sources/NookCore/Agents/HookConfigInstaller.swift
and plugins/amp/index.ts. All five are Observe (kimi/copilot PreToolUse and
PermissionRequest fire before the host's own check; Crush documents one
event; a silent Cursor permission hook blocks; Amp's plugin API has no
permission-wait event).
- agents.test.ts asserts the roster as an equality with the 18-name registry
in registry order again, plus the count, instead of a subset check.
- remote-claims.test.ts keeps every FRE-323 remote removal guard and the parked
copy, and drops only the two completeness bans the corrected count
contradicts ("every coding agent", "Supported agents") — the ban existed
because the page claimed the set and listed 13 of 18.
- positioning.md: the coverage row is publishable at 18.
This is the count/roster half of FRE-997 only. The remote-SSH restore is held
by the Chief of Staff against FRE-346 §3 and is not in this commit: no remote
tile, breakdown, demo, chip, /agents remote paragraph or drafts deletion here.
Gate: `bun test src/routes/nook` 18 pass / 0 fail; `bun run build` succeeds.
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
/**
|
|
* Regression test for the /agents roster and its coverage count.
|
|
*
|
|
* The page mirrors the app's registry, `AgentSpec.all` in
|
|
* the-nook/Sources/NookCore/Agents/AgentRegistry.swift. When Muse joined
|
|
* the registry in 0.10.0 the page kept twelve entries and kept saying
|
|
* "twelve", so a shipped agent was missing from the one page that lists
|
|
* them. The registry lives in another repo, so the expected roster is
|
|
* restated here; when an agent is added there, add it here and on the page.
|
|
*
|
|
* FRE-997 restored the count. The page said thirteen while the registry held
|
|
* eighteen, so the count was dropped rather than corrected (FRE-359 verdict B);
|
|
* now that all eighteen rows are on the page, the roster check is an equality
|
|
* check again and the page states eighteen. A subset check would let a shipped
|
|
* agent go missing behind a passing suite, which is the NOOK-336 failure.
|
|
*
|
|
* STATIC SOURCE AUDIT, the same pattern as the downloads regressions.
|
|
*/
|
|
import { describe, it, expect } from "bun:test";
|
|
import { readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const SOURCE = readFileSync(join(import.meta.dir, "agents.tsx"), "utf8");
|
|
|
|
/** User-facing copy only: comments are not copy and may name the old wording. */
|
|
const COPY = SOURCE.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
|
|
|
/** AgentSpec.all display names, in registry order (18 rows). @ The-Nook f4258034, 2026-10-29 */
|
|
const REGISTRY = [
|
|
"Claude Code",
|
|
"Codex",
|
|
"OpenCode",
|
|
"Pi",
|
|
"Oh My Pi",
|
|
"Muse",
|
|
"Hermes",
|
|
"OpenClaw",
|
|
"Z.ai (ZCode)",
|
|
"Gemini CLI",
|
|
"Cline",
|
|
"Qwen Code",
|
|
"DeepSeek",
|
|
"Kimi",
|
|
"GitHub Copilot CLI",
|
|
"Crush",
|
|
"Cursor",
|
|
"Amp"
|
|
];
|
|
|
|
const entries = [...SOURCE.matchAll(/^\s{4}name: "([^"]+)",$/gm)].map((m) => m[1]);
|
|
|
|
describe("Nook /agents roster", () => {
|
|
it("lists every registry agent, once, in registry order", () => {
|
|
expect(entries).toEqual(REGISTRY);
|
|
});
|
|
|
|
it("states the registry's size", () => {
|
|
expect(entries.length).toBe(18);
|
|
expect(COPY).toContain("all eighteen");
|
|
expect(COPY).toContain("The 18 agents");
|
|
expect(COPY).toContain("eighteen coding agents");
|
|
});
|
|
|
|
it("carries no stale count", () => {
|
|
expect(COPY.toLowerCase()).not.toContain("thirteen");
|
|
expect(COPY).not.toMatch(/\b13 agents\b/);
|
|
expect(COPY).not.toContain("all thirteen");
|
|
});
|
|
});
|