nook: list Muse on the agents page
nook.freno.me/agents listed twelve agents and said "twelve" in its meta description, OG title and intro, while the app's registry (AgentSpec.all) gained Muse in 0.10.0 as its thirteenth. The page mirrors that registry by hand from another repo, so nothing flagged the drift. Adds the Muse card from its plugin manifest and registry row: the plugin body at ~/.nook/plugins/muse installed through Muse's own plugins CLI, its fourteen hook events, approvals answerable from a card (every tool call under Verify), and this Mac only since remote hosts skip it. The positioning claims table and copy move to thirteen with it. Tests: src/routes/nook/agents.test.ts pins the roster to the registry's names in order (red on master: Muse missing) and every stated count to the number of entries (red when the intro says twelve again). NOOK-336 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ Primary source: `~/Code/the-nook/docs/marketing-strategy.md`.
|
||||
## The sentence
|
||||
|
||||
> **Your Mac and your agents, under control.** The Nook puts your whole coding-agent
|
||||
> fleet in the notch — twelve agents, local or over SSH — so you see what is running,
|
||||
> fleet in the notch — thirteen agents, local or over SSH — so you see what is running,
|
||||
> unblock it in one tap, and keep the machine from overheating while it works.
|
||||
|
||||
## The wedge
|
||||
@@ -50,7 +50,7 @@ pages, marketing copy, comparison tables, meta descriptions, emails, FAQs, all o
|
||||
|
||||
### 2. A claim requires a test to exist
|
||||
|
||||
Copy that says "12 agents" or "no data leaves the device" must have a test backing it.
|
||||
Copy that says "13 agents" or "no data leaves the device" must have a test backing it.
|
||||
If a claim cannot be pointed at code or a test, it does not go in copy.
|
||||
|
||||
### 3. Honest privacy scoping
|
||||
@@ -77,7 +77,7 @@ nothing posts itself.
|
||||
|
||||
| Claim | Backing |
|
||||
|---|---|
|
||||
| Twelve hooked agents, one glance | `AgentSpec.all` — claude, codex, opencode, pi, omp, hermes, openclaw, zai, gemini, cline, qwen, deepseek |
|
||||
| Thirteen hooked agents, one glance | `AgentSpec.all` — claude, codex, opencode, pi, omp, muse, hermes, openclaw, zai, gemini, cline, qwen, deepseek |
|
||||
| Remote agents over SSH | `hook/setup.go` remote install path; `NOOK_HOST` TCP transport |
|
||||
| Permission gate answered from a card | awaitPolicyTable + bridge directive path (`hook/normalize.go`, `serialize.go`) |
|
||||
| Fan / thermal / charge control | `helper/` (privileged helper, SMC, no kext) |
|
||||
@@ -87,7 +87,7 @@ nothing posts itself.
|
||||
|
||||
## Voice
|
||||
|
||||
- Short, concrete, no hype adjectives. Numbers over adjectives ("twelve agents",
|
||||
- Short, concrete, no hype adjectives. Numbers over adjectives ("thirteen agents",
|
||||
"one tap", "$10 once").
|
||||
- The notch/island is the product's home; agents are the product's point.
|
||||
- Never apologize for being a utility. The utility is the point.
|
||||
|
||||
54
src/routes/nook/agents.test.ts
Normal file
54
src/routes/nook/agents.test.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Regression test for the /agents roster (NOOK-336).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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");
|
||||
|
||||
/** AgentSpec.all display names, in registry order. */
|
||||
const REGISTRY = [
|
||||
"Claude Code",
|
||||
"Codex",
|
||||
"OpenCode",
|
||||
"Pi",
|
||||
"Oh My Pi",
|
||||
"Muse",
|
||||
"Hermes",
|
||||
"OpenClaw",
|
||||
"Z.ai (ZCode)",
|
||||
"Gemini CLI",
|
||||
"Cline",
|
||||
"Qwen Code",
|
||||
"DeepSeek"
|
||||
];
|
||||
|
||||
const NUMBER_WORDS = ["twelve", "thirteen", "fourteen", "fifteen"];
|
||||
|
||||
const entries = [...SOURCE.matchAll(/^\s{4}name: "([^"]+)",$/gm)].map((m) => m[1]);
|
||||
|
||||
describe("Nook /agents roster (NOOK-336)", () => {
|
||||
it("lists every registry agent, in registry order", () => {
|
||||
expect(entries).toEqual(REGISTRY);
|
||||
});
|
||||
|
||||
it("states the same count everywhere it names one", () => {
|
||||
const word = NUMBER_WORDS[entries.length - 12];
|
||||
for (const other of NUMBER_WORDS.filter((w) => w !== word)) {
|
||||
expect(SOURCE.toLowerCase()).not.toContain(other);
|
||||
}
|
||||
expect(SOURCE).toContain(`all ${word}`);
|
||||
expect(SOURCE).toContain(`The ${entries.length} agents`);
|
||||
expect(SOURCE).toContain(`watches ${word} coding agents`);
|
||||
});
|
||||
});
|
||||
@@ -105,6 +105,29 @@ const AGENTS: AgentEntry[] = [
|
||||
gating:
|
||||
"Full — honors the agent's own approval tiers, per-tool policies included"
|
||||
},
|
||||
{
|
||||
name: "Muse",
|
||||
wiring:
|
||||
"Plugin at ~/.nook/plugins/muse, installed, approved and enabled through Muse's own plugins CLI; each hook calls the shared hook binary. This Mac only — remote hosts skip it",
|
||||
events: [
|
||||
"SessionStart",
|
||||
"SessionEnd",
|
||||
"UserPromptSubmit",
|
||||
"PreToolUse",
|
||||
"PermissionRequest",
|
||||
"PostToolUse",
|
||||
"PostToolUseFailure",
|
||||
"Stop",
|
||||
"StopFailure",
|
||||
"Notification",
|
||||
"PreCompact",
|
||||
"PostCompact",
|
||||
"SubagentStart",
|
||||
"SubagentStop"
|
||||
],
|
||||
gating:
|
||||
"Full — permission prompts can be allowed or denied from a card, and every tool call under Verify"
|
||||
},
|
||||
{
|
||||
name: "Hermes",
|
||||
wiring:
|
||||
@@ -240,8 +263,8 @@ export default function NookAgentsPage() {
|
||||
<EdgeCacheHeaders maxAge={300} />
|
||||
<PageHead
|
||||
title="Supported agents"
|
||||
description="Every coding agent The Nook supports — all twelve, with each hook's exact event coverage and what you can do from a card: watch sessions live, answer permission prompts, unblock work."
|
||||
ogTitle="The 12 agents The Nook supports, and what each hook sees"
|
||||
description="Every coding agent The Nook supports — all thirteen, with each hook's exact event coverage and what you can do from a card: watch sessions live, answer permission prompts, unblock work."
|
||||
ogTitle="The 13 agents The Nook supports, and what each hook sees"
|
||||
/>
|
||||
<SubdomainHeader />
|
||||
<main class="min-h-screen px-[8vw] py-[8vh]">
|
||||
@@ -249,7 +272,7 @@ export default function NookAgentsPage() {
|
||||
Supported agents
|
||||
</h1>
|
||||
<p class="text-subtext0 mb-2 max-w-2xl text-lg">
|
||||
The Nook watches twelve coding agents in one place — your menu bar and
|
||||
The Nook watches thirteen coding agents in one place — your menu bar and
|
||||
notch show every session that is running, thinking, or blocked, and a
|
||||
card answers permission prompts without leaving your keyboard.
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user