One command to bootstrap AI coding agent config on a new machine or repo.
.\init.ps1 # defaults to claude-code
.\init.ps1 -Provider claude-code
.\init.ps1 -Provider copilot
.\init.ps1 -Provider codex-routerIdempotent: safe to re-run. Never overwrites a file or settings key that already exists with a different value — it reports what it skipped and why instead.
The Codex router gives Claude Code one execution party: Codex CLI. Claude makes
product decisions, delegates edits/search/tests/debugging through codex-task,
and performs one gated digest review before a push. There are no alternate model
providers or quota fallbacks; when Codex is unavailable, a short-lived marker
re-opens direct Claude work and [claude-fallback] subagents.
Quick start:
- Run
.\init.ps1 -Provider codex-router. - Run
codex loginif the doctor reports that authentication is missing. - Open a new Claude Code session so the installed hooks and instructions load.
Delegate a task with a bounded prompt file:
~/.claude/codex-router/codex-task.ps1 -Mode execute -Type feature -Tier auto -Repo . -PromptFile .\task.txt-Tier auto selects a Codex model and reasoning effort by task type; -Escalate
moves one tier higher. investigate and review use a read-only sandbox, while
execute uses workspace-write. Codex is never launched with unrestricted or
danger-full-access permissions and never owns commit/push/reset/clean/deploy.
Before push or PR creation, the hook requests a neutral
codex-task -Mode review -Tier deep, followed by Claude's review of
pr-review-digest.ps1 and its flagged hunks. Claude owns the final go/no-go.
Uninstall only recorded installer-owned files and hook entries:
.\init.ps1 -Provider codex-router -UninstallThe tier-to-model mapping lives in ~/.claude/codex-router/model-catalog.json. The
installed defaults are:
| Tier | Model | Effort |
|---|---|---|
| fast | gpt-reserve | low |
| std | gpt-5.6-sol | medium |
| deep | gpt-5.6-sol | high |
| max | gpt-6-astra | high |
These defaults reflect the author's Codex catalog; your catalog may differ. Edit
the JSON to use models available in your account. To list available Codex models,
run codex models (or check the Codex CLI documentation for the current command).
Missing tiers fall back to the defaults above.
- Windows
- PowerShell 7 (
pwsh) or Windows PowerShell 5.1 (powershell). Both hosts pass the router test suite.
Troubleshooting:
- Hooks require PowerShell 7 (
pwsh). The doctor prints an exact install hint. - RTK is optional. If it exists in the Codex runtime cache but is not resolvable,
re-run with
-FixRtk; otherwise install Rust Token Killer and re-run. - Install Codex CLI with
npm i -g @openai/codex, then authenticate withcodex login. The installer never reads or writes credentials. - Claude desktop's model selector and claude.ai connectors must be changed in the app UI; this repository does not configure either surface.
- RTK hook wiring in
~/.claude/settings.json(only ifrtkis on PATH — this script never installs binaries silently). RTK compresses verbose shell output (git, docker, terraform, kubectl...) before it enters context. Validated on real repos: 57–83% saved ongit diff/git log. Does not coveraz— az output goes in raw, no hook rewrites it today. - Graphify, registered as a user-scope MCP server so the agent queries the
graph on its own — no
/graphifyto type. Graphify parses the repo locally with tree-sitter into a queryable knowledge graph, so the agent navigates the graph instead of re-reading files. Complementary to RTK, not overlapping: RTK compresses command output, Graphify compresses codebase exploration. Payoff scales with repo size — on a few dozen files it buys close to nothing, the vendor's headline numbers are measured on 500+ file codebases. Only wired ifgraphifyis on PATH — same policy as RTK, the script never installs the Python package for you:The script also runsuv tool install "graphifyy[mcp]"graphify install(skill file +~/.claude/CLAUDE.mdpointer) so/graphify .still works for building the graph in the first place. See the MCP wiring notes below — three details there are not what the upstream docs suggest. model: opusplandefault (Opus plans, Sonnet executes) — the model-routing part of the setup; applies to the main thread, not just subagents.permissions.defaultMode: auto(auto-proceed on safe/local actions, gate on anything touching prod/cloud/shared state — this is the built-in Claude Code auto-mode classifier, not a custom rule). Confirmed: destructive commands (terraform destroy,az group delete, etc.) stay gated regardless of which subagent invokes them — the classifier evaluates the command, not the caller.- Three subagents in
~/.claude/agents/:dev(Sonnet) — writes/edits codesearcher(Haiku, read-only) — locates code, no Bash/Edit/Writerunner(Haiku, Bash-only) — runs tests/verification commands
ponytail@ponytailplugin (anti-overengineering ladder: reuse before writing, stdlib before dependency, shortest diff that works) registered and installed, forced to ultra intensity.caveman@cavemanplugin (ultra-compressed responses) forced to ultra intensity, same mechanism as ponytail below.
Generic on purpose — no project- or company-specific rules baked in. Add those
to your own project's CLAUDE.md, not here.
Both plugins resolve their default intensity in this order: PONYTAIL_DEFAULT_MODE /
CAVEMAN_DEFAULT_MODE env var → config.json → hardcoded default (full).
The config file lives at %APPDATA%\<tool>\config.json on Windows —
~/.config/<tool>/ is a Mac/Linux-only fallback. An earlier version of this
script wrote to ~/.config/, so on Windows neither plugin ever saw the
override and silently stayed at full despite the file existing. Confirmed
via a fresh session showing the literal startup reminder text (level: ultra
vs level: full) before and after the fix — not assumed from the config
file alone. The script now sets both the user env var (highest priority,
survives even if the path logic is wrong again) and the config file at the
correct path, idempotently, and warns instead of overwriting if you've set a
different mode yourself.
Read off the upstream source (graphify/__main__.py, graphify/serve.py,
pyproject.toml at v0.1.14), not off the README:
- There is no
graphify --mcpcommand. The CLI'smain()dispatches onlyinstall,vscode,claude,hookandbenchmark; anything else printsunknown commandand exits 1. The--mcpyou see in the docs is a flag the skill passes, not a CLI verb. The stdio server isgraphify/serve.py, so the real command is<python> -m graphify.serve. mcpis an optional extra, not a dependency —pip install graphifyygives you a server that raisesImportErrorthe moment it starts. You needgraphifyy[mcp]. The script checksimport mcpseparately and warns with the exact fix rather than registering a server that can't boot.- Which python matters.
uv tool installisolates the package in its own venv, sopython -m graphify.serveagainst the interpreter on PATH fails to import. The script probes candidates (uv tool venv → the dir next to thegraphifyshim → PATH python) and keeps the first that can actuallyimport graphify.serve, then registers that absolute path.
One consequence worth knowing before you turn this on: serve() loads
graphify-out/graph.json as a relative path and sys.exit(1)s if it's
missing. The server inherits the session's working directory, so it resolves
per-repo — which is what makes a single user-scope registration workable — but
it also means the server shows up as failed in every repo where you have not
run /graphify . at least once. That's noise, not breakage.
Registration goes through claude mcp add --scope user, deliberately not by
editing ~/.claude.json directly: that file holds your oauth account and the
full per-project history, and a PowerShell 5.1 ConvertFrom-Json →
ConvertTo-Json -Depth 10 round-trip would quietly flatten the deep structures
it doesn't fit. If the claude CLI isn't on PATH the script prints the exact
command instead of touching the file.
Scope is smaller on purpose: Copilot Chat's instructions file
(.github/copilot-instructions.md) is per-repo, not global like ~/.claude,
so this provider doesn't write into any project on your behalf.
- Checks the GitHub Copilot Chat extension is installed (reports, never auto-downloads on a corporate machine; sign-in can't be automated either)
- Sets the global VS Code setting
github.copilot.chat.codeGeneration.useInstructionFiles: true, so Copilot picks up a repo's instructions file when present - Ships
providers/copilot/copilot-instructions.mdas a template — copy it to<project>\.github\copilot-instructions.mdin whichever repos you want it active
Config files being correct isn't the same as behavior being correct — see the path bug above. Env vars and some hook-driven state (model, permission mode) are only read at process start, so anything changed by this script won't be live in the session you ran it from. To verify for real:
- Open a new Claude Code session (new window/terminal, not the one that ran the script).
- Check the SessionStart reminders verbatim: ponytail and caveman both print
their active level on boot (
... MODE ACTIVE — level: X) — confirm it saysultra, notfull. - Run a verbose command from your real stack (
git diff,git log --stat) in a real repo, then runrtk gainand confirm that specific command shows up with a nonzero saved percentage — don't trust the aggregate number alone, it can be dominated by unrelated commands. claude plugin listshould show bothponytail@ponytailandcaveman@cavemanas enabled.- For Graphify, in a repo where you've run
/graphify .once:claude mcp listmust showgraphifyas connected, and the session must expose its tools (query_graph,god_nodes,graph_stats...). A server that registers but never connects saves nothing. Then ask an architecture question and confirm the agent hits those tools instead of reading files — that's the whole point, and it's the only thing that proves the tokens are actually going down.
Create providers/<name>/install.ps1 following the same shape as
providers/claude-code/install.ps1: check what's already there before writing,
merge instead of overwrite, print [add]/[ok]/[warn] per change. Add the
name to the -Provider ValidateSet in init.ps1.