Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 7 additions & 5 deletions plugins/claude-code-advisor/scripts/claude-companion.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -798,16 +798,18 @@ function printUsage() {
[
"Usage:",
" claude-companion setup [--json]",
" claude-companion advise [--background] [--write] [--max-turns <n>] [--effort <level>] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]",
" claude-companion advise [--background] [--write] [--model <model>] [--max-turns <n>] [--effort <level>] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]",
" claude-companion do [--background] [--write] [--model <model>] [--max-turns <n>] [--effort <level>] [--allow-mcp] [--allow-web] [prompt]",
" claude-companion rescue [--background] [--write] [--resume] [--model <model>] [--max-turns <n>] [--effort <level>] [--allow-mcp] [--allow-web] [--no-background-fallback] [prompt]",
" claude-companion review [--base <ref>] [--max-turns <n>] [--effort <level>] [--json]",
" claude-companion adversarial-review [--base <ref>] [--max-turns <n>] [--effort <level>] [focus] [--json]",
" claude-companion review [--base <ref>] [--model <model>] [--max-turns <n>] [--effort <level>] [--json]",
" claude-companion adversarial-review [--base <ref>] [--model <model>] [--max-turns <n>] [--effort <level>] [focus] [--json]",
" claude-companion monitor [job-id] [--interval-ms <ms>] [--max-checks <n>] [--stale-after-ms <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"
);
}
Expand Down
54 changes: 41 additions & 13 deletions plugins/claude-code-advisor/skills/claude/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,18 +21,23 @@ Canonical forms:

```text
$claude setup
$claude advise [--max-turns <n>] <question>
$claude do [--background] [--write] [--model sonnet|opus] [--max-turns <n>] <prepared task>
$claude rescue [--background] [--write] [--resume] [--model sonnet|opus] [--max-turns <n>] <task>
$claude review [--base <ref>]
$claude adversarial-review [--base <ref>] [focus]
$claude advise [--background] [--model <model>] [--max-turns <n>] <question>
$claude do [--background] [--write] [--model <model>] [--max-turns <n>] <prepared task>
$claude rescue [--background] [--write] [--resume] [--model <model>] [--max-turns <n>] <task>
$claude review [--base <ref>] [--model <model>]
$claude adversarial-review [--base <ref>] [--model <model>] [focus]
$claude monitor [job-id]
$claude status [job-id]
$claude result [job-id]
$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:

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -125,6 +134,7 @@ For long-running work, prefer:

```bash
node "<plugin root>/scripts/claude-companion.mjs" advise --background "<question>"
node "<plugin root>/scripts/claude-companion.mjs" advise --background --model fable "<question>"
node "<plugin root>/scripts/claude-companion.mjs" do --background --model sonnet "<prepared task>"
node "<plugin root>/scripts/claude-companion.mjs" do --background --model opus "<prepared task>"
node "<plugin root>/scripts/claude-companion.mjs" rescue --background --model opus "<task>"
Expand Down Expand Up @@ -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 <question>
$claude do --background --model fable <prepared task>
```

```bash
node "<plugin root>/scripts/claude-companion.mjs" advise --background --model fable --effort xhigh "<question>"
node "<plugin root>/scripts/claude-companion.mjs" do --background --model fable --effort xhigh "<prepared task>"
```

## Prepared Opus Tasks

Use `$claude do --model opus` when the user asks Claude to do a complex task
Expand Down Expand Up @@ -243,6 +270,7 @@ Examples:
node "<plugin root>/scripts/claude-companion.mjs" setup --json
node "<plugin root>/scripts/claude-companion.mjs" adversarial-review --base main --json
node "<plugin root>/scripts/claude-companion.mjs" advise --background --effort xhigh "<question>"
node "<plugin root>/scripts/claude-companion.mjs" advise --background --model fable --effort xhigh "<question>"
node "<plugin root>/scripts/claude-companion.mjs" do --background --model sonnet --effort xhigh "<prepared task>"
node "<plugin root>/scripts/claude-companion.mjs" do --background --model opus --effort xhigh "<prepared task>"
node "<plugin root>/scripts/claude-companion.mjs" monitor <job-id> --interval-ms 30000 --stale-after-ms 120000
Expand Down
1 change: 1 addition & 0 deletions tests/commands.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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…");
Expand Down
22 changes: 22 additions & 0 deletions tests/runtime.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 3 additions & 1 deletion tests/validate-plugin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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/);
Expand All @@ -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/);
Expand Down