Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
58 KiB
JSON
1 line
58 KiB
JSON
{"repo": "atrium-cloud/acp-stack", "files": {"data/env_vars.toml": {"f734a924803c6965e1407c0df3f1508ff5f475ad": {"t": 1785745327.82455, "n": 4359, "h": "769d456009938545", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [Kimi Code environment variables](https://www.kimi.com/code/docs/en/kimi-code-cli/configuration/env-vars.html)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-07-17\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\nagent_ids = [\"kimi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\", \"moonshotai-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "587712f0e0185a365cf8d406fe77431ff277ebdd": {"t": 1785750228.1324801, "n": 4359, "h": "769d456009938545", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [Kimi Code environment variables](https://www.kimi.com/code/docs/en/kimi-code-cli/configuration/env-vars.html)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-07-17\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\nagent_ids = [\"kimi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\", \"moonshotai-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "447e33398ce3c9a34908b406ada120b90388066a": {"t": 1785750230.2504025, "n": 4342, "h": "1c4e49c5f7a57ddc", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [Kimi Code environment variables](https://www.kimi.com/code/docs/en/kimi-code-cli/configuration/env-vars.html)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-07-17\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\nagent_ids = [\"kimi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "3912e0fb42f7d276da39ceaf5f156b3be07ed38b": {"t": 1785750231.4474223, "n": 4208, "h": "3de75d0cf97e330b", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-05-22\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "e0bea2eaaee0be5873805a1e8d454b2ab3ee35a0": {"t": 1785750232.5200193, "n": 3836, "h": "268512e4df782457", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-05-22\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "fec1a02e66c5fd431e799ef36c4d478b00e5553b": {"t": 1786067351.614011, "n": 4359, "h": "769d456009938545", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [Kimi Code environment variables](https://www.kimi.com/code/docs/en/kimi-code-cli/configuration/env-vars.html)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-07-17\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\nagent_ids = [\"kimi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\", \"moonshotai-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}, "8317429621c3670764432b57005780788d9677a8": {"t": 1786068233.6130023, "n": 4464, "h": "6dee71c32c02d93f", "c": "# API-key compatibility metadata.\n#\n# Curated from:\n# [OpenCode Docs - Providers](https://opencode.ai/docs/providers/)\n# [Pi Agent Docs - Providers](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/providers.md)\n# [Amp manual](https://ampcode.com/manual)\n# [Cursor CLI auth docs](https://docs.cursor.com/en/cli/reference/authentication)\n# [Kimi Code environment variables](https://www.kimi.com/code/docs/en/kimi-code-cli/configuration/env-vars.html)\n# [Hermes Agent configuration docs](https://hermes-agent.nousresearch.com/docs/user-guide/configuration)\n# [models.dev](https://models.dev/api.json)\n# Last updated on 2026-08-05\n\n# Provider env vars\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_API_KEY\"\nprovider_ids = [\"anthropic\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AZURE_OPENAI_API_KEY\"\nprovider_ids = [\"azure-openai-responses\"]\ncompanion_env_vars = [\"AZURE_OPENAI_BASE_URL\"]\noptional_env_vars = [\n \"AZURE_OPENAI_RESOURCE_NAME\",\n \"AZURE_OPENAI_API_VERSION\",\n \"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\",\n]\n\n[[api_keys]]\nenv_var = \"OPENAI_API_KEY\"\nprovider_ids = [\"openai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"DEEPSEEK_API_KEY\"\nprovider_ids = [\"deepseek\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GEMINI_API_KEY\"\nprovider_ids = [\"google\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MISTRAL_API_KEY\"\nprovider_ids = [\"mistral\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"GROQ_API_KEY\"\nprovider_ids = [\"groq\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CEREBRAS_API_KEY\"\nprovider_ids = [\"cerebras\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CLOUDFLARE_API_KEY\"\nprovider_ids = [\"cloudflare-ai-gateway\", \"cloudflare-workers-ai\"]\ncompanion_env_vars = [\"CLOUDFLARE_ACCOUNT_ID\"]\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XAI_API_KEY\"\nprovider_ids = [\"xai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENROUTER_API_KEY\"\nprovider_ids = [\"openrouter\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"AI_GATEWAY_API_KEY\"\nprovider_ids = [\"vercel\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ZAI_API_KEY\"\nprovider_ids = [\"zai\", \"zhipuai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"OPENCODE_API_KEY\"\nprovider_ids = [\"opencode\", \"opencode-go\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"HF_TOKEN\"\nprovider_ids = [\"huggingface\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"FIREWORKS_API_KEY\"\nprovider_ids = [\"fireworks\", \"fireworks-ai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"TOGETHER_API_KEY\"\nprovider_ids = [\"together\", \"togetherai\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"KIMI_API_KEY\"\nprovider_ids = [\"kimi-coding\", \"kimi-for-coding\"]\nagent_ids = [\"kimi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_API_KEY\"\nprovider_ids = [\"minimax\", \"minimax-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MINIMAX_CN_API_KEY\"\nprovider_ids = [\"minimax-cn\", \"minimax-cn-coding-plan\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"MOONSHOT_API_KEY\"\nprovider_ids = [\"moonshotai\", \"moonshotai-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"ANTHROPIC_FOUNDRY_API_KEY\"\nprovider_ids = [\"microsoft-foundry\"]\ncompanion_env_vars = [\"ANTHROPIC_FOUNDRY_BASE_URL\"]\noptional_env_vars = [\"ANTHROPIC_FOUNDRY_RESOURCE\"]\n\n[[api_keys]]\nenv_var = \"XIAOMI_API_KEY\"\nprovider_ids = [\"xiaomi\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_CN_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-cn\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_AMS_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-ams\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"XIAOMI_TOKEN_PLAN_SGP_API_KEY\"\nprovider_ids = [\"xiaomi-token-plan-sgp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n# Direct agent env vars\n\n[[api_keys]]\nenv_var = \"AMP_API_KEY\"\nagent_ids = [\"amp\"]\ncompanion_env_vars = []\noptional_env_vars = []\n\n[[api_keys]]\nenv_var = \"CURSOR_API_KEY\"\nagent_ids = [\"cursor\"]\ncompanion_env_vars = []\noptional_env_vars = []\n"}}, "src/runtime/agent/agent_headless_config/claude_code.rs": {"fec1a02e66c5fd431e799ef36c4d478b00e5553b": {"t": 1786067494.492813, "n": 24494, "h": "4b432b22b15a251c", "c": "use super::*;\n\nconst CLAUDE_CODE_API_KEY_HELPER_PREFIX: &str = \"printenv \";\n\npub(super) fn provision_claude_code_config(config: &Config, home: &Path) -> Result<Vec<PathBuf>> {\n let mut written = Vec::new();\n let Some(provider) = config.agent.provider.as_ref() else {\n return Ok(written);\n };\n let settings_path = home.join(\".claude\").join(\"settings.json\");\n let onboarding_path = home.join(\".claude.json\");\n let mut settings = read_json_object(&settings_path)?;\n let remove_env = {\n let env = ensure_object_field(&mut settings, \"env\", &settings_path)?;\n remove_claude_managed_env(env);\n write_claude_provider_env(config, provider, env, &settings_path)?;\n env.is_empty()\n };\n if remove_env {\n settings.remove(\"env\");\n }\n write_claude_api_key_helper(config, provider, &mut settings, &settings_path)?;\n write_json_object(&settings_path, settings)?;\n written.push(settings_path);\n\n let mut onboarding = read_json_object(&onboarding_path)?;\n onboarding.insert(\"hasCompletedOnboarding\".to_owned(), json!(true));\n write_json_object(&onboarding_path, onboarding)?;\n written.push(onboarding_path);\n Ok(written)\n}\n\npub(super) fn cleanup_claude_code_config(\n config: &Config,\n home: &Path,\n) -> Result<Vec<CleanedAgentConfig>> {\n let mut cleaned = Vec::new();\n let Some(provider) = config.agent.provider.as_ref() else {\n return Ok(cleaned);\n };\n let settings_path = home.join(\".claude\").join(\"settings.json\");\n let expected_env = claude_provider_env_for_config(config, provider, &settings_path)?;\n let expected_helper = claude_api_key_helper_for_provider(config, provider, &settings_path)?;\n if settings_path.exists() {\n let mut settings = read_json_object(&settings_path)?;\n let mut changed = false;\n let mut remove_env = false;\n if let Some(env) = settings\n .get_mut(\"env\")\n .and_then(serde_json::Value::as_object_mut)\n {\n changed |= remove_matching_claude_env(env, &expected_env);\n remove_env = env.is_empty();\n }\n if remove_env {\n settings.remove(\"env\");\n changed = true;\n }\n changed |= remove_matching_claude_api_key_helper(&mut settings, expected_helper.as_deref());\n if changed {\n write_or_remove_json_object(&settings_path, settings)?;\n cleaned.push(CleanedAgentConfig {\n label: \"Claude Code config\",\n path: settings_path,\n });\n }\n }\n\n Ok(cleaned)\n}\n\nfn claude_provider_env_for_config(\n config: &Config,\n provider: &AgentProviderConfig,\n path: &Path,\n) -> Result<Map<String, serde_json::Value>> {\n let mut env = Map::new();\n write_claude_provider_env(config, provider, &mut env, path)?;\n Ok(env)\n}\n\nfn write_claude_provider_env(\n config: &Config,\n provider: &AgentProviderConfig,\n env: &mut Map<String, serde_json::Value>,\n path: &Path,\n) -> Result<()> {\n if let Some(custom) = provider.custom.as_ref() {\n if custom.api != CustomProviderApi::AnthropicMessages {\n return Err(StackError::AgentConfigProvision {\n path: path.to_path_buf(),\n reason: \"Claude Code custom providers only support anthropic-messages\".to_owned(),\n });\n }\n env.insert(\n \"ANTHROPIC_BASE_URL\".to_owned(),\n json!(custom.base_url.clone()),\n );\n if let Some(model) = configured_provider_model(config) {\n insert_claude_model_env(env, model, false);\n }\n return Ok(());\n }\n\n let Some(profile) = claude_code_profile_for_provider_id(&provider.id) else {\n return Err(StackError::AgentConfigProvision {\n path: path.to_path_buf(),\n reason: format!(\n \"Claude Code provider `{}` has no Claude Code provider profile\",\n provider.id\n ),\n });\n };\n for (key, value) in &profile.env {\n env.insert(key.clone(), json!(value));\n }\n if let Some(base_url) = profile.base_url.as_deref() {\n env.insert(\"ANTHROPIC_BASE_URL\".to_owned(), json!(base_url));\n }\n if let Some(model) = configured_provider_model(config).filter(|model| !model.trim().is_empty())\n {\n // Profile env keys such as DeepSeek's CLAUDE_CODE_SUBAGENT_MODEL stay\n // in effect under an explicit model pin so the provider's recommended\n // cheap subagent routing is preserved; set_subagent_model profiles\n // still re-point the subagent at the pinned model below.\n insert_claude_model_env(env, model, profile.set_subagent_model);\n } else {\n insert_claude_profile_default_model_env(env, profile);\n }\n Ok(())\n}\n\nfn write_claude_api_key_helper(\n config: &Config,\n provider: &AgentProviderConfig,\n settings: &mut Map<String, serde_json::Value>,\n path: &Path,\n) -> Result<()> {\n match claude_api_key_helper_for_provider(config, provider, path)? {\n Some(helper) => {\n settings.insert(\"apiKeyHelper\".to_owned(), json!(helper));\n }\n None => {\n remove_managed_claude_api_key_helper(settings);\n }\n }\n Ok(())\n}\n\nfn claude_api_key_helper_for_provider(\n config: &Config,\n provider: &AgentProviderConfig,\n path: &Path,\n) -> Result<Option<String>> {\n if provider.custom.is_some() {\n let api_key_ref =\n require_agent_env_for_provider_config(config, provider, &provider.id, path)?;\n return Ok(Some(claude_api_key_helper_command(api_key_ref)));\n }\n let Some(profile) = claude_code_profile_for_provider_id(&provider.id) else {\n return Err(StackError::AgentConfigProvision {\n path: path.to_path_buf(),\n reason: format!(\n \"Claude Code provider `{}` has no Claude Code provider profile\",\n provider.id\n ),\n });\n };\n if profile.agent_native_auth {\n if provider.api_key_ref.is_some() {\n return Err(StackError::AgentConfigProvision {\n path: path.to_path_buf(),\n reason: format!(\n \"Claude Code provider `{}` uses agent-native auth; do not configure api_key_ref\",\n provider.id\n ),\n });\n }\n return Ok(None);\n }\n let api_key_ref = require_agent_env_for_provider_config(config, provider, &provider.id, path)?;\n Ok(Some(claude_api_key_helper_command(api_key_ref)))\n}\n\nfn insert_claude_model_env(\n env: &mut Map<String, serde_json::Value>,\n model: &str,\n set_subagent_model: bool,\n) {\n for key in [\n \"ANTHROPIC_MODEL\",\n \"ANTHROPIC_DEFAULT_FABLE_MODEL\",\n \"ANTHROPIC_DEFAULT_SONNET_MODEL\",\n \"ANTHROPIC_DEFAULT_OPUS_MODEL\",\n \"ANTHROPIC_DEFAULT_HAIKU_MODEL\",\n ] {\n env.insert(key.to_owned(), json!(model));\n }\n if set_subagent_model {\n env.insert(\"CLAUDE_CODE_SUBAGENT_MODEL\".to_owned(), json!(model));\n }\n}\n\nfn insert_claude_profile_default_model_env(\n env: &mut Map<String, serde_json::Value>,\n profile: &ClaudeCodeProviderProfile,\n) {\n let Some(model) = profile\n .default_model\n .as_deref()\n .filter(|model| !model.trim().is_empty())\n else {\n return;\n };\n let opus_model = profile.default_opus_model.as_deref().unwrap_or(model);\n env.insert(\"ANTHROPIC_MODEL\".to_owned(), json!(model));\n env.insert(\n \"ANTHROPIC_DEFAULT_FABLE_MODEL\".to_owned(),\n json!(opus_model),\n );\n env.insert(\"ANTHROPIC_DEFAULT_OPUS_MODEL\".to_owned(), json!(opus_model));\n env.insert(\n \"ANTHROPIC_DEFAULT_SONNET_MODEL\".to_owned(),\n json!(profile.default_sonnet_model.as_deref().unwrap_or(model)),\n );\n env.insert(\n \"ANTHROPIC_DEFAULT_HAIKU_MODEL\".to_owned(),\n json!(profile.default_haiku_model.as_deref().unwrap_or(model)),\n );\n if profile.set_subagent_model {\n env.insert(\"CLAUDE_CODE_SUBAGENT_MODEL\".to_owned(), json!(model));\n }\n}\n\nfn remove_claude_managed_env(env: &mut Map<String, serde_json::Value>) -> bool {\n let mut changed = false;\n for key in CLAUDE_CODE_MANAGED_ENV_KEYS {\n changed |= env.remove(*key).is_some();\n }\n changed\n}\n\nfn remove_matching_claude_env(\n env: &mut Map<String, serde_json::Value>,\n expected: &Map<String, serde_json::Value>,\n) -> bool {\n let mut changed = false;\n for key in CLAUDE_CODE_MANAGED_ENV_KEYS {\n if expected\n .get(*key)\n .is_some_and(|expected_value| env.get(*key) == Some(expected_value))\n {\n env.remove(*key);\n changed = true;\n }\n }\n changed\n}\n\nfn claude_api_key_helper_command(api_key_ref: &str) -> String {\n format!(\"{CLAUDE_CODE_API_KEY_HELPER_PREFIX}{api_key_ref}\")\n}\n\nfn remove_managed_claude_api_key_helper(settings: &mut Map<String, serde_json::Value>) -> bool {\n if settings\n .get(\"apiKeyHelper\")\n .and_then(serde_json::Value::as_str)\n .is_some_and(|value| value.starts_with(CLAUDE_CODE_API_KEY_HELPER_PREFIX))\n {\n settings.remove(\"apiKeyHelper\");\n return true;\n }\n false\n}\n\nfn remove_matching_claude_api_key_helper(\n settings: &mut Map<String, serde_json::Value>,\n expected: Option<&str>,\n) -> bool {\n if let Some(expected) = expected\n && settings\n .get(\"apiKeyHelper\")\n .and_then(serde_json::Value::as_str)\n == Some(expected)\n {\n settings.remove(\"apiKeyHelper\");\n return true;\n }\n false\n}\n\n#[cfg(test)]\nmod tests {\n use super::*;\n use serde_json::Value;\n\n #[test]\n fn claude_code_moonshot_writes_endpoint_model_and_helper_without_secret_value() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let mut config = config_with_agent(\"claude-code\", &[\"MOONSHOT_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"moonshotai\".to_owned(),\n model: None,\n api_key_ref: Some(\"MOONSHOT_API_KEY\".to_owned()),\n custom: None,\n });\n\n let provisioned =\n provision_agent_headless_config(&config, tempdir.path()).expect(\"provision\");\n\n assert_eq!(provisioned.len(), 2);\n let settings_path = tempdir.path().join(\".claude\").join(\"settings.json\");\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(&settings_path).expect(\"settings should be readable\"),\n )\n .expect(\"settings json parses\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_BASE_URL\"],\n \"https://api.moonshot.ai/anthropic\"\n );\n assert_eq!(settings[\"env\"][\"ANTHROPIC_MODEL\"], \"kimi-k3[1m]\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_FABLE_MODEL\"],\n \"kimi-k3[1m]\"\n );\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_OPUS_MODEL\"],\n \"kimi-k3[1m]\"\n );\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_SONNET_MODEL\"],\n \"kimi-k3[1m]\"\n );\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_HAIKU_MODEL\"],\n \"kimi-k3[1m]\"\n );\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_SUBAGENT_MODEL\"], \"kimi-k3[1m]\");\n assert_eq!(settings[\"env\"][\"ENABLE_TOOL_SEARCH\"], \"false\");\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_AUTO_COMPACT_WINDOW\"],\n \"1048576\"\n );\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_EFFORT_LEVEL\"], \"max\");\n assert_eq!(settings[\"apiKeyHelper\"], \"printenv MOONSHOT_API_KEY\");\n assert!(!settings.to_string().contains(\"sk-\"));\n\n let onboarding_path = tempdir.path().join(\".claude.json\");\n let onboarding: Value = serde_json::from_str(\n &std::fs::read_to_string(onboarding_path).expect(\"onboarding should be readable\"),\n )\n .expect(\"onboarding json parses\");\n assert_eq!(onboarding[\"hasCompletedOnboarding\"], true);\n }\n\n #[test]\n fn claude_code_zai_writes_profile_role_model_defaults() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let mut config = config_with_agent(\"claude-code\", &[\"ZAI_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"zai\".to_owned(),\n model: None,\n api_key_ref: Some(\"ZAI_API_KEY\".to_owned()),\n custom: None,\n });\n\n provision_agent_headless_config(&config, tempdir.path()).expect(\"provision\");\n\n let settings_path = tempdir.path().join(\".claude\").join(\"settings.json\");\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(&settings_path).expect(\"settings should be readable\"),\n )\n .expect(\"settings json parses\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_BASE_URL\"],\n \"https://api.z.ai/api/anthropic\"\n );\n assert_eq!(settings[\"env\"][\"ANTHROPIC_MODEL\"], \"glm-5.2[1m]\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_FABLE_MODEL\"],\n \"glm-5.2[1m]\"\n );\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_OPUS_MODEL\"],\n \"glm-5.2[1m]\"\n );\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_SONNET_MODEL\"],\n \"glm-5.2[1m]\"\n );\n assert_eq!(settings[\"env\"][\"ANTHROPIC_DEFAULT_HAIKU_MODEL\"], \"GLM-4.7\");\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_AUTO_COMPACT_WINDOW\"],\n \"1000000\"\n );\n assert_eq!(settings[\"env\"][\"API_TIMEOUT_MS\"], \"3000000\");\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC\"],\n \"1\"\n );\n assert_eq!(settings[\"apiKeyHelper\"], \"printenv ZAI_API_KEY\");\n }\n\n #[test]\n fn claude_code_deepseek_uses_flash_for_haiku_and_subagents() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let mut config = config_with_agent(\"claude-code\", &[\"DEEPSEEK_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"deepseek\".to_owned(),\n model: None,\n api_key_ref: Some(\"DEEPSEEK_API_KEY\".to_owned()),\n custom: None,\n });\n\n provision_agent_headless_config(&config, tempdir.path()).expect(\"provision\");\n\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(tempdir.path().join(\".claude/settings.json\"))\n .expect(\"settings\"),\n )\n .expect(\"settings parse\");\n assert_eq!(settings[\"env\"][\"ANTHROPIC_MODEL\"], \"deepseek-v4-pro[1m]\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_DEFAULT_HAIKU_MODEL\"],\n \"deepseek-v4-flash\"\n );\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_SUBAGENT_MODEL\"],\n \"deepseek-v4-flash\"\n );\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_EFFORT_LEVEL\"], \"max\");\n\n config.agent.provider.as_mut().expect(\"provider\").model =\n Some(\"deepseek-v4-pro[1m]\".to_owned());\n provision_agent_headless_config(&config, tempdir.path()).expect(\"reprovision\");\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(tempdir.path().join(\".claude/settings.json\"))\n .expect(\"settings\"),\n )\n .expect(\"settings parse\");\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_SUBAGENT_MODEL\"],\n \"deepseek-v4-flash\"\n );\n }\n\n #[test]\n fn claude_code_kimi_for_coding_uses_coding_endpoint_and_kimi_key() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let mut config = config_with_agent(\"claude-code\", &[\"KIMI_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"kimi-coding\".to_owned(),\n model: None,\n api_key_ref: Some(\"KIMI_API_KEY\".to_owned()),\n custom: None,\n });\n\n provision_agent_headless_config(&config, tempdir.path()).expect(\"provision\");\n\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(tempdir.path().join(\".claude/settings.json\"))\n .expect(\"settings\"),\n )\n .expect(\"settings parse\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_BASE_URL\"],\n \"https://api.kimi.com/coding/\"\n );\n assert_eq!(settings[\"env\"][\"ANTHROPIC_MODEL\"], \"kimi-for-coding\");\n assert_eq!(\n settings[\"env\"][\"CLAUDE_CODE_SUBAGENT_MODEL\"],\n \"kimi-for-coding\"\n );\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_EFFORT_LEVEL\"], \"high\");\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_AUTO_COMPACT_WINDOW\"], \"262144\");\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_MAX_CONTEXT_TOKENS\"], \"262144\");\n assert_eq!(settings[\"apiKeyHelper\"], \"printenv KIMI_API_KEY\");\n }\n\n #[test]\n fn claude_code_bedrock_uses_native_auth_without_helper() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let settings_path = tempdir.path().join(\".claude\").join(\"settings.json\");\n std::fs::create_dir_all(settings_path.parent().expect(\"settings has parent\"))\n .expect(\"create settings dir\");\n std::fs::write(\n &settings_path,\n r#\"{\"apiKeyHelper\":\"printenv OLD_KEY\",\"env\":{\"KEEP_ME\":\"yes\",\"ANTHROPIC_BASE_URL\":\"https://old.example\"}}\"#,\n )\n .expect(\"write existing settings\");\n let mut config = config_with_agent(\"claude-code\", &[]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"amazon-bedrock\".to_owned(),\n model: Some(\"us.anthropic.claude-sonnet-4-5-20250929-v1:0\".to_owned()),\n api_key_ref: None,\n custom: None,\n });\n\n provision_agent_headless_config(&config, tempdir.path()).expect(\"provision\");\n\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(&settings_path).expect(\"settings should be readable\"),\n )\n .expect(\"settings json parses\");\n assert!(settings.get(\"apiKeyHelper\").is_none());\n assert_eq!(settings[\"env\"][\"KEEP_ME\"], \"yes\");\n assert_eq!(settings[\"env\"][\"CLAUDE_CODE_USE_BEDROCK\"], \"1\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_MODEL\"],\n \"us.anthropic.claude-sonnet-4-5-20250929-v1:0\"\n );\n }\n\n #[test]\n fn claude_code_cleanup_removes_managed_keys_and_keeps_user_settings() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let settings_path = tempdir.path().join(\".claude\").join(\"settings.json\");\n std::fs::create_dir_all(settings_path.parent().expect(\"settings has parent\"))\n .expect(\"create settings dir\");\n std::fs::write(\n &settings_path,\n r#\"{\"apiKeyHelper\":\"printenv MOONSHOT_API_KEY\",\"env\":{\"ANTHROPIC_BASE_URL\":\"https://api.moonshot.ai/anthropic\",\"ANTHROPIC_AUTH_TOKEN\":\"old\",\"ANTHROPIC_API_KEY\":\"old\",\"ANTHROPIC_MODEL\":\"kimi-k2.7-code\",\"ANTHROPIC_DEFAULT_FABLE_MODEL\":\"kimi-k2.7-code\",\"ANTHROPIC_DEFAULT_OPUS_MODEL\":\"kimi-k2.7-code\",\"ANTHROPIC_DEFAULT_SONNET_MODEL\":\"kimi-k2.7-code\",\"ANTHROPIC_DEFAULT_HAIKU_MODEL\":\"kimi-k2.7-code\",\"CLAUDE_CODE_SUBAGENT_MODEL\":\"kimi-k2.7-code\",\"KEEP_ME\":\"yes\"},\"theme\":\"keep\"}\"#,\n )\n .expect(\"write settings\");\n let onboarding_path = tempdir.path().join(\".claude.json\");\n std::fs::write(\n &onboarding_path,\n r#\"{\"hasCompletedOnboarding\":true,\"keep\":true}\"#,\n )\n .expect(\"write onboarding\");\n let mut config = config_with_agent(\"claude-code\", &[\"MOONSHOT_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"moonshotai\".to_owned(),\n model: Some(\"kimi-k2.7-code\".to_owned()),\n api_key_ref: Some(\"MOONSHOT_API_KEY\".to_owned()),\n custom: None,\n });\n\n let cleaned = cleanup_agent_headless_config(&config, tempdir.path()).expect(\"cleanup\");\n\n assert_eq!(cleaned.len(), 1);\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(&settings_path).expect(\"settings should be readable\"),\n )\n .expect(\"settings json parses\");\n assert!(settings.get(\"apiKeyHelper\").is_none());\n assert!(settings[\"env\"].get(\"ANTHROPIC_BASE_URL\").is_none());\n assert_eq!(settings[\"env\"][\"ANTHROPIC_AUTH_TOKEN\"], \"old\");\n assert_eq!(settings[\"env\"][\"ANTHROPIC_API_KEY\"], \"old\");\n assert!(settings[\"env\"].get(\"ANTHROPIC_MODEL\").is_none());\n assert!(\n settings[\"env\"]\n .get(\"ANTHROPIC_DEFAULT_FABLE_MODEL\")\n .is_none()\n );\n assert!(\n settings[\"env\"]\n .get(\"ANTHROPIC_DEFAULT_OPUS_MODEL\")\n .is_none()\n );\n assert!(\n settings[\"env\"]\n .get(\"ANTHROPIC_DEFAULT_SONNET_MODEL\")\n .is_none()\n );\n assert!(\n settings[\"env\"]\n .get(\"ANTHROPIC_DEFAULT_HAIKU_MODEL\")\n .is_none()\n );\n assert!(settings[\"env\"].get(\"CLAUDE_CODE_SUBAGENT_MODEL\").is_none());\n assert_eq!(settings[\"env\"][\"KEEP_ME\"], \"yes\");\n assert_eq!(settings[\"theme\"], \"keep\");\n let onboarding: Value = serde_json::from_str(\n &std::fs::read_to_string(onboarding_path).expect(\"onboarding should be readable\"),\n )\n .expect(\"onboarding json parses\");\n assert_eq!(onboarding[\"hasCompletedOnboarding\"], true);\n assert_eq!(onboarding[\"keep\"], true);\n }\n\n #[test]\n fn claude_code_cleanup_preserves_unmatched_env_and_helper() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let settings_path = tempdir.path().join(\".claude\").join(\"settings.json\");\n std::fs::create_dir_all(settings_path.parent().expect(\"settings has parent\"))\n .expect(\"create settings dir\");\n std::fs::write(\n &settings_path,\n r#\"{\"apiKeyHelper\":\"printenv USER_KEY\",\"env\":{\"ANTHROPIC_BASE_URL\":\"https://user.example/anthropic\",\"ANTHROPIC_MODEL\":\"user-model\",\"KEEP_ME\":\"yes\"}}\"#,\n )\n .expect(\"write settings\");\n let mut config = config_with_agent(\"claude-code\", &[\"MOONSHOT_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"moonshotai\".to_owned(),\n model: Some(\"kimi-k2.7-code\".to_owned()),\n api_key_ref: Some(\"MOONSHOT_API_KEY\".to_owned()),\n custom: None,\n });\n\n let cleaned = cleanup_agent_headless_config(&config, tempdir.path()).expect(\"cleanup\");\n\n assert!(cleaned.is_empty());\n let settings: Value = serde_json::from_str(\n &std::fs::read_to_string(&settings_path).expect(\"settings should be readable\"),\n )\n .expect(\"settings json parses\");\n assert_eq!(settings[\"apiKeyHelper\"], \"printenv USER_KEY\");\n assert_eq!(\n settings[\"env\"][\"ANTHROPIC_BASE_URL\"],\n \"https://user.example/anthropic\"\n );\n assert_eq!(settings[\"env\"][\"ANTHROPIC_MODEL\"], \"user-model\");\n assert_eq!(settings[\"env\"][\"KEEP_ME\"], \"yes\");\n }\n\n #[test]\n fn claude_code_cleanup_preserves_onboarding_when_unshared() {\n let tempdir = tempfile::tempdir().expect(\"tempdir\");\n let onboarding_path = tempdir.path().join(\".claude.json\");\n std::fs::write(&onboarding_path, r#\"{\"hasCompletedOnboarding\":true}\"#)\n .expect(\"write onboarding\");\n let mut config = config_with_agent(\"claude-code\", &[\"MOONSHOT_API_KEY\"]);\n config.agent.provider = Some(crate::config::AgentProviderConfig {\n id: \"moonshotai\".to_owned(),\n model: Some(\"kimi-k2.7-code\".to_owned()),\n api_key_ref: Some(\"MOONSHOT_API_KEY\".to_owned()),\n custom: None,\n });\n\n let cleaned = cleanup_agent_headless_config(&config, tempdir.path()).expect(\"cleanup\");\n\n assert!(cleaned.is_empty());\n let onboarding: Value = serde_json::from_str(\n &std::fs::read_to_string(onboarding_path).expect(\"onboarding should be readable\"),\n )\n .expect(\"onboarding json parses\");\n assert_eq!(onboarding[\"hasCompletedOnboarding\"], true);\n }\n}\n"}}}} |