Project defaults for the CLI
Commit a .codeherder.env file to a repo so everyone who checks it out gets the same server and workspace, without exporting anything themselves.
If everyone on your team checks out the same repo and always points ch at the same server and workspace, you can commit that default once instead of asking each person to export it. A .codeherder.env file at the root of a repo gives ch those two defaults automatically, for anyone who runs it from inside that checkout.
It’s meant to be committed. It never holds a token, a key, or anything else that identifies you — see What it never sets below.
Where it goes, and how ch finds it
Create a file named .codeherder.env at the root of your repository:
cat > .codeherder.env << 'EOF'
CH_ADDR=https://codeherder.example.com
CH_WORKSPACE_ID=acme/platform
EOF
Every ch command walks upward from your current directory looking for that file (apart from ch device-server — see The ch device-server exception below), so it’s found whether you run ch from the repo root or from a subdirectory somewhere inside the checkout. Commit it like any other file:
git add .codeherder.env
git commit -m "Add CodeHerder project defaults"
Format
The file uses the same KEY=value shape as a shell .env file:
- One
KEY=valuepair per line. - An optional
exportprefix is allowed and ignored —export CH_ADDR=...andCH_ADDR=...behave the same way. - Wrap a value in single or double quotes if you want to; the quotes are stripped.
- Lines starting with
#are comments, and blank lines are skipped. - A line with no
=is skipped rather than treated as an error.
The two keys it can set
Only two keys are read from this file — anything else is ignored (see What it ignores):
| Key | What it sets |
|---|---|
CH_ADDR |
The server your commands talk to. Set this only if your team runs its own CodeHerder server rather than the CodeHerder cloud. |
CH_WORKSPACE_ID |
The workspace commands operate on — a name, slug, slug path, or UUID; see Managing workspaces. |
Where it sits in precedence
The project file supplies the lowest-precedence default for each key: it’s applied only when your environment doesn’t already have a value for that key. If you’ve exported CH_ADDR or CH_WORKSPACE_ID yourself, or you’re using a profile or a --workspace/--addr flag, the effective value comes from that source instead. See Credential precedence for how this fits alongside browser sign-in, CH_TOKEN, and profiles.
Because CH_ADDR changes which server your commands talk to, applying it from the project file always prints a notice so it’s never a silent switch:
ch: /path/to/repo/.codeherder.env: applying CH_ADDR=https://codeherder.example.com from the project file — commands now talk to this server
What it ignores
Any key in the file other than CH_ADDR and CH_WORKSPACE_ID is ignored, and ch prints a line to say so:
ch: .codeherder.env at /path/to/repo/.codeherder.env: ignoring SOME_OTHER_KEY — not a project-config key
What it never sets
Credentials and session identity are never read from a project file — CH_TOKEN, a profile name, or anything that identifies a signed-in person, agent, or session is rejected outright, with a sharper message:
ch: .codeherder.env at /path/to/repo/.codeherder.env: ignoring CH_TOKEN — credentials and session identity are never read from a project file
This is deliberate: a .codeherder.env file is committed to the repo, so anyone who clones it can read it. It should never carry anything a committer wouldn’t want the whole team — or anyone with read access to the repo — to see.
Two refusals follow from the same principle, both about the server the project file names in CH_ADDR:
-
If the project file sets
CH_ADDRand you’re also supplying a bearer token — viaCH_TOKEN,--token, or a profile (--profile/CH_PROFILE) — without otherwise confirming you mean to send it to that server,chrefuses:ch: /path/to/repo/.codeherder.env declares CH_ADDR=https://codeherder.example.com — refusing to send your bearer token there without your consent. Export CH_ADDR=https://codeherder.example.com yourself, or pass --addr https://codeherder.example.com, if you mean it.Exporting
CH_ADDRyourself, or passing--addrexplicitly, counts as consent and clears the refusal. -
If the project file sets
CH_ADDRand your cachedch logincredential was minted against a different server,chwon’t send that credential to the project’s server:ch: /path/to/repo/.codeherder.env declares CH_ADDR=https://codeherder.example.com, but your cached credential (`ch login`) is for a different server (https://other.example.com) — refusing to send it there. Run `ch login` against https://codeherder.example.com, or pass --token.
Either way, follow the message: run ch login against the server the project file names, or pass --token explicitly.
The ch device-server exception
ch device-server never reads a project file, even when you run it from inside a repo that has one. It’s a long-running process, and its environment is inherited by every session it later spawns — a repo-level default has no business leaking into every task that device ever runs. Point a device at a specific server or workspace with its own flags or environment instead; see Managing your devices.
Checking what applied
ch whoami shows whether a project file supplied anything for the current invocation, and which keys:
project config: /path/to/repo/.codeherder.env (CH_ADDR, CH_WORKSPACE_ID)
This row only appears when at least one key was actually applied from the file — if your environment already set both keys itself, the project file’s values were never used, and the row doesn’t show. ch whoami --json carries the same information as projectConfigPath and projectConfigApplied.
Related guides
- A repository’s project folder — a different, similarly-named
.codeherderfolder for workflow, stage, and rubric documents, not this file - Credentials and profiles — the full credential-resolution order, browser sign-in, and profiles
- Managing workspaces — how the CLI resolves your active workspace
- Using the ch CLI — the conventions that apply to every command
Last updated