Skip to content
Open
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
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,20 @@ Quick routing rule:
Standard read-only review of your current work.

```text
$cc:review # review uncommitted changes (default: opus + xhigh effort)
$cc:review # review uncommitted changes (default: opus + high effort)
$cc:review --base main # review branch vs main
$cc:review --scope branch # explicitly compare branch tip to base
$cc:review --background # run in background, check with $cc:status later
$cc:review --model sonnet # switch to sonnet (defaults to high effort)
$cc:review --model opus --effort high # opus with a lighter effort
$cc:review --model fable # use Fable (defaults to high effort)
$cc:review --model opus --effort xhigh # explicitly raise opus effort
```

**Flags:** `--base <ref>`, `--scope <auto|working-tree|branch>`, `--wait`, `--background`, `--model <model>`, `--effort <low|medium|high|max>`
**Flags:** `--base <ref>`, `--scope <auto|working-tree|branch>`, `--wait`, `--background`, `--model <model>`, `--effort <low|medium|high|xhigh|max>`

**Defaults:** model `opus` (resolves to `claude-opus-4-7[1m]`, the 1M-context variant) with `xhigh` effort. If you pick `sonnet`, it resolves to `claude-sonnet-4-6[1m]` (also 1M context) and the default effort drops to `high`. `haiku` resolves to `claude-haiku-4-5` and has no effort setting. Pass `--model` and `--effort` to override.
**Defaults:** model `opus` with `high` effort. After trimming surrounding whitespace, the friendly aliases `fable`, `opus`, `sonnet`, and `haiku` are matched case-insensitively and canonicalized to lowercase; every friendly alias defaults to `high` effort. Every other `--model` value passes through unchanged for Claude Code to resolve, including full model IDs and provider-specific names, and receives no inferred effort. Pass `--model` and `--effort` to override.

**Model discovery:** run `/model` in Claude Code to see the models and effort levels available to your current account and provider, then pass the selected alias or full ID to this plugin. The plugin intentionally does not maintain a static model catalog or force `[1m]`; Claude Code owns alias versions, managed restrictions, provider routing, and extended-context eligibility.

Scope `auto` (the default) inspects `git status` and chooses between working-tree and branch automatically.

Expand Down Expand Up @@ -171,8 +174,8 @@ $cc:rescue --model sonnet --effort medium investigate the flaky test
| `--resume-last` | Alias for `--resume` |
| `--fresh` | Force a new task (don't resume) |
| `--write` | Allow file edits (default) |
| `--model <model>` | Claude model (`opus`, `sonnet`, `haiku`, or full ID; defaults to `opus`. The `opus` and `sonnet` aliases resolve to their 1M-context variants `claude-opus-4-7[1m]` and `claude-sonnet-4-6[1m]`.) |
| `--effort <level>` | Reasoning effort: `low`, `medium`, `high`, `xhigh`, `max` (default: `xhigh` for opus, `high` for sonnet, unset for haiku) |
| `--model <model>` | Any Claude Code model alias, full model ID, or provider-specific name; defaults to `opus`. Run `/model` in Claude Code to discover options available to your account and provider. |
| `--effort <level>` | Reasoning effort: `low`, `medium`, `high`, `xhigh`, `max` (default: `high` for every friendly model alias) |
| `--prompt-file <path>` | Read task description from a file |

**Resume behavior:** If you don't pass `--resume` or `--fresh`, rescue checks for a resumable Claude session and asks once whether to continue or start fresh. Your phrasing guides the recommendation — "continue the last run" → resume, "start over" → fresh.
Expand Down Expand Up @@ -278,7 +281,7 @@ The review gate is an **optional turn-end hook**. When enabled, Codex runs a Cla
| **Runtime** | Codex app-server + broker | Fresh `claude -p` subprocess per invocation |
| **Review gate trigger** | End of Claude Code turn | End of Codex turn |
| **Review gate target** | Reviews previous Claude response | Reviews previous Codex response |
| **Model flags** | Codex model names and effort controls | Claude model names and effort values (`low` / `medium` / `high` / `max`) |
| **Model flags** | Codex model names and effort controls | Claude model names and effort values (`low` / `medium` / `high` / `xhigh` / `max`) |

### Where This Goes Further

Expand Down
3 changes: 2 additions & 1 deletion internal-skills/cli-runtime/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Command selection:

Routing controls:
- Treat `--model`, `--effort`, `--resume`, `--resume-last`, `--fresh`, `--prompt-file`, `--view-state`, `--owner-session-id`, and `--job-id` as routing controls, not task text.
- Leave `--model` and `--effort` unset unless the user explicitly asks for a specific model or effort. The companion command applies these defaults itself: model defaults to `opus`, effort defaults to `xhigh` for opus, `high` for sonnet, and is left unset for haiku.
- Leave `--model` and `--effort` unset unless the user explicitly asks for a specific model or effort. The companion command applies these defaults itself: model defaults to `opus`; fable, opus, sonnet, and haiku each default to `high` effort.
- Forward an explicit `--model` value unchanged to the companion. The companion trims surrounding whitespace, canonicalizes the friendly aliases `fable`, `opus`, `sonnet`, and `haiku` to lowercase, then forwards every other `--model` value unchanged to Claude Code. Claude Code owns alias resolution; `/model` is the authoritative picker for the current account and provider.
- `--view-state on-success` means the user will see this companion result in the current turn, so the companion may mark it viewed on success.
- `--view-state defer` means the parent is not waiting, so the companion must leave the result unread until the user explicitly checks it.
- `--owner-session-id <session-id>` is an internal parent-session routing control. Preserve it when present so tracked jobs remain visible to the parent session's `$cc:status` / `$cc:result`.
Expand Down
27 changes: 8 additions & 19 deletions scripts/claude-companion.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
*
* Adapted from codex-companion.mjs:
* - Uses claude-cli.mjs instead of app-server/broker
* - MODEL_ALIASES: opus -> claude-opus-4-7[1m], sonnet -> claude-sonnet-4-6[1m], haiku -> claude-haiku-4-5
* - Friendly model aliases canonicalize to lowercase; other names pass through
* - Default model when --model is unset: opus
* - Default effort by model: opus -> xhigh, sonnet -> high, haiku -> unset
* - Default effort for friendly model aliases: high
* - Claude CLI effort values: low, medium, high, xhigh, max
* - Legacy effort aliases: none|minimal -> low
* - Review gate matches upstream setup semantics: Stop hook runs when enabled
Expand Down Expand Up @@ -42,7 +42,7 @@ import {
runClaudeReview,
runClaudeAdversarialReview,
cancelClaudeProcess,
MODEL_ALIASES,
resolveModel,
resolveEffort,
resolveDefaultModel,
resolveDefaultEffort,
Expand Down Expand Up @@ -137,9 +137,9 @@ function printUsage() {
[
"Usage:",
" node scripts/claude-companion.mjs setup [--enable-review-gate|--disable-review-gate] [--json]",
" node scripts/claude-companion.mjs review [--wait|--background] [--base <ref>] [--scope <auto|working-tree|branch>] [--model <model|opus|sonnet|haiku>] [--effort <low|medium|high|xhigh|max>]",
" node scripts/claude-companion.mjs adversarial-review [--wait|--background] [--base <ref>] [--scope <auto|working-tree|branch>] [--model <model|opus|sonnet|haiku>] [--effort <low|medium|high|xhigh|max>] [focus text]",
" node scripts/claude-companion.mjs task [--background] [--write] [--resume-last|--resume|--fresh] [--model <model|opus|sonnet|haiku>] [--effort <low|medium|high|xhigh|max>] [prompt]",
" node scripts/claude-companion.mjs review [--wait|--background] [--base <ref>] [--scope <auto|working-tree|branch>] [--model <model>] [--effort <low|medium|high|xhigh|max>]",
" node scripts/claude-companion.mjs adversarial-review [--wait|--background] [--base <ref>] [--scope <auto|working-tree|branch>] [--model <model>] [--effort <low|medium|high|xhigh|max>] [focus text]",
" node scripts/claude-companion.mjs task [--background] [--write] [--resume-last|--resume|--fresh] [--model <model>] [--effort <low|medium|high|xhigh|max>] [prompt]",
" node scripts/claude-companion.mjs status [job-id] [--all] [--json]",
" node scripts/claude-companion.mjs result [job-id] [--json]",
" node scripts/claude-companion.mjs cancel [job-id] [--json]",
Expand Down Expand Up @@ -179,17 +179,6 @@ function redactOutputReplacer(key, value) {
// Normalization
// ---------------------------------------------------------------------------

function normalizeRequestedModel(model) {
if (model == null) {
return null;
}
const normalized = String(model).trim();
if (!normalized) {
return null;
}
return MODEL_ALIASES.get(normalized.toLowerCase()) ?? normalized;
}

function resolveReservedJobFile(workspaceRoot, jobId) {
const safeJobId = sanitizeId(jobId, "job ID");
return path.join(resolveJobsDir(workspaceRoot), `${safeJobId}${JOB_RESERVATION_SUFFIX}`);
Expand Down Expand Up @@ -1521,7 +1510,7 @@ async function handleReviewCommand(argv, config) {
Boolean(options.background)
);

const requestedModel = normalizeRequestedModel(options.model);
const requestedModel = resolveModel(options.model);
const resolvedModel = resolveDefaultModel(requestedModel);
const resolvedEffort = resolveDefaultEffort(resolvedModel, options.effort);

Expand Down Expand Up @@ -1622,7 +1611,7 @@ async function handleTask(argv) {
const cwd = resolveCommandCwd(options);
const workspaceRoot = resolveCommandWorkspace(options);

const requestedModel = normalizeRequestedModel(options.model);
const requestedModel = resolveModel(options.model);
const model = resolveDefaultModel(requestedModel);
const resolvedEffort = resolveDefaultEffort(model, options.effort);
const effort = resolvedEffort ? resolveEffort(resolvedEffort) : null;
Expand Down
25 changes: 11 additions & 14 deletions scripts/lib/claude-cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -634,15 +634,9 @@ export function pruneStaleReviewMcpConfigs(options = {}) {
}

// ---------------------------------------------------------------------------
// Model & Effort Mapping
// Model & Effort Selection
// ---------------------------------------------------------------------------

export const MODEL_ALIASES = new Map([
["opus", "claude-opus-4-7[1m]"],
["sonnet", "claude-sonnet-4-6[1m]"],
["haiku", "claude-haiku-4-5"],
]);

export const EFFORT_ALIASES = {
none: "low",
minimal: "low",
Expand All @@ -652,13 +646,13 @@ export const VALID_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);

export const DEFAULT_MODEL = "opus";

const FRIENDLY_ALIASES = new Set(["fable", "opus", "sonnet", "haiku"]);

export const DEFAULT_EFFORT_BY_MODEL = new Map([
["opus", "xhigh"],
["claude-opus-4-7", "xhigh"],
["claude-opus-4-7[1m]", "xhigh"],
["fable", "high"],
["opus", "high"],
["sonnet", "high"],
["claude-sonnet-4-6", "high"],
["claude-sonnet-4-6[1m]", "high"],
["haiku", "high"],
]);

export function resolveDefaultModel(model) {
Expand All @@ -677,8 +671,11 @@ export function resolveDefaultEffort(model, effort) {
}

export function resolveModel(model) {
if (!model) return undefined;
return MODEL_ALIASES.get(model) ?? model;
if (model == null) return undefined;
const normalized = String(model).trim();
if (!normalized) return undefined;
const canonical = normalized.toLowerCase();
return FRIENDLY_ALIASES.has(canonical) ? canonical : normalized;
}

export function resolveEffort(effort) {
Expand Down
6 changes: 4 additions & 2 deletions skills/adversarial-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: adversarial-review
description: 'Run a design-challenging Claude Code review of local git changes in this repository. Args: --wait, --background, --base <ref>, --scope <auto|working-tree|branch>, --model <model>, --effort <low|medium|high|xhigh|max>, [focus text]. Defaults to opus + xhigh effort. Use only when the user wants stronger scrutiny than a normal review, such as explicit tradeoff challenge, risky-change review, or custom focus text.'
description: 'Run a design-challenging Claude Code review of local git changes in this repository. Args: --wait, --background, --base <ref>, --scope <auto|working-tree|branch>, --model <model>, --effort <low|medium|high|xhigh|max>, [focus text]. Defaults to opus + high effort. Use only when the user wants stronger scrutiny than a normal review, such as explicit tradeoff challenge, risky-change review, or custom focus text.'
---

# Claude Code Adversarial Review
Expand All @@ -16,7 +16,9 @@ Unlike `$cc:review`, this skill accepts custom focus text after the flags. The m
Resolve `<plugin-root>` as two directories above this `SKILL.md` file. Always run the companion from that active plugin root:
`node "<plugin-root>/scripts/claude-companion.mjs" adversarial-review ...`

Supported arguments: `--wait`, `--background`, `--base <ref>`, `--scope auto|working-tree|branch`, `--model <model>`, `--effort <low|medium|high|xhigh|max>`, plus optional focus text after the flags (defaults: model=opus, effort=xhigh; sonnet defaults to high; haiku has no effort)
Supported arguments: `--wait`, `--background`, `--base <ref>`, `--scope auto|working-tree|branch`, `--model <model>`, `--effort <low|medium|high|xhigh|max>`, plus optional focus text after the flags (defaults: model=opus; fable, opus, sonnet, and haiku each default to high effort)

Forward `--model` unchanged to the companion. The companion trims surrounding whitespace, canonicalizes the friendly aliases `fable`, `opus`, `sonnet`, and `haiku` to lowercase, then forwards every other `--model` value unchanged to Claude Code. Claude Code owns alias resolution; `/model` is the authoritative picker for the current account and provider.

Raw slash-command arguments:
`$ARGUMENTS`
Expand Down
6 changes: 5 additions & 1 deletion skills/rescue/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: rescue
description: 'Delegate a substantial diagnosis, implementation, or follow-up task to Claude Code through the tracked-job runtime. Args: --background, --wait, --resume, --resume-last, --fresh, --write, --model <model>, --effort <low|medium|high|xhigh|max>, --prompt-file <path>, [task text]. Defaults to opus + xhigh effort. Use when Claude should investigate or change things, not when the user only wants review findings.'
description: 'Delegate a substantial diagnosis, implementation, or follow-up task to Claude Code through the tracked-job runtime. Args: --background, --wait, --resume, --resume-last, --fresh, --write, --model <model>, --effort <low|medium|high|xhigh|max>, --prompt-file <path>, [task text]. Defaults to opus + high effort. Use when Claude should investigate or change things, not when the user only wants review findings.'
---

# Claude Code Rescue
Expand All @@ -24,6 +24,10 @@ Raw slash-command arguments:

Supported arguments: `--background`, `--wait`, `--resume`, `--resume-last`, `--fresh`, `--write`, `--model <model>`, `--effort <low|medium|high|xhigh|max>`, `--prompt-file <path>`, plus free-text task text

Companion defaults: model=opus; fable, opus, sonnet, and haiku each default to high effort.

Forward `--model` unchanged to the companion. The companion trims surrounding whitespace, canonicalizes the friendly aliases `fable`, `opus`, `sonnet`, and `haiku` to lowercase, then forwards every other `--model` value unchanged to Claude Code. Claude Code owns alias resolution; `/model` is the authoritative picker for the current account and provider.

Main-thread routing rules:
- If the user explicitly invoked `$cc:rescue` or `Claude Code Rescue`, do not keep the work in the main Codex thread. Delegate it.
- If the user did not supply a task, ask what Claude Code should investigate or fix.
Expand Down
6 changes: 4 additions & 2 deletions skills/review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: review
description: 'Run a standard Claude Code review of local git changes in this repository. Args: --wait, --background, --base <ref>, --scope <auto|working-tree|branch>, --model <model>, --effort <low|medium|high|xhigh|max>. Defaults to opus + xhigh effort. Use as the default path for ordinary code-review requests when the user did not explicitly ask for stronger adversarial scrutiny or for Claude to own the implementation work.'
description: 'Run a standard Claude Code review of local git changes in this repository. Args: --wait, --background, --base <ref>, --scope <auto|working-tree|branch>, --model <model>, --effort <low|medium|high|xhigh|max>. Defaults to opus + high effort. Use as the default path for ordinary code-review requests when the user did not explicitly ask for stronger adversarial scrutiny or for Claude to own the implementation work.'
---

# Claude Code Review
Expand All @@ -16,7 +16,9 @@ If the overall request is "you review it too, also ask Claude to review in the b
Resolve `<plugin-root>` as two directories above this `SKILL.md` file. Always run the companion from that active plugin root:
`node "<plugin-root>/scripts/claude-companion.mjs" review ...`

Supported arguments: `--wait`, `--background`, `--base <ref>`, `--scope auto|working-tree|branch`, `--model <model>`, `--effort <low|medium|high|xhigh|max>` (defaults: model=opus, effort=xhigh; sonnet defaults to high; haiku has no effort)
Supported arguments: `--wait`, `--background`, `--base <ref>`, `--scope auto|working-tree|branch`, `--model <model>`, `--effort <low|medium|high|xhigh|max>` (defaults: model=opus; fable, opus, sonnet, and haiku each default to high effort)

Forward `--model` unchanged to the companion. The companion trims surrounding whitespace, canonicalizes the friendly aliases `fable`, `opus`, `sonnet`, and `haiku` to lowercase, then forwards every other `--model` value unchanged to Claude Code. Claude Code owns alias resolution; `/model` is the authoritative picker for the current account and provider.

Raw slash-command arguments:
`$ARGUMENTS`
Expand Down
Loading