From daymade-claude-code
Set up multiple isolated Claude Code CLI profiles so students and power users can run different LLM providers (Kimi K3, Kimi K2.7 highspeed, GLM, DeepSeek, StepFun, Anthropic) in separate terminal windows at the same time. Use this skill whenever the user asks about multi-provider Claude setup, multiple Claude Code windows, switching models, CLAUDE_CONFIG_DIR, post-class profile installation, or running Kimi/GLM/DeepSeek/StepFun alongside Anthropic in Claude Code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/daymade-claude-code:claude-switch-models-setupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill creates an isolated-but-shared profile system for Claude Code CLI. Each profile gets its own `.claude.json` state file (credentials and session history) while sharing skills, projects, hook scripts, agents, and installed plugin state across all profiles — and converging each profile's `settings.json` (hook registration, marketplaces, env feature flags, permissions, preferences) from ...
assets/templates/anthropic.jsonassets/templates/deepseek.jsonassets/templates/glm.jsonassets/templates/kimi-highspeed.jsonassets/templates/kimi.jsonassets/templates/stepfun.jsonreferences/local-source-sync-architecture.mdreferences/student-setup-guide.mdreferences/troubleshooting.mdscripts/claude-plugins-sync.pyscripts/claude-profiles.shscripts/setup.shscripts/sync-local-skill-sources-daemon.shscripts/sync-local-skill-sources.pyscripts/sync-profile-settings.pyThis skill creates an isolated-but-shared profile system for Claude Code CLI. Each profile gets its own .claude.json state file (credentials and session history) while sharing skills, projects, hook scripts, agents, and installed plugin state across all profiles — and converging each profile's settings.json (hook registration, marketplaces, env feature flags, permissions, preferences) from the default profile, so the only intended difference between profiles is the model/provider.
The result: you can open one terminal with Kimi, another with DeepSeek, another with Anthropic — each running as a fully independent Claude Code process, without configuration bleed.
CLAUDE_CONFIG_DIR tells Claude Code CLI which directory to use as its config root.~/.claude-profiles/<name>/ with an isolated .claude.json.skills/, projects/, hooks/, agents/, settings/) are symlinked back to the main ~/.claude/ directory so you only maintain one copy. Note this shares hook scripts, not hook registration — registration lives in each profile's own settings.json (next bullet).settings.json: each profile has its own settings.json (Claude Code treats it as config-dir-local), so everything stored there — hook registration, extraKnownMarketplaces, enabledPlugins, env feature flags, permissions, behavior preferences — silently drifts the moment it changes in the default profile (measured 2026-07-18: 9/9 real profiles had zero hook registrations). sync-profile-settings.py is the converger: registered as a SessionStart hook, it copies every key from the default profile's settings.json into the active profile's, except identity keys (top-level model; and env vars that carry provider routing or Anthropic-native isolation — ANTHROPIC_*, CLAUDE_CODE_SUBAGENT_MODEL, ENABLE_TOOL_SEARCH, DISABLE_GROWTHBOOK/TELEMETRY/AUTOUPDATER — which the provider settings file deliberately sets differently). Profile-only keys are preserved; the sync never deletes. This is what makes "everything except the model works in every profile" actually hold.plugins/: marketplace content and install state are shared, but each profile keeps its own known_marketplaces.json. Claude validates a marketplace's installLocation with path.resolve() (which does NOT resolve symlinks), so a single shared file would make every non-writing profile report "corrupted installLocation". claude-plugins-sync.py builds and maintains this per-profile structure.claude-plugins-sync.py also mirrors enabledPlugins from the default ~/.claude/settings.json into each profile's settings.json (sharing cache files is not enough; Claude Code treats "enabled" state as config-dir-local). The SessionStart converger above covers the same key as part of its whole-settings sync; claude-plugins-sync.py remains the owner of the per-profile known_marketplaces.json structure.sync-local-skill-sources.py is the idempotent repair primitive; claude-profile init/launch runs it automatically, and sync-local-skill-sources-daemon.sh --install installs a macOS LaunchAgent that watches default Claude install state plus local marketplace manifests for structural changes. When a skill is removed from a marketplace manifest, the same repair pass prunes only stale Codex/agents symlinks that point back into the managed source repos; it never deletes real skill directories.references/local-source-sync-architecture.md before changing these scripts.~/.claude/settings/<name>.json, which sets ANTHROPIC_MODEL, ANTHROPIC_BASE_URL, and ANTHROPIC_AUTH_TOKEN for that window.When the user says something like "set up Claude Code profiles" or "I want to use Kimi and DeepSeek in different windows":
Check prerequisites
claude CLI is installed: which claude$SHELLpython3 is availableInstall the profile manager scripts
scripts/claude-profiles.sh to ~/.config/claude-switch-models-setup/claude-profiles.shscripts/claude-plugins-sync.py to ~/.config/claude-switch-models-setup/claude-plugins-sync.pyscripts/sync-local-skill-sources.py to ~/.config/claude-switch-models-setup/sync-local-skill-sources.pyscripts/sync-local-skill-sources-daemon.sh to ~/.config/claude-switch-models-setup/sync-local-skill-sources-daemon.shscripts/sync-profile-settings.py to ~/.config/claude-switch-models-setup/sync-profile-settings.pyAdd shell integration
~/.zshrc or ~/.bashrccsk, csks, csd, csg, css, csspsource ~/.zshrc (or open a new terminal)Generate provider settings files
~/.claude/settings/<provider>.jsonassets/templates/ as a starting pointCLAUDE_CODE_SUBAGENT_MODEL (same as ANTHROPIC_MODEL)ENABLE_TOOL_SEARCH: "false"DISABLE_GROWTHBOOK: "1"DISABLE_TELEMETRY: "1"DISABLE_AUTOUPDATER: "1"Initialize profile directories
claude-profiles-init~/.claude-profiles/<provider>/ with isolated .claude.json and symlinksStatusline wiring: claude-profiles-init auto-detects a statusline script from
~/.claude/settings.json or ~/.claude/statusline.sh and injects it into each new
profile. If neither is present, profiles will work but without a status bar. It is
the AI's job to decide whether the user needs a statusline, install the
statusline-generator skill if appropriate, and run its installer — not the profile
setup script. Do not hardcode dependency installs into shell scripts.
Register the settings converger
~/.config/claude-switch-models-setup/sync-profile-settings.py as a SessionStart hook in the default profile's ~/.claude/settings.json hooks.SessionStart list (it no-ops when the active profile IS the default; its job there is to propagate into every profile's own hooks key on the first sync)python3 ~/.config/claude-switch-models-setup/sync-profile-settings.py --allsettings.json from the default profile at each session start (changes apply next session). Audit without writing: --check --allVerify isolation
claude-profiles-doctor.claude.json and valid symlinksInstall automatic local source sync for maintainers
sync-local-skill-sources-daemon.sh --installShow the user how to launch
csk → Kimi K3 windowcsks → Kimi K2.7 highspeed windowcsd → DeepSeek windowcsg → GLM windowcss → StepFun windowcssp → StepFun paid/account-specific window, when step-pay.json existsclaude (no alias) → default Anthropic profileAfter setup, the user can run:
claude-profiles-init # Re-scan settings/*.json and create missing profiles
claude-profile <name> # Launch a specific profile
claude-profiles-ls # List profiles
claude-profiles-doctor # Check symlink health
claude-profile-rm <name> # Remove a profile's isolation directory
python3 ~/.config/claude-switch-models-setup/claude-plugins-sync.py
# Repair per-profile plugin structure and enabledPlugins
python3 ~/.config/claude-switch-models-setup/sync-profile-settings.py --all
# Converge every profile's settings.json from the default
# profile (hooks, marketplaces, env flags, permissions,
# preferences); --check --all audits without writing
python3 ~/.config/claude-switch-models-setup/sync-local-skill-sources.py --apply
# Maintainers: one-shot repair for Claude/Codex source symlinks
~/.config/claude-switch-models-setup/sync-local-skill-sources-daemon.sh --install
# Maintainers: install automatic macOS watcher
These are not day-to-day commands. Normal source edits are live through symlinks. The one-shot commands are for repair, bootstrap, or non-macOS environments without the LaunchAgent watcher.
Templates live in assets/templates/:
kimi.json — Kimi K3 (1M context, k3[1m])kimi-highspeed.json — Kimi K2.7 highspeed (legacy 200K context)glm.jsondeepseek.jsonstepfun.jsonanthropic.jsonEach template has placeholders for <API_KEY> and <BASE_URL>. Ask the user for real values; do not guess or reuse values from the current machine unless the user explicitly provides them.
| Provider | Typical base URL |
|---|---|
| Kimi | https://api.moonshot.cn or OpenRouter-compatible endpoint |
| GLM | https://open.bigmodel.cn/api/paas/v4 or OpenRouter-compatible endpoint |
| DeepSeek | https://api.deepseek.com or OpenRouter-compatible endpoint |
| StepFun | https://api.stepfun.com or OpenRouter-compatible endpoint |
| Anthropic | https://api.anthropic.com |
Important: The exact endpoint depends on whether the user is calling the provider directly or through a compatibility gateway (e.g., OpenRouter). Always ask.
| Data | Location | Shared? |
|---|---|---|
| Session history | ~/.claude-profiles/<name>/.claude.json | Isolated per profile |
| Auth tokens/cache | ~/.claude-profiles/<name>/.claude.json | Isolated per profile |
| Skills | ~/.claude/skills/ | Shared via symlink |
| Plugin content | ~/.claude/plugins/marketplaces, cache, data, ... | Shared via symlink |
| Plugin install registry | ~/.claude/plugins/installed_plugins.json | Shared via symlink |
| Enabled plugin map | ~/.claude/settings.json -> <profile>/settings.json | Converged by sync-profile-settings.py (also mirrored by claude-plugins-sync.py) |
| Plugin marketplace index | <profile>/plugins/known_marketplaces.json | Per-profile (installLocation is config-dir-specific; can't be shared) |
| Projects/memory | ~/.claude/projects/, ~/.claude/memory/ | Shared via symlink |
| Hook scripts | ~/.claude/hooks/, ~/.claude/commands/ | Shared via symlink (scripts only — NOT registration) |
settings.json config: hook registration, marketplaces, env flags, permissions, preferences | <profile>/settings.json | Converged from default profile by sync-profile-settings.py at session start (identity keys like model and provider-routing/isolation env vars are never synced) |
| Provider settings | ~/.claude/settings/<name>.json | Shared source, loaded per profile |
Symptom: /plugin or claude plugin marketplace update reports
corrupted installLocation ... expected a path inside <config-dir>/plugins/marketplaces.
Cause: known_marketplaces.json ended up shared across profiles (or hand-edited). Its
installLocation is config-dir-specific because Claude validates with path.resolve()
(symlinks NOT resolved), so one shared copy cannot satisfy multiple profiles.
Fix: claude-plugins-sync.py rebuilds each profile's own copy + the shared-content
symlinks. It runs automatically at claude-profile init/launch; to run manually:
python3 ~/.config/claude-switch-models-setup/claude-plugins-sync.py
Symptom: the default Anthropic profile can see a skill, but a third-party profile cannot.
Cause: Claude Code stores enabledPlugins in each config directory's settings.json.
Sharing plugins/cache only makes files available; it does not enable them.
Fix:
python3 ~/.config/claude-switch-models-setup/claude-plugins-sync.py
Then restart the affected Claude Code window.
Symptom: you edit a skill in a local source repo, but Claude Code or Codex still loads an old installed copy.
Expected design: normal edits to existing source files are live immediately because the installed locations are symlinks. Existing Claude Code/Codex sessions may still need a restart because skill metadata is loaded at session start.
If the edit is structural (new plugin, new skill entry, version bump, install/uninstall, or marketplace manifest change), the macOS LaunchAgent should run automatically. Check:
launchctl print gui/$(id -u)/ai.daymade.claude-skill-source-sync
Repair manually only if the watcher is not installed or you are on a non-macOS machine:
python3 ~/.config/claude-switch-models-setup/sync-local-skill-sources.py --apply
This moves existing real copies into timestamped .source-sync-backups/ folders, replaces them with symlinks to the source repos, and prunes stale managed symlinks after a skill is removed from the manifest.
Symptom: the default profile has hook guards, marketplaces, or feature flags configured, but a third-party profile behaves as if they don't exist (no PreToolUse guards fire, claude plugin marketplace list is empty, a feature enabled in the default profile is off).
Cause: those live in each profile's own settings.json, which is config-dir-local — symlinking directories does not cover the config layer, and it drifts silently the moment the default profile changes.
Fix:
python3 ~/.config/claude-switch-models-setup/sync-profile-settings.py --all
Then restart the affected window. Once the converger is registered as a SessionStart hook (setup step 6), every profile self-converges at session start, so this should only be needed after a manual settings edit you want propagated immediately.
Symptom: WebSearch or other Anthropic-native tools fail with 400 errors.
Fix: Ensure the profile's settings.json sets:
{
"env": {
"ENABLE_TOOL_SEARCH": "false",
"DISABLE_GROWTHBOOK": "1",
"DISABLE_TELEMETRY": "1",
"DISABLE_AUTOUPDATER": "1"
}
}
Symptom: Subagents inside a Kimi window call claude-opus-4-7.
Fix: Set CLAUDE_CODE_SUBAGENT_MODEL to the same value as ANTHROPIC_MODEL in the profile's settings.json.
~/.claude/settings/<new-provider>.json using a template.claude-profiles-init.~/.claude/settings/<provider>.json in plain text, the same way Claude Code stores ANTHROPIC_AUTH_TOKEN. This matches Claude Code's own security model.After setup, the user can immediately test by opening two terminals and running csk (Kimi K3) in one and csd in the other. Each window is independent.
npx claudepluginhub daymade/claude-code-skills --plugin daymade-claude-codeClaude Code extensibility and configuration reference: plugins, hooks, skills, subagents, MCP servers, output styles, memory, settings, and model configuration. Invoke whenever Claude Code itself is the subject — questions, configuration, building extensions, debugging, or understanding internals.
Deep expertise in Claude Code CLI configuration, hooks, MCPs, CLAUDE.md, sub-agents, permissions, and workflows. Activate for setup, optimization, or troubleshooting of Claude Code features.
Documents the internal architecture of Claude Code CLI v2.1.84 — covers agent loop, tool execution, prompt assembly, MCP, plugin/skill systems, and rewrite logic. Useful for building compatible alternatives or understanding the runtime.