From d67a6eeb47b0452710cfd98a1b17f41660036aeb Mon Sep 17 00:00:00 2001 From: medking82 <19301787+medking82@users.noreply.github.com> Date: Mon, 3 Aug 2026 22:42:43 +0800 Subject: [PATCH] Document and test Fable model support --- AGENTS.md | 4 ++ README.md | 17 ++++++ .../scripts/claude-companion.mjs | 12 +++-- .../skills/claude/SKILL.md | 54 ++++++++++++++----- tests/commands.test.mjs | 1 + tests/runtime.test.mjs | 22 ++++++++ tests/validate-plugin.mjs | 4 +- 7 files changed, 95 insertions(+), 19 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3aa63f1..dcba29a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,6 +30,10 @@ Codex remains the orchestrator. work to Sonnet. - Let Claude Code use the user's configured default model unless the user explicitly asks for another model. +- Use Fable only when the user explicitly asks for it; do not make it the + advisor, review, rescue, or delegation default. +- Keep explicit model values as pass-through CLI arguments. Do not add a local + allowlist that would reject full model names or future Claude Code aliases. - Pass xhigh effort for Claude advisor, review, adversarial-review, rescue, and background work unless the user explicitly asks for another effort. - Use Sonnet only for junior-agent delegation governed by the diff --git a/README.md b/README.md index 9d8402d..4b4a2b2 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,14 @@ The stable command form is `$claude`. If your Codex UI exposes the skill as active, stale, or finished. - `$claude status`, `$claude result`, and `$claude cancel` manage Claude jobs. +Pass `--model fable`, `--model opus`, `--model sonnet`, or a full model name to +select a model explicitly. The companion forwards the value to Claude Code +unchanged. Omit `--model` to use your configured default. + Longer jobs can run in the background: ```text +$claude advise --background --model fable challenge this architecture decision $claude advise --background should this VAD tuning loop collect N=5 now? $claude do --background --model sonnet map the auth module and return file:line citations $claude rescue --background --model opus investigate the flaky integration test @@ -107,6 +112,9 @@ syntax errors. - Claude Code installed and authenticated on the same machine. - Node.js 18.18 or newer. +Using `--model fable` also requires a Claude Code build and account that expose +the `fable` alias. Run `$claude setup` after upgrading Claude Code. + ## Local Development From a local checkout: @@ -129,7 +137,9 @@ Use `$claude` in a Codex thread: ```text $claude setup +$claude advise --background --model fable challenge this architecture decision $claude advise --background should this plan use a background worker? +$claude do --background --model fable inspect the proposed design and cite risks $claude do --background --model sonnet map this package and cite file:line call sites $claude do --background --model opus debug this cross-module failure with a prepared task $claude rescue --background --model opus investigate the flaky integration test @@ -179,6 +189,10 @@ Review and adversarial review are read-only. `advise` and `rescue` are also read-only unless you pass `--write`. Write-capable Claude work is recorded as a separate job type. +Fable is an explicit opt-in, not a new default. Use `--model fable` only when +the user asks for it. The same read-only, prepared-task, MCP, web, and +explicit-write boundaries continue to apply. + `$claude do --model sonnet` is for prepared junior-agent work. Before using it, Codex should apply `tasks-for-sonnet` and turn the request into a bounded task: role, absolute paths, word cap, What Must Be True, Known Constraints, Mechanical @@ -296,6 +310,9 @@ through the installed skill. Sonnet is used only for this small routing test. - The plugin depends on the installed Claude Code CLI contract. Run `$claude setup` after upgrading Claude Code. +- Model aliases and full model names are resolved by the installed Claude Code + CLI. Fable availability therefore depends on the installed version and + account; the companion does not translate or locally allowlist model names. - Background mode is optional. If the companion cannot verify `claude --bg`, `claude agents`, `claude logs`, `claude attach`, and `claude stop`, it degrades to foreground-only behavior. diff --git a/plugins/claude-code-advisor/scripts/claude-companion.mjs b/plugins/claude-code-advisor/scripts/claude-companion.mjs index 490c951..89c35b1 100755 --- a/plugins/claude-code-advisor/scripts/claude-companion.mjs +++ b/plugins/claude-code-advisor/scripts/claude-companion.mjs @@ -136,7 +136,7 @@ function isMeaningfulLogLine(line) { if (/^warning: the 'NO_COLOR' env is ignored/i.test(text) || /^at\s+/.test(text) || /\binternal:/.test(text)) { return false; } - if (/opus|sonnet|haiku|claude max/i.test(text)) { + if (/fable|opus|sonnet|haiku|claude max/i.test(text)) { return false; } if (/thinking with .* effort/i.test(text)) { @@ -798,16 +798,18 @@ function printUsage() { [ "Usage:", " claude-companion setup [--json]", - " claude-companion advise [--background] [--write] [--max-turns ] [--effort ] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]", + " claude-companion advise [--background] [--write] [--model ] [--max-turns ] [--effort ] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]", " claude-companion do [--background] [--write] [--model ] [--max-turns ] [--effort ] [--allow-mcp] [--allow-web] [prompt]", " claude-companion rescue [--background] [--write] [--resume] [--model ] [--max-turns ] [--effort ] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]", - " claude-companion review [--base ] [--max-turns ] [--effort ] [--json]", - " claude-companion adversarial-review [--base ] [--max-turns ] [--effort ] [focus] [--json]", + " claude-companion review [--base ] [--model ] [--max-turns ] [--effort ] [--json]", + " claude-companion adversarial-review [--base ] [--model ] [--max-turns ] [--effort ] [focus] [--json]", " claude-companion monitor [job-id] [--interval-ms ] [--max-checks ] [--stale-after-ms ] [--json]", " claude-companion status [job-id] [--watch] [--json]", " claude-companion result [job-id] [--json]", " claude-companion cancel [job-id] [--json]", - " claude-companion resume-candidate [--json]" + " claude-companion resume-candidate [--json]", + "", + "Models are passed through to Claude Code. Examples: fable, opus, sonnet, or a full model name." ].join("\n") + "\n" ); } diff --git a/plugins/claude-code-advisor/skills/claude/SKILL.md b/plugins/claude-code-advisor/skills/claude/SKILL.md index 404f1e6..69a415f 100644 --- a/plugins/claude-code-advisor/skills/claude/SKILL.md +++ b/plugins/claude-code-advisor/skills/claude/SKILL.md @@ -3,10 +3,10 @@ name: claude description: > Use when the user asks Codex to consult Claude Code, run a Claude advisor pass, get a Claude adversarial review, check a plan or diff with Claude, - ask Claude to do a prepared coding, exploration, verifier, scout, or rescue - task, inspect Claude advisor job status, fetch a Claude result, or cancel a - Claude advisor job. This skill routes through the bundled claude-companion.mjs - runtime; it does not call the Claude CLI directly. + ask Claude Fable, Opus, or Sonnet to do a prepared coding, exploration, + verifier, scout, or rescue task, inspect Claude advisor job status, fetch a + Claude result, or cancel a Claude advisor job. This skill routes through the + bundled claude-companion.mjs runtime; it does not call the Claude CLI directly. --- # Claude Code Advisor @@ -21,11 +21,11 @@ Canonical forms: ```text $claude setup -$claude advise [--max-turns ] -$claude do [--background] [--write] [--model sonnet|opus] [--max-turns ] -$claude rescue [--background] [--write] [--resume] [--model sonnet|opus] [--max-turns ] -$claude review [--base ] -$claude adversarial-review [--base ] [focus] +$claude advise [--background] [--model ] [--max-turns ] +$claude do [--background] [--write] [--model ] [--max-turns ] +$claude rescue [--background] [--write] [--resume] [--model ] [--max-turns ] +$claude review [--base ] [--model ] +$claude adversarial-review [--base ] [--model ] [focus] $claude monitor [job-id] $claude status [job-id] $claude result [job-id] @@ -33,6 +33,11 @@ $claude cancel [job-id] $claude resume-candidate ``` +The companion passes explicit model values through to Claude Code unchanged. +Common aliases include `fable`, `opus`, and `sonnet`; full model names accepted +by the installed Claude Code CLI also work. Omit `--model` to use the user's +configured default. + If Codex passes slash-style text through to this skill, normalize it before routing: @@ -75,9 +80,12 @@ commands. The guaranteed Codex surface is the `$claude` skill mention. default: `Read,Glob,Grep`. `advise` may use web tools. For `do` and `rescue`, enable `WebFetch` or `WebSearch` only when the task needs web access and `--allow-web` is explicit. -- Do not pass `--model sonnet` for advice, review, adversarial-review, rescue, - or monitor work unless the user explicitly asks for Sonnet. Let Claude Code - use the user's configured default model. +- Do not pass an explicit `--model` for advice, review, + adversarial-review, rescue, or delegation work unless the user explicitly + asks for that model. Let Claude Code use the user's configured default model. +- Pass explicit model values through unchanged. Do not translate `fable` or + maintain a local model allowlist; the installed Claude Code CLI is the source + of truth for supported aliases and full model names. - Pass `--effort xhigh` for advice, review, adversarial-review, rescue, and background jobs unless the user explicitly asks for another effort. - Sonnet is reserved for explicit junior-agent delegation governed by the @@ -101,7 +109,8 @@ commands. The guaranteed Codex surface is the `$claude` skill mention. - `setup`: run the companion setup command and show the result. - `advise`: use for architecture questions, second opinions, and checker work. Use `--background` for substantive prompts, large context, or anything likely - to need more than one short answer. + to need more than one short answer. Honor an explicit model request such as + `--model fable`; otherwise omit `--model`. - `do`: use only for a specific prepared task. This is the preferred route when the user asks Claude to do coding, exploration, scout, verifier, reviewer, or synthesis work. For Sonnet, first apply `tasks-for-sonnet`; then route the @@ -125,6 +134,7 @@ For long-running work, prefer: ```bash node "/scripts/claude-companion.mjs" advise --background "" +node "/scripts/claude-companion.mjs" advise --background --model fable "" node "/scripts/claude-companion.mjs" do --background --model sonnet "" node "/scripts/claude-companion.mjs" do --background --model opus "" node "/scripts/claude-companion.mjs" rescue --background --model opus "" @@ -202,6 +212,23 @@ work around them when copying commands: --mcp-config '{"mcpServers":{}}' --strict-mcp-config --no-chrome ``` +## Explicit Fable Tasks + +Use `--model fable` only when the user explicitly asks for Fable. The companion +forwards the alias unchanged and Claude Code resolves it according to the +installed CLI and account. Keep the same read-only, task-preparation, MCP, web, +and explicit-write boundaries used by the selected route. + +```text +$claude advise --background --model fable +$claude do --background --model fable +``` + +```bash +node "/scripts/claude-companion.mjs" advise --background --model fable --effort xhigh "" +node "/scripts/claude-companion.mjs" do --background --model fable --effort xhigh "" +``` + ## Prepared Opus Tasks Use `$claude do --model opus` when the user asks Claude to do a complex task @@ -243,6 +270,7 @@ Examples: node "/scripts/claude-companion.mjs" setup --json node "/scripts/claude-companion.mjs" adversarial-review --base main --json node "/scripts/claude-companion.mjs" advise --background --effort xhigh "" +node "/scripts/claude-companion.mjs" advise --background --model fable --effort xhigh "" node "/scripts/claude-companion.mjs" do --background --model sonnet --effort xhigh "" node "/scripts/claude-companion.mjs" do --background --model opus --effort xhigh "" node "/scripts/claude-companion.mjs" monitor --interval-ms 30000 --stale-after-ms 120000 diff --git a/tests/commands.test.mjs b/tests/commands.test.mjs index 8b0abed..34c5883 100644 --- a/tests/commands.test.mjs +++ b/tests/commands.test.mjs @@ -265,6 +265,7 @@ if (args[0] === "logs") { console.log("at refresh (internal:util/colors:18:31)"); console.log("at loadAssertionError (node:assert:28:96)"); console.log("▝▜█████▛▘Opus 4.7 with xhigh effort"); + console.log("▝▜█████▛▘Fable 5 with xhigh effort"); console.log("▘▘ ▝▝ ~/Documents/GitHub/claude-plugin-codex"); console.log("❯ Return exactly PASS."); console.log("✳Hyperspacing…"); diff --git a/tests/runtime.test.mjs b/tests/runtime.test.mjs index 45e6b8f..2b2186d 100644 --- a/tests/runtime.test.mjs +++ b/tests/runtime.test.mjs @@ -79,6 +79,28 @@ test("buildClaudeArgs passes explicit effort", () => { assert.deepEqual(args.slice(args.indexOf("--effort"), args.indexOf("--effort") + 2), ["--effort", "xhigh"]); }); +test("argument builders pass Fable through for foreground and background work", () => { + const foreground = buildClaudeArgs({ + mode: "advise", + prompt: "check this", + model: "fable" + }); + const background = buildBackgroundArgs({ + prompt: "check this", + name: "codex-advice", + model: "fable" + }); + + assert.deepEqual(foreground.slice(foreground.indexOf("--model"), foreground.indexOf("--model") + 2), [ + "--model", + "fable" + ]); + assert.deepEqual(background.slice(background.indexOf("--model"), background.indexOf("--model") + 2), [ + "--model", + "fable" + ]); +}); + test("buildClaudeArgs keeps local read-only tasks off web tools by default", () => { const args = buildClaudeArgs({ mode: "do", diff --git a/tests/validate-plugin.mjs b/tests/validate-plugin.mjs index 036842c..c439e62 100644 --- a/tests/validate-plugin.mjs +++ b/tests/validate-plugin.mjs @@ -26,12 +26,13 @@ assert.match(skill, /claude-companion\.mjs/); assert.match(skill, /\/claude:rescue/); assert.match(skill, /\/claude:do/); assert.match(skill, /tasks-for-sonnet/); +assert.match(skill, /\$claude do --background --model fable/); assert.match(skill, /\$claude do --model opus/); assert.match(skill, /complex\/high-judgment/); assert.match(skill, /What Must Be True/); assert.match(skill, /Mechanical Verification/); assert.match(skill, /\$claude monitor/); -assert.match(skill, /Do not pass `--model sonnet`/); +assert.match(skill, /Do not pass an explicit `--model`/); assert.match(skill, /`--effort xhigh`/); assert.match(skill, /--stale-after-ms 120000/); assert.match(skill, /--mcp-config/); @@ -50,6 +51,7 @@ assert.match(readme, /ancestor directories/); assert.match(readme, /Unable to load skill contents/); assert.match(readme, /\$claude do/); assert.match(readme, /tasks-for-sonnet/); +assert.match(readme, /--model fable/); assert.match(readme, /\$claude do --model opus/); assert.match(readme, /\$claude advise --model sonnet/); assert.match(e2e, /--model sonnet/);