Shrnutí
Tohle mě štvalo asi měsíc, než jsem se rozhodl to vyřešit. Claude Code ukládá úplně všechno — credentials, nastavení, MCP servery, projektová data — do jednoho adresáře ~/.claude. Žádné profily, žádná podpora více účtů. Osobní subscription a firemní team? Odhlásit, přihlásit, doufat. Tak jsem si napsal cpm — jednoduchý CLI, který dá každému účtu vlastní příkaz claude-<jméno> a hotovo.
Co mě k tomu přivedlo
Mám osobní Claude předplatné na side projekty a firemní team účet. Plus občas testuju věci přes Vertex AI. A pokaždé, když jsem potřeboval přepnout, musel jsem se odhlásit, přihlásit znovu, a pak zjistit, že se mi někde přepsalo nastavení. Spustit dva účty vedle sebe nešlo vůbec.
Jednou jsem omylem rozjel firemní Claude na osobním projektu. Špatný billing, špatné credentials — prostě nepříjemnost, které se dalo vyhnout.
Chvíli jsem si ručně vytvářel adresáře a nastavoval CLAUDE_CONFIG_DIR, ale to se rychle stalo neudržitelným. Zapomněl jsem synchronizovat MCP servery, rozbil symlink, jednou jsem si přepsal settings. Takže jsem to zautomatizoval.
Jak to funguje
Celý princip je jednoduchý — cpm vytvoří pro každý profil izolovaný adresář a vygeneruje wrapper skript, který na něj nasměruje Claude Code.
# Instalace
brew install jakubkontra/tap/cpm
# Průvodce nastavením — zeptá se na profily, modely, env proměnné
cpm init
# Vytvoří adresáře a wrapper skripty
cpm install
# A teď máte oddělené příkazy
claude-personal # otevře OAuth pro osobní účet
claude-work # úplně nezávislý OAuth pro firemní účet
Po prvním cpm install máte v ~/.local/bin/ bash skripty pro každý profil. Fungují nezávisle na cpm — i kdybyste ho odinstalovali, wrapper skripty jedou dál.
Konfigurace
Všechno se řídí jedním TOML souborem:
[profiles.personal]
description = "Osobní předplatné"
default_model = "opus"
[profiles.work]
description = "Firemní team účet"
default_model = "sonnet"
extra_directories = ["~/Work/shared-configs"]
[profiles.vertex]
description = "Vertex AI (GCP)"
default_model = "sonnet"
[profiles.vertex.env]
CLAUDE_CODE_USE_VERTEX = "1"
CLOUD_ML_REGION = "europe-west1"
ANTHROPIC_VERTEX_PROJECT_ID = "my-gcp-project"
Co se sdílí a co ne
Nad tímhle jsem přemýšlel asi nejvíc. Nakonec jsem zvolil hybridní strategii:
Zkopírované soubory — settings.json, settings.local.json, CLAUDE.md. Tyhle se kopírují z ~/.claude, protože každý profil je může mít jiné. Firemní profil s jinými pravidly než osobní — to dává smysl.
Symlinkované adresáře — commands/, skills/, agents/, plugins/. Tyhle ukazují zpět na ~/.claude/. Když si přidáte nový custom command, vidí ho všechny profily okamžitě. Nechtěl jsem, aby se tyhle věci duplikovaly.
Credentials — ty si každý profil řeší sám. cpm je záměrně nekopíruje a nesdílí.
Co wrapper skripty doopravdy dělají
# Zjednodušená verze claude-work:
unset CLAUDE_CONFIG_DIR CLAUDE_PROFILE ANTHROPIC_API_KEY # vyčistit
export CLAUDE_CONFIG_DIR="$HOME/.claude-profiles/work"
export CLAUDE_PROFILE="work"
exec claude "$@"
Ten unset na začátku je důležitější, než by se zdálo. Bez něj vám exportovaný ANTHROPIC_API_KEY z jednoho shellu tiše unikne do všech profilů. U Vertex AI setupu to znamená auth selhání, které je neskutečně těžké debugovat.
Automatické přepínání podle projektu
Tahle funkce mě osobně těší asi nejvíc. Prostě hodíte do projektu soubor .claude-profile:
cd ~/Work/company-project
cpm link work
# vytvoří .claude-profile s obsahem "work"
Přidáte hook do .zshrc:
echo 'eval "$(cpm hook)"' >> ~/.zshrc
A od teď pokaždé, když cd do toho projektu, automaticky se aktivuje správný profil. Hook prochází adresářový strom nahoru — úplně stejný princip jako .nvmrc nebo .node-version. Žádné přemýšlení, žádné ruční přepínání.
Když se něco rozsype
Do cpm jsem přidal doctor, protože jsem sám potřeboval způsob, jak rychle zjistit, jestli je všechno v pořádku:
$ cpm doctor
claude binary found at /usr/local/bin/claude
source directory ~/.claude exists
bin directory ~/.local/bin exists and is on PATH
profile "personal": all symlinks intact
profile "work": all symlinks intact
profile "personal": credentials valid (expires in 12 days)
profile "work": credentials expired 2 days ago
Kontroluje symlinky, credentials, jestli je bin adresář v PATH — všechno, co se může časem rozbít. Taky hlídá expiraci OAuth tokenů, což je věc, na kterou jsem předtím pravidelně zapomínal.
A cpm status ukáže, kde se profily rozešly od zdroje:
$ cpm status
personal: settings.json diverged from source
work: in sync
vertex: CLAUDE.md diverged from source
Když chcete profily srovnat zpět, cpm install --sync překopíruje mutable soubory z ~/.claude.
Na co jsem narazil (a vy nemusíte)
Pár věcí, které mě stály čas a které cpm řeší za vás:
-
Ruční správa adresářů. Funguje, dokud nezapomenete synchronizovat MCP servery. Nebo dokud nerozbijete symlink. Nebo dokud nepřibude nový sdílený adresář. Prostě se to neškáluje.
-
Sdílení credentials. Každý profil se musí autentizovat sám. cpm záměrně credentials nekopíruje — OAuth je OAuth, zkratky neexistují.
-
Únik env proměnných.
ANTHROPIC_API_KEYv shellu tiše unikne do všeho. Wrapper skripty to řešíunsetna začátku. -
Duplikace skills a commands. Nepotřebujete je v každém profilu zvlášť. Symlinky fungují skvěle — jedna kopie, sdílená všude.
-
Expirované tokeny. OAuth tokeny vyprší a vy to zjistíte uprostřed práce.
cpm doctorvaruje předem.
Technické detaily
cpm je napsaný v Go, dvě závislosti — cobra na CLI a BurntSushi/toml na config. Statická binárka, žádné runtime závislosti.
Celý codebase má kolem tisíce řádků. Není to složitý nástroj — řeší jeden konkrétní problém a snaží se ho řešit dobře. Wrapper skripty jsou čistý bash, fungují bez cpm na PATH, exec nahradí shell proces bez dalšího overhead.
FAQ
Proč bash wrapper skripty a ne Go shim?
Protože chci nulovou závislost za běhu. Jakmile cpm install vygeneruje skripty, fungují i bez cpm. Shim binárka by přidávala latenci a byla single point of failure. Bash skript je jednoduchý, čitelný, debugovatelný.
Funguje to s Claude Code v IDE?
Wrapper skripty fungují v jakémkoli terminálu. Pro VS Code nebo JetBrains nastavte CLAUDE_CONFIG_DIR v environment settings IDE — nasměrujte ho na adresář profilu.
Můžu config sdílet mezi stroji?
config.toml je přenositelný. Ale adresáře profilů obsahují machine-specific symlinky a credentials, takže na každém stroji musíte spustit cpm install.
Jak to řeší MCP servery?
Při každém cpm install se přečte globální ~/.claude.json a mcpServers blok se zkopíruje do konfigurace každého profilu. Všechny profily dostanou stejné MCP servery automaticky.
Projekt je na GitHubu. Instalace přes brew install jakubkontra/tap/cpm. Pokud řešíte podobný problém, vyzkoušejte to — a klidně otevřete issue, pokud něco nefunguje.
