Firemní profil má od dneška vlastní Jira MCP server, který osobní profil nikdy neuvidí. Stačí na to tři řádky v config.toml. V dubnu jsem tu psal o cpm jako o nástroji na víc účtů Claude Code na jednom počítači. Verze 0.2.0 mezitím přidala cloud sync nastavení (settings.json, CLAUDE.md, commands/…) přes privátní git repo. Verze 0.3.0 rozšiřuje, co všechno se s účtem přepíná. Vybírám jen věci, které mění použití.
Profil je teď prostředí, ne jen token
Každý profil může mít vlastní MCP servery. mcp_exclude skryje nechtěné globální servery a [profiles.work.mcp_servers.jira] přidá server jen pro tenhle profil se stejnými klíči jako v ~/.claude.json. Při shodě jmen vyhrává profilový server nad globálním.
Stejně funguje [profiles.work.settings]: hodnoty se do settings.json hluboce slučují (deep merge). Mapy se spojí, pole a skalární hodnoty profil nahradí. Attribution, dosud jediné profilové nastavení v settings.json, je teď jen jeden z klíčů.
Sdílené adresáře jsou v profilu symlinky na ~/.claude/<dir>. isolate = ["projects"] symlink nahradí prázdným skutečným adresářem, takže profil má vlastní historii sessions – tu Claude Code drží v projects/. Skutečný adresář s daty cpm nikdy nemaže.
Nový profil dostane z ~/.claude.json jen vybrané klíče: onboarding flagy, theme a způsob instalace, nikdy oauthAccount ani projects. Do profilu pak cpm hned zapíše i MCP servery, tedy globální bez mcp_exclude a profilové. První claude-work tak přeskočí onboarding a servery vidí hned.
[profiles.work]
description = "Firemní účet"
isolate = ["projects"]
mcp_exclude = ["personal-notes"]
[profiles.work.mcp_servers.jira]
type = "http"
url = "https://jira.example.com/mcp"
[profiles.work.settings]
model = "sonnet"
Profily bez ručního editování configu
cpm add work -d "Firemní účet" -m sonnet -e JIRA_TOKEN=… zapíše profil do configu a rovnou ho nainstaluje. cpm remove work --purge odstraní wrapper, adresář, credentials i záznam v Keychainu; potvrzení přeskočí --yes. cpm clone nový profil zapíše sám.
Wrapper claude-work umí spustit jen claude. cpm exec <profile> -- <cmd> spustí s prostředím profilu cokoli jiného: skript volající claude -p, git hook, krok v CI nebo nástroj, který potřebuje třeba Vertex proměnné z [profiles.vertex.env].
cpm exec work -- ./scripts/review.sh
cpm exec work -- .git/hooks/prepare-commit-msg
Co cpm hlídá za tebe
Před pushem do cloudu cpm projde env blok v settings*.json a s API klíčem push zastaví – klíč v historii gitu už nevezmeš zpět. Přebiješ to přes --allow-secrets.
Shell hook (eval "$(cpm hook)") při odchodu z projektu s .claude-profile maže jen proměnné, které sám nastavil (CPM_MANAGED_VARS), takže tvoje vlastní proměnné ANTHROPIC_* přežijí změnu adresáře. cpm hook --default personal mimo takové projekty přepne na výchozí profil.
Na macOS list, credentials i běžný doctor jen ověří, že záznam v Keychainu existuje, a token nečtou, aby macOS nevyskakoval s dotazem na přístup. Proto cpm list ukáže „authenticated“, ale expiraci a typ předplatného uvidíš až s doctor --verify, který token přečte. Na Linuxu je token v .credentials.json a expiraci ukáže cpm credentials i doctor. doctor vrací exit 1, když některá kontrola skončí chybou, takže se hodí do CI.
Baseline v <profil>/.cpm/baseline/ pamatuje stav po syncu. Díky ní install --sync rozliší lokální úpravu od změny upstream a nepřepíše ti rozdělanou práci.
A dál: --json u čtecích příkazů, fish, cpm completion, cloud diff, push --dry-run, auto_push a auto_pull_on_install.
Co se opravilo
cpm cloud pullzapisuje profily z cloudu doconfig.toml.cpm cloud remoteuloží URL i vedle zakomentovaného# [cloud]z example configu.cpm listna macOS ukazuje „authenticated“ (viz výše).- Parser expirace čte
claudeAiOauth.expiresAtsprávně v milisekundách. auto_pushfunguje.cpm upgradeověřuje SHA-256 checksum a nahrazuje běžící binárku.- Hodnoty env proměnných ve wrapperech jsou escapované a HTTP volání mají timeout 10 s.
- Zbytek je pod „Fixed“ v CHANGELOGu.
Zpětná kompatibilita
Nová pole jsou volitelná, starý config funguje dál. Záměrné změny jsou tři. Jména profilů smí obsahovat jen [A-Za-z0-9_-]. Cloud sync vynechává settings.local.json, protože ten patří ke konkrétnímu stroji; vrátíš ho přes include = ["settings.local.json"]. A první cpm install po upgradu přegeneruje wrappery – pokud jsi je ručně neupravoval, nemusíš dělat nic.
Jak to vzniklo
Jeden prompt v plan módu Claude Code: „Podívej se, co by se dalo zlepšit, případně přidat za feature.“ Plán jsem schválil celý, proběhl v jedné session a každý krok má vlastní commit, který prošel go test, go vet a golangci-lint. Výstupy jsem četl průběžně a před merge verzi ověřil na svém stroji: cpm install je idempotentní, po cpm add a cpm remove --purge se config vrátil byte po bytu a hook v zsh přepíná, jak má. PR #3 má 19 commitů, 58 souborů a +6 312 / −1 189 řádků. Testovacích funkcí je 174, bylo jich 72.
V dubnu cpm přepínal účty, teď přepíná celé prostředí. brew upgrade cpm, zbytek najdeš v repu.
