Skip to content
Development
Command

/v-models

Refresh the Compound V tier→model map — discover the concrete models each backend (claude, codex, antigravity, cursor, opencode) currently offers, show them, let you assign frontier/deep/standard/light, and write the result into .claude/compound-v.json so intent-based routing

From plugin
superpowers-v
3615 skills7 agents15 commands7 hooks
Install
> /plugin marketplace add procoders/superpowers-v
> /plugin install superpowers-v@procoders

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/v-models

Context preview

What this command does when you run it.

Refresh the Compound V tier→model map — discover the concrete models each backend (claude, codex, antigravity, cursor, opencode) currently offers, show them, let you assign frontier/deep/standard/light, and write the result into .claude/compound-v.json so intent-based routing

Command definition

v-models.md
description: Refresh the Compound V tier→model map — discover the concrete models each backend (claude, codex, antigravity, cursor, opencode) currently offers, show them, let you assign frontier/deep/standard/light, and write the result into .claude/compound-v.json so intent-based routing survives model churn without touching any call site.
disable-model-invocation: true

You are running **`/v:models`** — the Compound V model broker's **refresh surface**. Compound V routes work by **intent** (a stable `tier` vocabulary — `frontier` / `deep` / `standard` / `light`) instead of hardcoding model strings that rot every time a provider ships a new model. The mapping from tier → concrete model lives in a **refreshable** `models` block in `.claude/compound-v.json`. This command discovers what each backend can run **right now**, lets you assign each tier, and rewrites that block. Nothing else in the plugin changes — the dispatcher resolves tiers through [`scripts/compound-v-resolve-model.py`](../scripts/compound-v-resolve-model.py) at dispatch time, so refreshing the map here is the *only* thing you ever touch when models churn.

Argument (optional): `{{args}}` may name a single backend to refresh in isolation (`claude` | `codex` | `antigravity` | `cursor` | `opencode`); otherwise walk all of them. `opencode` is a **worker-only** backend (v1) — its model map drives dispatch only, never any arbiter/review panel seat.

**This is the "skill picks the models and offers you the options" surface.** Do the discovery, *show* what you found, then let the user choose. Never silently pick a model the user did not confirm. **NEVER assign `haiku` to any tier on any backend.**

**Resolving the plugin root.** The `scripts/` this command calls ship with the plugin — they are not files in your own repository. Resolve the plugin root once per session before calling any of them:

CV="${CLAUDE_PLUGIN_ROOT:-$(ls -d "$HOME"/.claude/plugins/cache/*/superpowers-v/*/ 2>/dev/null | sort -V | tail -1)}"
CV="${CV:-$PWD}"; CV="${CV%/}"

`CLAUDE_PLUGIN_ROOT` is set for hooks but is not set in this Bash environment, so treat it as a hint, never the whole answer — the fallback line covers an installed plugin cache or a checkout of this repo.

---

Step 0 — Load the current map

Read `.claude/compound-v.json` if it exists. Remember its current `models` block (seeded by [`/v:init`](v-init.md)) so you can show the user what is changing and preserve any backend they don't refresh this run. The `models` block is **per-stance** — shape `{<stance>: {<backend>: {<tier>: model}}}`. If the file or its `models` key is absent, fall back to the built-in default (the resolver carries the same one). Only the `claude` rows differ across stances — `conservative.claude.standard` is `opus`, everywhere else `standard` Claude is `sonnet`; and `cost-aware.claude.frontier` caps at `opus` instead of reaching `fable`:

"models": {
  "balanced": {
    "claude":      { "frontier": "fable", "deep": "opus",  "standard": "sonnet",                "light": "sonnet" },
    "codex":       { "frontier": "gpt-5.6-sol", "deep": "gpt-5.6-sol", "standard": "gpt-5.6-terra", "light": "gpt-5.6-luna" },
    "antigravity": { "deep": "Gemini 3.1 Pro (High)", "standard": "Gemini 3.1 Pro (Low)", "light": "Gemini 3.8 Flash (Low)" },
    "cursor":      { "deep": "auto",                  "standard": "auto",                  "light": "auto" }
  },
  "cost-aware": {
    "claude":      { "frontier": "opus",  "deep": "opus",  "standard": "sonnet",                "light": "sonnet" },
    "codex":       { "frontier": "gpt-5.6-sol", "deep": "gpt-5.6-sol", "standard": "gpt-5.6-terra", "light": "gpt-5.6-luna" },
    "antigravity": { "deep": "Gemini 3.1 Pro (High)", "standard": "Gemini 3.1 Pro (Low)", "light": "Gemini 3.8 Flash (Low)" },
    "cursor":      { "deep": "auto",                  "standard": "auto",                  "light": "auto" }
  }
  // claude-only mirrors balanced; conservative keeps standard on opus
}

`/v:models` writes this **per-stance** shape; the resolver still accepts the **legacy flat shape** `{<backend>: {<tier>: model}}` (applied to every stance) for backward-compat. If `{{args}}` named one backend, only discover + reassign that backend (across every stance's block) and leave the other backends exactly as they are.

---

Step 1 — Discover available models per backend

Each backend exposes its catalog differently. Discover, don't guess — and report honestly what discovery actually returned.

1a. claude — native tier aliases (no discovery call)

Claude resolves a tier to one of its **native model aliases**. The shipped tiers are:

  • `deep` → `opus` (strongest reasoning)
  • `standard` → `opus`
  • `light` → `sonnet`

There is no list command to run; the alias set is `opus` / `sonnet`. **Never `haiku`.** Offer `opus` and `sonnet` as the only choices per tier.

1b. codex — curated list (no list command exists)

Codex has **no `models` list command**. Maintain a small **curated** roster and let the user override any entry by hand (a model the curated list doesn't know about is still valid — codex accepts whatever model string you pass to `codex exec --model`). Present this curated starting roster:

  • `gpt-5.6-sol` — strongest; suggested for `deep` (requires codex-cli >= 0.143.0)
  • `gpt-5.6-terra` — balanced; suggested for `standard`
  • `gpt-5.6-luna` — fast/cheap; suggested for `light`

Confirm codex is even usable first (so you don't write a map the project can't run):

command -v codex && codex exec --help 2>/dev/null | grep -q -- '--model' && echo "codex usable" || echo "codex unavailable"

If codex is unavailable, say so, keep the existing codex block unchanged, and skip its reassignment (the map can still carry codex entries for when it returns).

1c. antigravity — headless `agy models` discovery (real names)

Antigravity (Gemini family) **does** have a discovery command, and it runs **headlessly** — `

Read more
Ships withsuperpowers-v

Compound V — a multi-model coding sidekick for Superpowers, running on Claude Code. You describe a feature. Claude sizes the request, plans it, splits it into non-overlapping pieces, and hands each piece to a worker in its own isolated worktree.

Get the whole plugin

Other commands on superpowers-v.