Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clau

CI Release

Every task wants Claude Code launched differently — Opus at max effort for the hard bug, cheap Sonnet for a quick question, your code-review setup for PRs. That's a long flag incantation or another trip through the /model picker, every single time.

clau makes the choice the command name:

co5                  # claude --model opus --effort max
cs1                  # sonnet on the cheap
crev                 # your code-review persona: model + effort + flags
c s3 "explain this"  # same grammar, argument style
c "fix this bug"     # unknown token? passes straight through

Demo: co5 launches Opus at max effort; the grouped clau list; clau show details one shortcut

Install

brew install usmanbashir/tap/clau               # macOS and Linux
go install github.com/usmanbashir/clau@latest   # anywhere with Go

Prebuilt archives for six platforms are on the releases page.

Quick start

clau link            # generate shortcut commands in ~/.local/bin
co5                  # you're in Opus at max effort

Zero config needed — the built-in letters below work out of the box. If a shortcut isn't found, run clau doctor — it checks your config, PATH, collisions, and links, and says what to fix.

The grammar

<letter><digit>: the letter picks a model from [models] in your config, the digit 1–5 picks effort low/medium/high/xhigh/max. Letter alone = model only. Built-in letters: o opus, s sonnet, f fable, h haiku (haiku takes no effort digit — the CLI would silently downgrade it, so clau errors instead). The digit ladder is itself config: an [efforts] table remaps digits 19 to --effort values, replacing the default five.

Add a model in one line — g = "glm-5.2" — and g, g1g5 all resolve (re-run clau link and the commands cg, cg1cg5 exist too). A model that shouldn't take effort digits opts out with the table form — k = { model = "kimi", efforts = false } — and gets haiku's guard. One line is enough when your backend serves the model; to aim a shortcut at a different backend, use a profile — see Other backends.

Profiles

Named shortcuts that carry flags and environment — the two things a [models] letter can't hold. The name is the whole token (no effort digits; pin effort here or pass --effort at launch), and a profile can also name the claude binary it should exec — a wrapper, a fork, a pinned version. Four directions:

[profiles.rev]           # persona
model = "opus"
effort = "high"
flags = ["--append-system-prompt", "You are a meticulous code reviewer."]

[profiles.q]             # cheap one-shot pipeline tool: git diff | cq -p ...
model = "haiku"
flags = ["-p", "--max-budget-usd", "0.25"]

[profiles.work]          # LLM gateway / account switch
env = { ANTHROPIC_BASE_URL = "https://gateway.corp.example" }

[profiles.lean]          # context loadout: fast, hookless startup
flags = ["--bare", "--strict-mcp-config"]

Your own flags always win: crev --model sonnet runs the rev profile on Sonnet. c -- anything skips resolution entirely.

When several profiles share flags or environment — five local models on one backend, say — put the shared parts in a base and point each profile at it with extends. A base is never a command itself. env merges per key, flags concatenate (base's first), and model, effort, and claude fill in only where the profile leaves them unset: change the host once and every profile built on it follows. The worked example is in Other backends, backend sharing being the motivating case.

Other backends

Claude Code will talk to any endpoint that speaks the Anthropic Messages API — Ollama and LM Studio serve it natively, LiteLLM translates for everything else, and LLM gateways add org auth and routing on top. Switching backends is environment, and environment lives in profiles — shared through a base when several models ride the same backend:

[bases.ollama]
flags = ["--bare", "--strict-mcp-config"]  # small models drown in big context

[bases.ollama.env]
# no /v1 suffix — Claude Code appends /v1/messages itself
ANTHROPIC_BASE_URL = "http://localhost:11434"
# throwaway: the server ignores it, Claude Code just needs one set
ANTHROPIC_AUTH_TOKEN = "ollama"

[profiles.gem]           # gemma on the local Ollama
extends = "ollama"
model = "gemma4:12b"
# background tasks stay on the local model too
env = { ANTHROPIC_DEFAULT_HAIKU_MODEL = "gemma4:12b" }

[profiles.q27]
extends = "ollama"
model = "qwen3.6:27b"
env = { ANTHROPIC_DEFAULT_HAIKU_MODEL = "qwen3.6:27b" }

cgem and cq27 run Claude Code entirely against the local model; co5 still talks to Anthropic, and changing the host is one edit. A single profile can of course carry the env inline without a base. A [models] letter can't switch backends — it only picks a model name, served by whatever backend your environment already points at. (Which is why, behind a LiteLLM router fronting many models, one [models] line per model really is the whole job.)

Per-project config

A repo can carry its own .clau.toml — same format — and clau layers it over your global config when you launch from inside the project: [models] merge per key, a project profile, base, or [efforts] table replaces its global namesake wholesale. A project profile may extend a global base, but inheritance resolves when each file is read — overriding a base in a project file only affects profiles that file itself declares. Commit the file and the whole team shares the project's launch shapes.

Because a repo file can set env and flags, nothing applies until you allow it once:

clau trust --show    # read what the project wants
clau trust           # allow it (re-asks whenever the file changes)

Untrusted or changed files are a hard error at launch — never silently applied. clau list, clau show, and clau doctor still work untrusted; list and doctor show that a project file is present. Project-only profiles stay argument-style (c deploy); clau link links global tokens only, and a linked global command like crev picks up the project's override automatically. CLAU_NO_PROJECT=1 skips the layer entirely.

Why not shell aliases?

clau began as fish functions in my dotfiles, generalized so the same idea works without fish — or any shell config at all:

  • One static binary and one TOML file, identical in fish, zsh, bash, and on Windows. No dotfiles to sync.
  • Linked shortcuts are real commands, so editors, scripts, and anything else that execs can use them — not just your interactive shell.
  • Profiles bundle model, effort, flags, and env as data, not shell syntax.
  • Tab completion in fish, zsh, and bash.
  • Collision protection: a profile named at will not silently shadow catclau link warns, skips, and moves on.

Config

$CLAU_CONFIG or ${XDG_CONFIG_HOME:-~/.config}/clau/config.toml. Missing file = defaults. A top-level claude = "..." names the binary every shortcut execs (default: claude on PATH; a profile or base can override it per shortcut). [models] entries merge over the built-in letters, profiles and bases are all yours (none are built in), and a non-empty [efforts] table replaces the digit ladder wholesale. clau init writes a fully commented reference config.

Commands

clau <token> [args...]            launch a shortcut (same as c <token>)
clau link [--dir DIR] [--force]   sync shortcut commands (symlinks; .cmd shims on Windows)
clau unlink [--dir DIR]           remove everything clau created
clau list [--tokens] [--dir DIR]  every shortcut at a glance, grouped
clau show <token> [--dir DIR]     everything about one shortcut
clau run <token> [args...]        explicit launcher (errors on unknown token)
clau init [--force]               write a starter config
clau trust [--show]               allow (or print) the project .clau.toml
clau untrust                      revoke that trust
clau doctor [--dir DIR]           config, PATH, collisions, stale links
clau completions fish|zsh|bash    tab completion
clau version | help               version and license / command help

For fish, persist completions with clau completions fish > ~/.config/fish/conf.d/clau.fish (conf.d, not completions/ — the file registers both clau and c).

How it works

clau is strictly a launcher. It reads argv[0] to know which shortcut you called, resolves it against your config, sets flags and env, and execs claude — no wrapper process, no runtime, no telemetry, nothing between you and your session. (On Windows, where exec doesn't exist, it spawns and waits instead.)

License

GPL-3.0-or-later. See COPYING.

About

Launch Claude Code pre-configured in one word: co5 is Opus at max effort; profiles carry flags and env.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages