Settings¶
Everything is configured through environment variables, set in your rc file
before the source line that loads the shell layer.
How a profile gets chosen¶
Before the variables, the rule they fit into. On every cd - and before the
first prompt of a new terminal - the shell layer walks up from the current
directory looking for a .claude-profile file:
~/projects/<project-name>/api/src no marker, go up
~/projects/<project-name>/api no marker, go up
~/projects/<project-name> .claude-profile -> "work" <- first match wins
- The nearest
.claude-profilewalking upward, if there is one. - Otherwise
CLAUDE_DEFAULT_PROFILE, if you set it. - Otherwise
default, the original~/.claude.
So markers answer "in this project, use that account", and
CLAUDE_DEFAULT_PROFILE answers "and everywhere else, use this one".
Marking a project¶
Create the file in any directory - a single repo, or a folder containing several:
It contains nothing but a profile name. From then on, cd anywhere at or below
that directory selects work automatically, and claude uses that account
without you switching anything.
~/projects/<project-name>/ .claude-profile -> "work"
├── api/ -> work
├── web/ -> work
└── infra/ -> work
Putting it one level above your repos, as here, covers all of them from one file and keeps it outside version control - nothing to commit or gitignore. Put it inside a repo instead if only that repo should differ.
A deeper marker beats a shallower one, so a single repo can opt out of its parent's rule:
Markers are just files. Delete one to remove the rule, or cat one to see it.
claude-doctor reports any that name a profile which does not exist.
See Per-project accounts for the full guide.
CLAUDE_DEFAULT_PROFILE¶
Which profile an unmarked directory falls back to. Defaults to default,
i.e. the original ~/.claude.
Set it before the source line, in ~/.zshrc or ~/.bashrc.
This is the machine-wide fallback, not a per-project setting - it applies wherever no marker matches.
It is worth setting when default is not the account you want to land on - after
logging out of it, for instance, or if your original ~/.claude belongs to an
account you rarely use.
A marker always wins
Setting this does not disturb directories that already have a
.claude-profile. It only changes what happens everywhere else.
If you would rather not set an environment variable, a marker at your home directory does much the same job:
The difference is small. The variable applies wherever your rc file is loaded. A
marker at ~ is a real file, so anything walking upward finds it too.
CLAUDE_PROFILE_PROMPT¶
Show the active profile in your prompt, so you cannot use the wrong account by accident.
zsh appends it to RPROMPT; bash prepends it to PS1.
It stays quiet on whichever profile is your normal one - default, or whatever
CLAUDE_DEFAULT_PROFILE is set to. So the prompt only speaks up when you are
somewhere unusual, which is when it matters:
~/projects/personal % (nothing - your usual account)
~/projects/client-work % claude:client (flagged)
| Variable | Effect |
|---|---|
CLAUDE_PROFILE_PROMPT=1 |
turn the indicator on |
CLAUDE_PROFILE_PROMPT_PREFIX |
text before the name (default claude:) |
CLAUDE_PROFILE_SHOW_DEFAULT=1 |
show it everywhere, including your usual profile |
Building your own prompt? Call claude_profile_prompt directly - it prints the
indicator or nothing, and touches no other state.
Knowing which profile is active¶
Two indicators cover two different places, and you probably want both:
| Where you are | What tells you | Set up with |
|---|---|---|
| Your shell | the prompt indicator | CLAUDE_PROFILE_PROMPT=1, above |
| Inside a Claude Code session | the status line | claude-profiles statusline --install-all |
The shell prompt disappears the moment Claude Code takes over the terminal, which is exactly when knowing the account matters most - so the status line is not a duplicate of it.
Choose what it shows with --show; the segments are listed in the
command reference. Settings are
per-profile, which is why --install-all exists.
CLAUDE_HANDOFF_COPY¶
Make claude-handoff copy instead of move. By default a handoff moves: the
source transcript is renamed to <session-id>.jsonl.bak once the target is
verified identical.
--move and --copy on the command line override it. See
Move or copy.
CLAUDE_PROFILE_HOME¶
Where account data lives. Defaults to ~/.claude-profiles. Set it before
running install.sh if you want it elsewhere.
CLAUDE_CONFIG_DIR¶
Read by Claude Code itself, not by this tool - claude-profile sets it for you.
Setting it by hand works too, and claude-doctor warns if it points somewhere
that does not exist.
NO_COLOR¶
Honoured by every command. Output is also uncoloured automatically when piped.
Overrides you rarely need¶
The shell layer works these out for itself. Set one only when the guess is
wrong on your machine, before the source line in your rc file.
| Variable | What it points at | Default |
|---|---|---|
CLAUDE_TOOLS_DIR |
where this tool is installed | derived from the sourced file's own path |
CLAUDE_PROFILE_PY |
the core script | $CLAUDE_TOOLS_DIR/bin/claude-profiles.py |
CLAUDE_PY |
the Python to run it with | python3, else python, whichever is on PATH |
The usual reason is a machine where Python is installed under another name, or a pinned interpreter:
claude-doctor reports which Python it found, so check there first.