/** * `/agents` on the Nook subdomain — all eighteen agents in the registry and * each row's event coverage. * * The registry below mirrors `AgentSpec.all` in the app * (~/Code/the-nook/Sources/NookCore/Agents/AgentRegistry.swift) and each * agent's installed hook surface (hook/setup.go) or plugin event subscription * (plugins/*), normalized onto the shared event vocabulary * (~/Code/the-nook/docs/agent-interface.md). Copy follows * marketing/positioning.md: category nouns, honest scoping, no unverifiable * claims. */ import { For } from "solid-js"; import { PageHead } from "~/components/PageHead"; import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders"; import SubdomainHeader from "~/components/SubdomainHeader"; interface AgentEntry { name: string; /** How The Nook connects to this agent. */ wiring: string; /** Events the installed hook/plugin reports, on the shared vocabulary. */ events: string[]; /** What the agent can be asked to do from a Nook card. */ gating: string; } const AGENTS: AgentEntry[] = [ { name: "Claude Code", wiring: "Hook entries in its settings, calling the shared hook binary", events: [ "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SessionError", "SubagentStart", "SubagentStop", "Notification", "PreToolUse", "PermissionRequest", "PostToolUse", "PostToolUseFailure", "PermissionDenied", "PreCompact" ], gating: "Full — tool calls and permission prompts can be allowed or denied from a card" }, { name: "Codex", wiring: "Hook entries in its config, with its hooks feature enabled", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PostToolUse", "Stop", "SessionError" ], gating: "Full — command/file approvals and user-input questions can be answered from a card" }, { name: "OpenCode", wiring: "In-process plugin on its server bus", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionError", "MessageUpdate", "PermissionRequest", "QuestionAsked" ], gating: "Full — the plugin answers OpenCode's own permission API when you tap Allow or Deny" }, { name: "Pi", wiring: "In-process extension registered in its settings", events: [ "SessionStart", "SessionEnd", "AgentStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionError", "MessageUpdate", "QuestionAsked", "QuestionResolved" ], gating: "Full when you force verification — Pi alone never asks natively, so the gate engages on the approval tool" }, { name: "Oh My Pi", wiring: "In-process extension package", events: [ "SessionStart", "SessionEnd", "AgentStart", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PermissionResolved", "PostToolUse", "Stop", "SessionError", "MessageUpdate", "QuestionAsked", "QuestionResolved" ], gating: "Full — honors the agent's own approval tiers, per-tool policies included" }, { name: "Muse", wiring: "Plugin 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: "Shell-hook entries in the agent's config, consent-gated by allowlist", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "Stop", "PreToolUse", "PostToolUse", "SubagentStart", "SubagentStop", "QuestionAsked" ], gating: "Observation — every event appears as a card; the agent keeps its own prompting" }, { name: "OpenClaw", wiring: "Hook handler package in its hooks directory", events: [ "SessionStart", "UserPromptSubmit", "Stop", "SessionError", "PreCompact", "SessionEnd" ], gating: "Observation — strict fire-and-forget; the agent surface has no tool or permission events" }, { name: "Z.ai (ZCode)", wiring: "Hook entries in its CLI config", events: [ "SessionStart", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PostToolUse", "PostToolUseFailure", "Stop" ], gating: "Full — tool calls and permission prompts can be allowed or denied from a card" }, { name: "Gemini CLI", wiring: "Hook entries in its settings", events: [ "SessionStart", "SessionEnd", "AgentStart", "Stop", "SessionError", "Notification" ], gating: "Observation — every event appears as a card; the agent keeps its own prompting" }, { name: "Cline", wiring: "One hook file per event in its hooks directory. This Mac only — remote hosts skip it", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "PreCompact", "Notification" ], gating: "Observation — every event appears as a card; the agent keeps its own prompting" }, { name: "Qwen Code", wiring: "Hook entries in its settings (same surface as the Claude-style schema)", events: [ "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "Notification", "PreToolUse", "PermissionRequest", "PostToolUse", "PostToolUseFailure", "PermissionDenied", "PreCompact" ], gating: "Full — tool calls and permission prompts can be allowed or denied from a card" }, { name: "DeepSeek", wiring: "A standalone hooks file its bridge is pointed at", events: [ "SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SubagentStart", "SubagentStop" ], gating: "Tool calls can be allowed or denied from a card; permission prompts stay with the agent" }, { name: "Kimi", wiring: "Hook rules in its TOML config, one per event", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "AgentStart", "PreToolUse", "PermissionRequest", "PermissionResolved", "PostToolUse", "PostToolUseFailure", "Stop", "SessionError", "SubagentStart", "SubagentStop", "PreCompact", "Notification" ], gating: "Observation — every event appears as a card; its PreToolUse fires before its own permission check, so the agent keeps its own prompting" }, { name: "GitHub Copilot CLI", wiring: "One hook file of ours in its hooks directory", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PreToolUse", "PermissionRequest", "PostToolUse", "PostToolUseFailure", "Stop", "SubagentStart", "SubagentStop", "ErrorOccurred", "PreCompact", "Notification" ], gating: "Observation — every event appears as a card; its permission request runs before its own policy check, so the agent keeps its own prompting" }, { name: "Crush", wiring: "One entry in its JSONC config, the only event it documents", events: ["PreToolUse"], gating: "Observation — tool calls appear as cards; its own permission prompts decide" }, { name: "Cursor", wiring: "Hook entries in its hooks.json, merged with your own. No permission hook, on purpose", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PostToolUse", "PostToolUseFailure", "Stop", "SessionError", "AfterAgentResponse", "SubagentStop", "PreCompact" ], gating: "Observation — a permission hook that stays silent blocks the action here, so Cursor keeps its own prompting" }, { name: "Amp", wiring: "In-process extension package. This Mac only — remote hosts skip it", events: [ "SessionStart", "SessionEnd", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionError" ], gating: "Observation — its plugin API has no permission-wait event, so the agent keeps its own prompting" } ]; const GATING_BADGE: Record = { full: { label: "Allow / Deny from a card", class: "text-green border-green/40 bg-green/10" }, observation: { label: "Observe", class: "text-blue border-blue/40 bg-blue/10" } }; function gatingKey(entry: AgentEntry): "full" | "observation" { return entry.gating.startsWith("Full") ? "full" : "observation"; } export default function NookAgentsPage() { return ( <>

Supported agents

The Nook watches eighteen 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.

Each agent reports its own set of events. "Allow / Deny from a card" means the agent hands the decision to The Nook while it waits; "Observe" means every event still appears live, but the agent keeps its own prompting. Agents can run on this Mac or on remote machines over SSH — remote sessions report into the same grid. Muse, Cline and Amp run on this Mac only.

{(agent) => (

{agent.name}

{GATING_BADGE[gatingKey(agent)].label}

{agent.wiring}

Events reported

{(event) => ( {event} )}

{agent.gating}

)}

Running something else? A custom agent can wire itself in with the same one-line contract the built-in integrations use.

); }