Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/edotau/claude-code itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 22, 2026claude-code
A minimal harness for Claude Code. This repo is ~/.claude:
one Go binary, claude-code, plus the agents, commands, rules, skills and Workflow scripts every session loads.
What it adds to a stock install:
- Provider registry — Anthropic, Claude/ChatGPT/Copilot subscriptions, OpenAI, Gemini, Nvidia, Ollama or any gateway; tier slots (opus/sonnet/haiku/fable) map to model ids per provider.
- Loopback router — OpenAI-dialect translation, per-tier provider mixing, failover on 429/5xx.
- Agent runners — one-shot tasks on Claude, Codex, Gemini, OpenCode or Copilot (
ask), interactive CLIs (run). - Hooks, memory, status line — a Bash safety gate, a per-repo memory bank, format-on-stop, context checkpoint.
Every verb takes --help; claude-code describe maps the whole harness.
Install
git clone https://github.com/edotau/claude-code ~/.claude
cd ~/.claude
make install # build, link vendor CLIs into bin/, render settings.json, add linters (DEV_TOOLS=0 skips)
claude-code doctor # check binaries, providers, credentials, router
make bootstrap— fresh box: Go toolchain (no sudo), install, bash completion, thenclaude-code configure(CHECK=1runsconfigure --checkinstead;TAILSCALE=1adds tailscale).claude-code install --dry-runpreviews; foreign hooks insettings.jsonare kept, with a timestamped backup.- A missing vendor CLI is reported, never downloaded;
install --tools=<name>installs it. bin/<vendor>is the real, unrouted CLI. Routed launches go throughclaude-code <vendor>.
claude-code opus # Claude Code with opus as the main model (also sonnet | haiku | fable)
claude-code codex # a vendor CLI through the registry (also gemini | opencode | copilot)
claude-code ollama # Claude Code on that registered provider
claude-code --resume # a leading flag passes to claude, on the session provider
Setup
claude-code configure # interactive menu: providers, logins/keys, models, agents; Submit seals keys
claude-code configure models # one section (provider|models|agents|router|github|remote|browser|claude|doctor)
claude-code configure claude # per-machine settings overrides; team defaults stay in the template
claude-code configure --check # report only; exit 1 if anything is unset
claude-code configure --reset [--out f|--check|--dry-run] # render settings + vendor configs
claude-code configure --restore [--agent a,b] # restore vendor configs from backup
claude-code theme vscode [--check|--dry-run] # merge VS Code settings + keybindings
configurereuses what already exists (env, vault, vendor logins) and prompts only for what is missing.- Claude subscription keeps Remote Control; API key pays per token. For headless runs on a Max plan,
configuremintsclaude setup-tokeninto the vault asCLAUDE_CODE_OAUTH_TOKEN. - Vendor configs are merged, never replaced:
~/.codex/config.toml,~/.gemini/antigravity-cli/settings.json, Codex/Copilot hooks. Keys are referenced by env var, exported only by a routed launch. opencode's own~/.config/opencode/is never written (its model/MCP/theme come from a tracked overlay,OPENCODE_CONFIG/OPENCODE_TUI_CONFIG, injected at launch —internal/vendors/template/). - On a terminal,
configure --resetprompts before overwriting hand-edited lines it would otherwise lose; a non-interactive run (launch,configure,make install) writes and warns instead. Each overwrite keeps 5 timestamped backups;configure --restoresteps a vendor file back one version at a time. - From a worktree, render only that checkout:
CLAUDE_CONFIG_DIR="$PWD" claude-code configure --reset --out "$PWD/settings.json"(vendor homes are skipped unless--vendors).
Setup modes: adopt, nuke, workspace
git clone https://github.com/edotau/claude-code ~/.claude.stage # ~/.claude already exists: stage the clone,
make -C ~/.claude.stage adopt # then adopt it (backs up collisions) + bootstrap
claude-code install --setup nuke [--apply] [--keep-memory] # archive untracked content, then remove
claude-code install --setup workspace init|link|status # scope a project's own .claude/
Providers
Built-ins live in internal/providers/defaults.json. claude-code vault edit overlays them by name (an entry
replaces the built-in; null removes it).
"providers": {
"default": "gateway",
"fallback": ["gateway", "anthropic"], // 429/5xx ladder (implies the router)
"providers": {
"gateway": {
"kind": "anthropic", // dialect base_url speaks
"base_url": "https://llm.example.com",
"routes": {"openai": "/v1"}, // extra dialects on the same gateway
"auth": {"type": "bearer", "env": "GATEWAY_API_KEY"},
"models": {"opus": "claude-opus-5", "sonnet": "claude-sonnet-5", "haiku": "gpt-5-nano"},
"one_m": true // adds [1m] to Claude ids
},
"ollama": null
}
}
| Field | Meaning |
|---|---|
kind | anthropic · openai · responses · gemini |
auth.type | x-api-key · bearer · none · passthrough (subscription OAuth; auth.login names the vendor CLI) |
models | slot → model id |
headers | sent on every upstream request |
claude-code configure provider --list [name] # providers, credential state, fallback ladder
claude-code switch gateway # pin the session provider
claude-code models --pin haiku=openai:gpt-5-nano # pin a slot; provider:model crosses providers
claude-code models --unpin | --live --provider p # clear pins | list what upstream serves
claude-code --provider gateway --model claude-sonnet-5 # this launch only
Precedence: --provider → HARNESS_PROVIDER → registry default. Slot: HARNESS_<SLOT>_MODEL → HARNESS_MODEL →
the provider's models. Process env beats vault pins.
Vault: claude-code vault list|edit
state/vault.db holds pins, custom launch env, provider/vendor overlays and key_command as one JSON document, plus
sealed secrets. vault edit opens it in $EDITOR and saves atomically; secrets never appear in it.
{
"pins": {"HARNESS_PROVIDER": "anthropic", "HARNESS_HAIKU_MODEL": "openai:gpt-5-nano"},
"env": {"MY_PROJECT_ROOT": "/home/me/work", "SOME_API_TOKEN": "@secret"}, // @secret = vault secret of that name
"providers": {"default": "gateway"},
"vendors": {"vendors": {"codex": {"permission": {"approvalPolicy": "on-failure"}}}},
"vault": {"key_command": ""}
}
Credentials
First non-empty source wins:
- Process env —
auth.env - Vault —
claude-code vault set <KEY>(AES-256-GCM) auth.fileauth.command— prints the credential; cachedauth.ttlseconds (default 300), re-run on 401
"auth": {"type": "bearer", "command": "op read op://Private/gateway/credential", "ttl": 3600}
claude-code token --provider <p> is the apiKeyHelper Claude Code calls, so no key lands in settings.json.
claude-code vault set [KEY] # bare on a terminal = guided dialog
claude-code vault get KEY... [--export]
claude-code vault import keys.env # then delete the plaintext file
claude-code vault get KEY... | ssh box claude-code vault import - --yes
claude-code configure provider --list # credential sources; never prints values
claude-code doctor --scan|--git|--secrets # leak audits; never print values
Databricks: only u2m and pat credentials are stored, sealed in the vault, plus the u2m access token cached as
PROVIDER_<ID>_ACCESS_TOKEN. oauth-m2m tokens are minted per use and never stored; the SP client secret stays sealed.
claude-code databricks mint <id> [--copy] [--clear-after 30s] [--dry-run] prints the auth type, length and expiry,
never the token. --copy puts it on the clipboard and clears it after 30s; on WSL the copy stays out of Win+V history.
claude-code configure → databricks: Login / Paste PAT / Mint now / Copy token / Apply to agents.
configure databricks --check gives the same information without the TUI.
Clipboard gaps: macOS clipboard managers and Universal Clipboard can keep a copy; a killed clear process leaves the token; headless Linux has no clipboard.
The vault key
32 random bytes, resolved in order: HARNESS_VAULT_KEY → OS keyring (service claude-code) → key_command (a JSON
argv run without a shell). No key file is written. Headless boxes set HARNESS_VAULT_KEY or key_command.
HARNESS_VAULT_KEY is scrubbed from vendor CLI children. vault rotate-secret re-seals and keeps old keys.
Routing
claude launches direct when the provider speaks anthropic, every slot stays on it, and no fallback is set.
Otherwise it goes through the loopback router (127.0.0.1:18765, started on demand), which:
- requires a per-install client secret and a loopback
Host; - resolves
model(idorprovider:model) and strips[1m]; - passes
anthropicroutes through; translates Messages ⇄ chat-completions foropenairoutes (streaming, tools); - refreshes the credential and replays once on 401/403;
- fails over along
fallbackon 429/5xx/connect error before the first byte; - on a hard-quota 429 demotes opus → sonnet → haiku and skips the dead model for 30 minutes.
Provider hostnames resolving into the local network are refused (a literal IP or localhost in base_url is allowed).
The router disables Remote Control, so a subscription session stays direct under a fallback ladder; a
cross-provider slot or --router still routes it.
claude-code router start|status|stop
claude-code router serve --port 18765 # foreground
claude-code --router # force the router for one launch
Tailscale
claude-code network tailscale [--machines|--connect|--key [--save]|--exit-node on|off|approve]
status/machines/connect use the installed CLI. key and exit-node --approve need
TAILSCALE_OAUTH_CLIENT_ID/_SECRET (preferred) or TAILSCALE_API_KEY in the vault. make tailscale-cli installs it.
claude-code network vscode [--port N] [--stop] [--status] [--no-tailscale] [--funnel] runs
code serve-web as a detached daemon and maps it onto the tailnet (or the public internet with
--funnel), printing a token-gated URL and a terminal QR code for your phone.
Worktrees and agent views
claude-code worktree list|create <name>|clean <name>|clean-all # ~/worktrees/<repo>/*; never forces a removal
claude-code agents tree [--watch] # sessions → subagents → workflows, with vendor legs and fallbacks
claude-code agents tree --running # only what runs now, machine-wide: sessions, subagents, dispatch jobs
claude-code agents reap [--dry-run] # mark lost dispatch jobs `error`, drop dead agent-inflight markers
claude-code network view <agentId> [--follow] # one agent's snapshot or live events
claude-code network page [--addr ip:port] # dashboard over loopback or the tailnet
claude-code dispatch --host <h> --agent <a> "<task>" # detached agent TUI on another box (tmux)
claude-code network browser [--setup --browser edge] # browser control paths; Claude in Chrome install
claude-code network websearch --query q # Tavily one-shot (bare = stdio MCP server)
Agents
claude-code agents # runners and availability
claude-code ask --agent codex "Review this branch." # one-shot; --format json, --tools, --effort
claude-code ask --log | --retry <id> # recent dispatches; replay one
claude-code opencode --provider ollama --model qwen3-coder # interactive; -- forces passthrough
claude-code codex review --adversarial --base main # per-vendor verbs; claude-code codex -h lists them
claude-code gemini bridge --dirs internal "<task>" # one 1M-context sweep via agy
claude-code agents sync [--dry-run|--check] # project agents/ + CLAUDE.md into every vendor
claude-code usage --days 7 # subagent token usage
- Without
--tools, runners are read-only. Gemini runs only onagyand its Google sign-in. gemini bridgeinlines tracked files only and always skips.env*,state/, keys.agents syncrenders understate/projections/<vendor>/, installs into~/.codex,~/.copilot,~/.gemini,~/.config/opencode, and linksskills/into~/.agents/skills. No AGENTS.md lives at this root (Claude Code would load it as a second CLAUDE.md).- In-session fan-out:
agents/subagents andworkflows/scripts — seerules/workflow/master-workflow.md.
Hooks
Declared in internal/hookspec/hookspec.go, implemented in internal/hooks/. To add one: implement, register a
Spec, make install.
| Hook | Event | Does |
|---|---|---|
bash-guard | PreToolUse Bash | Blocks destructive commands (rm -rf /, force-push main, curl | sh, git resets in ~/.claude); routes noisy output through rtk |
docs-placement | PreToolUse Write/Edit | Blocks new .md at a repo root or ignored docs/; enforces the plan template |
agent-effort | PreToolUse Agent | Fills an unset subagent model (low → haiku, else sonnet); logs the decision; appends up to 3 memory recall pointers to the spawn prompt |
agent-routed | SubagentStart | Records the subagent's actual launch model against agent-effort's decision log |
workflow-lint | PreToolUse Workflow | Pins unpinned inline agents to sonnet |
agent-inflight* | Pre/PostToolUse Agent | Caps concurrent dispatches at 8 |
subagent-stop | SubagentStop | Retires the stopping subagent's inflight slot |
plan-mirror / save-plan | PostToolUse | Dated plan copies under plans/; files the approved plan |
context-checkpoint | Stop | At ≥85% context, pauses once for a handoff |
stop-format | Stop | Formats files edited this turn |
session-start | SessionStart | Injects the memory catalog and this repo's active context |
memory-recall | UserPromptSubmit | Injects up to 3 matching memory blocks |
wsl-path-normalize | UserPromptSubmit | Maps pasted Windows paths to /mnt/… |
session-harvest[-end] / pre-compact | Stop / SessionEnd / PreCompact | Saves the session into the memory bank |
access-trace | PostToolUse Read | Logs bank reads for memory review |
worktree-create / -remove | Worktree* | Under ~/worktrees/<repo>/; refuses dirty removals |
Memory bank
One store, ~/.claude/memory/: a local-only git repo (every settle commits, never pushed).
memory/
index.md generated catalog — never hand-edit
home/ cross-repo bank
claude-code/ the harness's own bank
<repo>/ per repo, keyed by origin remote basename; .origin records identity
Each bank dir holds Claude Code's native memory (MEMORY.md + topic files) and six typed files: projectContext,
activeContext, progress, decisionLog, conventions, sessionHistory. MEMORY.md's
<!-- bank:begin -->…<!-- bank:end --> region is generated; lines outside it are never touched.
~/.claude/projects/<slug>/memory is a symlink into the store.
A session gets the catalog plus this repo's active context and progress; the rest loads on demand. Settles rotate
sessionHistory past 30 entries into archive/. memory dream consolidates daily in the background.
claude-code memory recall [--repo R|--all] <terms> # BM25 search; public verb
claude-code memory init|review|promote|remember|update|dream # public verbs
claude-code memory path|index|show <id>|digest|timeline|fmt|watch # private plumbing
claude-code memory archive [--split N --apply|--dupes] # keep MEMORY.md small
claude-code memory alias # fold a second checkout
claude-code memory init enriches a bank; claude-code memory update saves manually.
Housekeeping
claude-code clean [--list|--dry-run] [--target projections|sessions] # sweep caches, run dirs, backups
claude-code history snapshot|log|diff # shadow history of config (never secrets)
claude-code doctor --audit [--days 7] # provider switches, pins, secret sets, guard blocks, failovers
claude-code network mcp # MCP health, scope drift, inline secrets
claude-code theme [--preview] | apply # statusline palette; whole look across tools
Status line
claude-code theme statusline [--style gradient|powerline|capsule|minimal|dashboard] shows model, provider, router,
context %, tokens, duration and git state, plus the 5h/weekly rate limits (5h:N% 7d:N%);
segments.agents adds N ◉ agents running (main thread + subagents + this session's dispatch legs), and
gradientEase (<1) reaches the ramp's end sooner.
Config: ~/.claude/state/statusline/config.json.
Layout
cmd/claude-code/ main
internal/ cli (verb table) · providers · router · translate · launch · vendors · agent · hooks · memory …
agents/ commands/ rules/ skills/ workflows/ loaded by Claude Code
state/vault.db pins, env, overlays, sealed secrets (untracked)
memory/ the memory store (its own local git repo)
.memory-cache/ harness backups (*.bak-*), shadow config history, vendor caches (untracked)
plans/ implementation plans (untracked)
docs/templates/ index of every embedded (`//go:embed`) template, with rendered examples
Command reference
Rows CLAUDE.md points here for.
| To… | Run |
|---|---|
| Set up a box end to end | claude-code configure [section] [--agent a] [--check] · make bootstrap |
Adopt, wipe or scope a .claude/ | claude-code install --setup adopt|nuke|workspace |
| Sync VS Code settings | claude-code theme vscode [--check|--dry-run] |
| Bash tab completion | claude-code completion --install |
| Add a gateway provider | claude-code vault edit → providers.providers |
| Edit pins, env, overlays | claude-code vault list|edit|rotate-secret |
| OpenCode reasoning effort | TUI ctrl+t · opencode run --variant high · claude-code ask --effort high |
| Project agents into vendors | claude-code agents sync [--vendor v] [--dry-run|--check] |
| Run an agent on another tailnet box | claude-code dispatch --host <h> --agent <a> "<task>" · --list --status |
| Watch agents from a phone | claude-code network page [--addr ip:port] |
| Subagent status and legs | claude-code agents tree [--watch|--running] · agents reap · claude-code network view <id> |
| Browsers Claude in Chrome can drive | claude-code network browser · network browser --setup --browser <b> |
| Audit what acted | claude-code doctor --audit |
| Config history | claude-code history snapshot|log|diff · memory: git -C ~/.claude/memory log |
| Theme | claude-code theme [--preview] [<palette>] · theme apply |
| Keep MEMORY.md small | claude-code memory archive [--split 20 --apply] |
| Lint a workflow script | claude-code workflow lint · workflow skeleton <pattern> |
| Tailnet | claude-code network tailscale [--machines|--connect|--key|--exit-node on|off|approve] |
| VS Code on your phone | claude-code network vscode [--stop|--status] [--funnel] |
Development
go test ./internal/<pkg> # while developing — only what you touched
make lint # fmt, vet, shell, yaml, markdown (CHECK=1 reports only)
make lint-deep # golangci-lint, uncapped
make test # full gate, once before pushing (= make audit = CI)
git pushruns the same gate via.githooks/pre-push;--no-verifybypasses it.settings.jsonis generated: editinternal/settings/template/, thenmake install. Template keys reset on every install; permission lists are unioned, so a removed rule must also be deleted fromsettings.jsonby hand.