configuration

Environment only, no config files. Paid keys win the auto-detect so nobody is silently downgraded.

variablemeaning
ANTHROPIC_API_KEYused if set (model: claude-opus-5)
OPENAI_API_KEYused if no anthropic key (model: gpt-5.6-terra)
GROQ_API_KEYused if neither (model: openai/gpt-oss-120b); none set: local ollama (model: llama3.2)
WH_PROVIDERforce one of: anthropic, openai, groq, ollama
WH_MODELoverride the model for any provider (wh models lists what it offers)
WH_ANTHROPIC_URLdefault https://api.anthropic.com
WH_OPENAI_URLdefault https://api.openai.com
WH_GROQ_URLdefault https://api.groq.com/openai
WH_OLLAMA_URLdefault http://localhost:11434
NO_COLORany value disables color

which provider answers

  1. ANTHROPIC_API_KEY
  2. OPENAI_API_KEY
  3. GROQ_API_KEY
  4. None of them: ollama on localhost

WH_PROVIDER overrides the order: groq opts into the free tier, ollama into the no-key option. A forced provider without its key fails with <VAR> is not set; an unknown name with unknown WH_PROVIDER '<value>' (anthropic, openai, groq, ollama).

gateways

The WH_*_URL variables point at any compatible gateway. A url that is not http or https, or that carries quotes or newlines, is rejected with invalid provider url.

how the request travels

  • Through the system curl
  • The key rides in curl's config on stdin, never in argv, so it is not in the process list
  • The request body sits in a 0600 temp file for the duration of the call and is deleted when it ends
  • wh explain carries the diff and its commit subjects (lockfiles, vendored, and minified files dropped), plus the branch name for --describe; wh why carries the commit blame points at, cut to that file, and the lines asked about; wh models carries only the key
  • The provider handles it under its own terms; ollama on localhost keeps it on your machine
  • Nothing is sent anywhere unless you run wh explain, wh why, or wh models
search $
↑↓ navigate · enter open · esc close