Skip to content

Environment variables

Every environment variable the workspace reads, by subsystem: the explain command’s provider resolution (and the Claude Code it may run), the desktop daemon, and the two Vite dev servers. One more is read only by a test.

process.env is read in six places at runtime — packages/cli/src/commands/explain.ts (the real seam hands it to the discovery and the resolution below), packages/llm/src/claude-code.ts (the environment a claude -p child inherits when the caller hands none), packages/cli/src/app/store.ts (the desktop daemon’s data directory: APPDATA on Windows, XDG_DATA_HOME elsewhere), packages/cli/src/app/jobs.ts (the parent environment an extractor job is spawned with, plus the registry entry’s own), packages/viz/vite.config.ts and packages/navigator-ui/vite.config.ts — and in one test, the opt-in corpus suite packages/insights/test/cycles.test.ts. packages/llm/src/claude-code-discovery.ts reads process.platform, not the environment, when no platform is passed in.

Model provider

Read by explain, which passes process.env into the Claude Code discovery (packages/llm/src/claude-code-discovery.ts) and the provider resolution (packages/llm/src/providers.ts). Nothing else in the workspace talks to a model provider: serve and the desktop daemon open sockets to serve pages, and the daemon’s jobs, scm and snapshots spawn extractors and git, but no other code sends a prompt anywhere. A variable that is set but blank counts as absent.

VariableProviderRequiredWhat it does
OPENROUTER_API_KEYopenrouteryesthe API key the OpenRouter client authenticates with
CLOUDFLARE_API_TOKENcloudflareyesthe API token for Cloudflare AI Gateway’s REST API
CLOUDFLARE_ACCOUNT_IDcloudflareyesthe Cloudflare account the gateway belongs to
CLOUDFLARE_AI_GATEWAY_IDcloudflarenothe named gateway to route through
CLAUDE_CODE_PATHclaude-codenothe Claude Code binary, when --claude-path is not given; a path that does not exist is an error, never a fall-through. Without it, claude is looked for on PATH (HOME, and on Windows USERPROFILE and APPDATA, name the known install locations searched next)

How --provider auto decides

auto is the default. A key provider is configured when all of its required variables are present and non-blank; claude-code when the discovery found a binary.

SituationChosenReason reported
exactly one configuredthat one<its required variables> set, or where the binary was found — always the absolute path, e.g. provider: claude-code (found on PATH: /home/me/.local/bin/claude), or found in a known install location: /home/me/.local/bin/claude, CLAUDE_CODE_PATH: /opt/tools/claude
several configuredthe first of OpenRouter, Cloudflare, Claude CodeOpenRouter and Claude Code are configured; using OpenRouter (pass --provider claude-code to run the local Claude Code) — a key is deliberate, an installed CLI is ambient
none configuredopenrouter, reported as missing its variablesno provider configured

An explicit --provider openrouter, --provider cloudflare or --provider claude-code skips the decision; its reason line is prefixed with the flag, e.g. provider: claude-code (--provider claude-code, --claude-path: /opt/tools/claude). A run that needs calls then reports exactly what that provider lacks: the variables (OPENROUTER_API_KEY is not set (--provider openrouter), and this run needs 68 model calls), or for Claude Code what the discovery said (no claude on PATH or in a known install location, and this run needs 68 model calls; --claude-path /nowhere/claude does not exist, …; CLAUDE_CODE_PATH=/x/claude does not exist, …). --claude-path FILE implies --provider claude-code under auto and is refused with --provider openrouter or cloudflare. --dry-run and --estimate make no call and need no variable and no binary at all.

Dev servers

Read only by the Vite configs, so only by pnpm dev in those packages. codegraph serve does not use them: it serves the built app with the artifacts already loaded.

VariableRead byWhat it does
CITY_JSONpackages/viz/vite.config.tsabsolute path to a city.json; the dev server serves it at /city.json
NAVIGATOR_JSONpackages/navigator-ui/vite.config.tsabsolute path to a navigator.json; the dev server serves it at /navigator.json
VOCABULARY_JSONpackages/navigator-ui/vite.config.tsabsolute path to a vocabulary.json; the dev server serves it at /vocabulary.json, for the Vocabulary tab
CITY_JSON=$PWD/city.json pnpm --filter @codegraph/viz dev
NAVIGATOR_JSON=$PWD/navigator.json pnpm --filter @codegraph/navigator-ui dev

Without the variable the app falls back to ?src=URL, drag and drop, or a file picker — the dev server never becomes a required part of the pipeline. An unreadable path answers 404 with the reason.

Tests only

VariableRead byWhat it does
CODEGRAPH_CORPUS_MODELpackages/insights/test/cycles.test.tspath to a real model.jsonl; when set, the cycle suite additionally checks the insights walk’s unit condensation against the analyzer’s cycle report on that corpus. Unset, the test is skipped.

Not environment variables

JAVA_HOME matters only to the Java extractor, which is an ordinary JVM program: non-interactive shells do not source sdkman, so a JDK has to be on PATH explicitly. PATH is also where explain looks for claude (above), and HOME, USERPROFILE and APPDATA only name the install locations it searches next.

Last updated on