/** * Guard for the remote / SSH story on the Nook site, and for the two phrasings * that must not come back with it (FRE-323 → FRE-997). * * FRE-323 removed the remote copy because it had been checked against claims * the copy never made: the app does list hosts from `~/.ssh/config` and * Tailscale, a one-time `ssh-copy-id` is a normal prerequisite the row explains, * and the per-host credential is minted and copied automatically * (`RemoteHostDiscovery`, `RemoteHostStatus.fixCommand`, `RemoteMirror`). Two * things in the old copy were genuinely wrong, and this file guards those * instead of the copy as a whole: * * - "Works across every hooked agent, local or remote" overstated it. Muse, * Cline and Amp are `.unsupported` for remote in `AgentSpec.remote`, so the * landing bullet and the /agents paragraph name them. * - The count said thirteen while `AgentSpec.all` holds eighteen. The fix was * to say eighteen, not to drop the count. * * So the removal guards from `d44133f` are gone: a removed sentence is exactly * what this task restores. What stays is the pair of bans, because either one * coming back would repeat the original defect. * * STATIC SOURCE AUDIT, the same pattern as `agents.test.ts` and * `downloads.test.ts` (SolidJS does not render under `bun:test`). */ import { describe, it, expect } from "bun:test"; import { readFileSync } from "node:fs"; import { join } from "node:path"; const ROOT = join(import.meta.dir, "../../.."); /** Shipped page and component source. */ const AUDITED = [ "src/routes/nook/index.tsx", "src/routes/nook/agents.tsx", "src/routes/nook/faq.tsx", "src/components/nook/FeatureCollage.tsx", "src/components/nook/FeatureBreakdowns.tsx", "src/components/nook/IslandExtras.tsx" ]; /** The overstatements the restored copy must never carry again. */ const BANNED_REMOTE_CLAIMS = [ // a universal claim: three registry agents cannot mirror over SSH "every hooked agent, local or remote", "Works across every hooked agent", // the stale count this task replaced "13 agents", "all thirteen", "thirteen coding agents" ]; /** User-facing copy only: comments are not copy and may name the old wording. */ function copyOf(file: string): string { return readFileSync(join(ROOT, file), "utf8") .replace(/\/\*[\s\S]*?\*\//g, "") .replace(/^\s*\/\/.*$/gm, ""); } describe("the restored remote copy is on the site (FRE-997)", () => { it("the landing collage sells agents on other machines", () => { const copy = copyOf("src/components/nook/FeatureCollage.tsx"); for (const phrase of [ "Agents on other machines", "one click installs the nook-hook", "Remote" ]) { expect(copy).toContain(phrase); } }); it("the landing breakdown keeps the SSH section and its demo", () => { const copy = copyOf("src/components/nook/FeatureBreakdowns.tsx"); for (const phrase of [ "Any SSH box, one click away", "Pick a host from your ssh config or your tailnet and click once", "Remote sessions are ordinary rows", "RemoteHostDemo" ]) { expect(copy).toContain(phrase); } }); it("the chip is back", () => { expect(copyOf("src/components/nook/IslandExtras.tsx")).toContain( "One-click SSH setup" ); }); it("/agents says remote sessions report into the same grid", () => { const copy = copyOf("src/routes/nook/agents.tsx"); expect(copy).toContain("remote machines"); expect(copy).toContain("remote sessions report into the same grid"); }); }); describe("the two original overstatements stay off the site (FRE-323, FRE-359)", () => { for (const file of AUDITED) { it(`${file} claims no universal remote coverage and no stale count`, () => { const copy = copyOf(file); for (const phrase of BANNED_REMOTE_CLAIMS) { expect(copy.toLowerCase()).not.toContain(phrase.toLowerCase()); } }); } it("the landing names the agents that stay local", () => { expect(copyOf("src/components/nook/FeatureBreakdowns.tsx")).toContain( "Muse, Cline and Amp are this Mac only" ); }); });