{"_id":"@alex-llm/claude-code-router","_rev":"3-88fc9e30c43bfe79ed951776622664d5","name":"@alex-llm/claude-code-router","dist-tags":{"latest":"1.0.46"},"versions":{"1.0.44":{"name":"@alex-llm/claude-code-router","version":"1.0.44","keywords":["claude","code","router","llm","anthropic"],"author":{"name":"alex-llm"},"license":"MIT","_id":"@alex-llm/claude-code-router@1.0.44","maintainers":[{"name":"alex-llm","email":"ycliu912@qq.com"}],"bin":{"ccrt":"dist/cli.js"},"dist":{"shasum":"9d246a039c04b839a44fe55ab93b8733a81856b9","tarball":"https://registry.npmjs.org/@alex-llm/claude-code-router/-/claude-code-router-1.0.44.tgz","fileCount":22,"integrity":"sha512-2y1GANdNUXjGVm0RN/n8Gs++ijNCbqFAHkq5DIK4BTr0KAgjDKF29rFc2rw1qu/U7VukelW9UYOPMn9HuC/fFw==","signatures":[{"sig":"MEYCIQCQijZHGqEhmY5lPNNV5UZdEE8aZEdxtJNhUiJK76OswQIhAPBgqwrqhKqKB2Hr+A+uqhOTTvtPhfdp7QFIA9seawLK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22977039},"gitHead":"e969fef05ee5d7e332cca5d7e268a47adc3a0584","scripts":{"build":"node scripts/build.js","release":"npm run build && npm publish"},"_npmUser":{"name":"alex-llm","email":"ycliu912@qq.com"},"_npmVersion":"10.8.2","description":"Use Claude Code without an Anthropics account and route it to another LLM provider","directories":{},"_nodeVersion":"22.8.0","dependencies":{"uuid":"^11.1.0","json5":"^2.2.3","dotenv":"^16.4.7","openurl":"^1.1.1","tiktoken":"^1.0.21","@fastify/static":"^8.2.0","@musistudio/llms":"^1.0.28","pino-rotating-file-stream":"^0.0.2"},"publishConfig":{"access":"public","ignore":["!build/","src/","screenshots/"]},"_hasShrinkwrap":false,"devDependencies":{"shx":"^0.4.0","esbuild":"^0.25.1","fastify":"^5.4.0","typescript":"^5.8.2","@types/node":"^24.0.15"},"_npmOperationalInternal":{"tmp":"tmp/claude-code-router_1.0.44_1756733548333_0.22105100531313293","host":"s3://npm-registry-packages-npm-production"}},"1.0.45":{"name":"@alex-llm/claude-code-router","version":"1.0.45","keywords":["claude","code","router","llm","anthropic"],"author":{"name":"alex-llm"},"license":"MIT","_id":"@alex-llm/claude-code-router@1.0.45","maintainers":[{"name":"alex-llm","email":"ycliu912@qq.com"}],"bin":{"ccrt":"dist/cli.js"},"dist":{"shasum":"fbb3a76acf1f796319d571d3e061946ef1396152","tarball":"https://registry.npmjs.org/@alex-llm/claude-code-router/-/claude-code-router-1.0.45.tgz","fileCount":23,"integrity":"sha512-fyKnZkqhqE7omnFEEu40rtb/gvlVFP/3tXbzjhPIGCc9Yl9cqHDObaBT2qyvnR3H9lgOmQR5syDq9HHhgkF3eA==","signatures":[{"sig":"MEUCIFb7iZnCYZEbtXefeMWBbU092mN1jwUNLJSmL8PyxmJ4AiEAu9Ltj5Jy6kfVi+S7wLGA/8GFmCT2k3TOkOKPn/qmjkg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22982938},"gitHead":"ccef7733bc9ba8373adadead594c2b5f22201ee3","scripts":{"build":"node scripts/build.js","release":"npm run build && npm publish"},"_npmUser":{"name":"alex-llm","email":"ycliu912@qq.com"},"_npmVersion":"10.8.2","description":"Use Claude Code without an Anthropics account and route it to another LLM provider","directories":{},"_nodeVersion":"22.8.0","dependencies":{"uuid":"^11.1.0","json5":"^2.2.3","dotenv":"^16.4.7","openurl":"^1.1.1","tiktoken":"^1.0.22","@fastify/static":"^8.2.0","@musistudio/llms":"^1.0.28","pino-rotating-file-stream":"^0.0.2"},"publishConfig":{"access":"public","ignore":["!build/","src/","screenshots/"]},"_hasShrinkwrap":false,"devDependencies":{"shx":"^0.4.0","esbuild":"^0.25.1","fastify":"^5.4.0","typescript":"^5.8.2","@types/node":"^24.0.15"},"_npmOperationalInternal":{"tmp":"tmp/claude-code-router_1.0.45_1756745521938_0.421699425995959","host":"s3://npm-registry-packages-npm-production"}},"1.0.46":{"name":"@alex-llm/claude-code-router","version":"1.0.46","description":"Use Claude Code without an Anthropics account and route it to another LLM provider","bin":{"ccrt":"dist/cli.js"},"scripts":{"build":"node scripts/build.js","release":"npm run build && npm publish"},"keywords":["claude","code","router","llm","anthropic"],"author":{"name":"alex-llm"},"license":"MIT","dependencies":{"@fastify/static":"^8.2.0","@musistudio/llms":"^1.0.28","dotenv":"^16.4.7","json5":"^2.2.3","openurl":"^1.1.1","pino-rotating-file-stream":"^0.0.2","tiktoken":"^1.0.22","uuid":"^11.1.0"},"devDependencies":{"@types/node":"^24.0.15","esbuild":"^0.25.1","fastify":"^5.4.0","shx":"^0.4.0","typescript":"^5.8.2"},"publishConfig":{"access":"public","ignore":["!build/","src/","screenshots/"]},"_id":"@alex-llm/claude-code-router@1.0.46","gitHead":"13e4628bdde31aa5dcec9dcb49eac7286adc67f0","_nodeVersion":"22.8.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-2ljJ+rAlNAMFTs4knY/vnZsbcgZGxQFePwB9RjCfXgWZVViHtTniDYPrilLUaWwG6broo32xRCfILQo2W2y6xA==","shasum":"8688080565eae21e8aafa931da30843cf368932b","tarball":"https://registry.npmjs.org/@alex-llm/claude-code-router/-/claude-code-router-1.0.46.tgz","fileCount":23,"unpackedSize":22983005,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBG7LzGIHiNO1kbVPhk3Ujuv+MZwk4j97l7aIiQzhXkWAiBeCBFX40sUYoFgOO583vGf8vUl8QXqKsKnQoHwgaTavg=="}]},"_npmUser":{"name":"alex-llm","email":"ycliu912@qq.com"},"directories":{},"maintainers":[{"name":"alex-llm","email":"ycliu912@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/claude-code-router_1.0.46_1756746746050_0.22414738281531754"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-01T13:32:28.273Z","modified":"2025-09-01T17:12:26.722Z","1.0.44":"2025-09-01T13:32:28.675Z","1.0.45":"2025-09-01T16:52:02.280Z","1.0.46":"2025-09-01T17:12:26.531Z"},"author":{"name":"alex-llm"},"license":"MIT","keywords":["claude","code","router","llm","anthropic"],"description":"Use Claude Code without an Anthropics account and route it to another LLM provider","maintainers":[{"name":"alex-llm","email":"ycliu912@qq.com"}],"readme":"# Claude Code Router\n\nI am seeking funding support for this project to better sustain its development. If you have any ideas, feel free to reach out to me: [m@musiiot.top](mailto:m@musiiot.top)\n\n\n[中文版](README_zh.md)\n\n> A powerful tool to route Claude Code requests to different models and customize any request.\n\n![](blog/images/claude-code.png)\n\n## ✨ Features\n\n- **Model Routing**: Route requests to different models based on your needs (e.g., background tasks, thinking, long context).\n- **Multi-Provider Support**: Supports various model providers like OpenRouter, DeepSeek, Ollama, Gemini, Volcengine, and SiliconFlow.\n- **Request/Response Transformation**: Customize requests and responses for different providers using transformers.\n- **Dynamic Model Switching**: Switch models on-the-fly within Claude Code using the `/model` command.\n- **GitHub Actions Integration**: Trigger Claude Code tasks in your GitHub workflows.\n- **Plugin System**: Extend functionality with custom transformers.\n\n## 🚀 Getting Started\n\n### 1. Installation\n\nFirst, ensure you have [Claude Code](https://docs.anthropic.com/en/docs/claude-code/quickstart) installed:\n\n```shell\nnpm install -g @anthropic-ai/claude-code\n```\n\nThen, install Claude Code Router:\n\n```shell\nnpm install -g @musistudio/claude-code-router\n```\n\n### 2. Configuration\n\nCreate and configure your `~/.claude-code-router/config.json` file. For more details, you can refer to `config.example.json`.\n\nThe `config.json` file has several key sections:\n\n- **`PROXY_URL`** (optional): You can set a proxy for API requests, for example: `\"PROXY_URL\": \"http://127.0.0.1:7890\"`.\n- **`LOG`** (optional): You can enable logging by setting it to `true`. When set to `false`, no log files will be created. Default is `true`.\n- **`LOG_LEVEL`** (optional): Set the logging level. Available options are: `\"fatal\"`, `\"error\"`, `\"warn\"`, `\"info\"`, `\"debug\"`, `\"trace\"`. Default is `\"debug\"`.\n- **Logging Systems**: The Claude Code Router uses two separate logging systems:\n  - **Server-level logs**: HTTP requests, API calls, and server events are logged using pino in the `~/.claude-code-router/logs/` directory with filenames like `ccr-*.log`\n  - **Application-level logs**: Routing decisions and business logic events are logged in `~/.claude-code-router/claude-code-router.log`\n- **`APIKEY`** (optional): You can set a secret key to authenticate requests. When set, clients must provide this key in the `Authorization` header (e.g., `Bearer your-secret-key`) or the `x-api-key` header. Example: `\"APIKEY\": \"your-secret-key\"`.\n- **`HOST`** (optional): You can set the host address for the server. If `APIKEY` is not set, the host will be forced to `127.0.0.1` for security reasons to prevent unauthorized access. Example: `\"HOST\": \"0.0.0.0\"`.\n- **`NON_INTERACTIVE_MODE`** (optional): When set to `true`, enables compatibility with non-interactive environments like GitHub Actions, Docker containers, or other CI/CD systems. This sets appropriate environment variables (`CI=true`, `FORCE_COLOR=0`, etc.) and configures stdin handling to prevent the process from hanging in automated environments. Example: `\"NON_INTERACTIVE_MODE\": true`.\n\n- **`Providers`**: Used to configure different model providers.\n- **`Router`**: Used to set up routing rules. `default` specifies the default model, which will be used for all requests if no other route is configured.\n- **`API_TIMEOUT_MS`**: Specifies the timeout for API calls in milliseconds.\n\n#### Environment Variable Interpolation\n\nClaude Code Router supports environment variable interpolation for secure API key management. You can reference environment variables in your `config.json` using either `$VAR_NAME` or `${VAR_NAME}` syntax:\n\n```json\n{\n  \"OPENAI_API_KEY\": \"$OPENAI_API_KEY\",\n  \"GEMINI_API_KEY\": \"${GEMINI_API_KEY}\",\n  \"Providers\": [\n    {\n      \"name\": \"openai\",\n      \"api_base_url\": \"https://api.openai.com/v1/chat/completions\",\n      \"api_key\": \"$OPENAI_API_KEY\",\n      \"models\": [\"gpt-5\", \"gpt-5-mini\"]\n    }\n  ]\n}\n```\n\nThis allows you to keep sensitive API keys in environment variables instead of hardcoding them in configuration files. The interpolation works recursively through nested objects and arrays.\n\nHere is a comprehensive example:\n\n```json\n{\n  \"APIKEY\": \"your-secret-key\",\n  \"PROXY_URL\": \"http://127.0.0.1:7890\",\n  \"LOG\": true,\n  \"API_TIMEOUT_MS\": 600000,\n  \"NON_INTERACTIVE_MODE\": false,\n  \"Providers\": [\n    {\n      \"name\": \"openrouter\",\n      \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n      \"api_key\": \"sk-xxx\",\n      \"models\": [\n        \"google/gemini-2.5-pro-preview\",\n        \"anthropic/claude-sonnet-4\",\n        \"anthropic/claude-3.5-sonnet\",\n        \"anthropic/claude-3.7-sonnet:thinking\"\n      ],\n      \"transformer\": {\n        \"use\": [\"openrouter\"]\n      }\n    },\n    {\n      \"name\": \"deepseek\",\n      \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n      \"api_key\": \"sk-xxx\",\n      \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n      \"transformer\": {\n        \"use\": [\"deepseek\"],\n        \"deepseek-chat\": {\n          \"use\": [\"tooluse\"]\n        }\n      }\n    },\n    {\n      \"name\": \"ollama\",\n      \"api_base_url\": \"http://localhost:11434/v1/chat/completions\",\n      \"api_key\": \"ollama\",\n      \"models\": [\"qwen2.5-coder:latest\"]\n    },\n    {\n      \"name\": \"gemini\",\n      \"api_base_url\": \"https://generativelanguage.googleapis.com/v1beta/models/\",\n      \"api_key\": \"sk-xxx\",\n      \"models\": [\"gemini-2.5-flash\", \"gemini-2.5-pro\"],\n      \"transformer\": {\n        \"use\": [\"gemini\"]\n      }\n    },\n    {\n      \"name\": \"volcengine\",\n      \"api_base_url\": \"https://ark.cn-beijing.volces.com/api/v3/chat/completions\",\n      \"api_key\": \"sk-xxx\",\n      \"models\": [\"deepseek-v3-250324\", \"deepseek-r1-250528\"],\n      \"transformer\": {\n        \"use\": [\"deepseek\"]\n      }\n    },\n    {\n      \"name\": \"modelscope\",\n      \"api_base_url\": \"https://api-inference.modelscope.cn/v1/chat/completions\",\n      \"api_key\": \"\",\n      \"models\": [\"Qwen/Qwen3-Coder-480B-A35B-Instruct\", \"Qwen/Qwen3-235B-A22B-Thinking-2507\"],\n      \"transformer\": {\n        \"use\": [\n          [\n            \"maxtoken\",\n            {\n              \"max_tokens\": 65536\n            }\n          ],\n          \"enhancetool\"\n        ],\n        \"Qwen/Qwen3-235B-A22B-Thinking-2507\": {\n          \"use\": [\"reasoning\"]\n        }\n      }\n    },\n    {\n      \"name\": \"dashscope\",\n      \"api_base_url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions\",\n      \"api_key\": \"\",\n      \"models\": [\"qwen3-coder-plus\"],\n      \"transformer\": {\n        \"use\": [\n          [\n            \"maxtoken\",\n            {\n              \"max_tokens\": 65536\n            }\n          ],\n          \"enhancetool\"\n        ]\n      }\n    },\n    {\n      \"name\": \"aihubmix\",\n      \"api_base_url\": \"https://aihubmix.com/v1/chat/completions\",\n      \"api_key\": \"sk-\",\n      \"models\": [\n        \"Z/glm-4.5\",\n        \"claude-opus-4-20250514\",\n        \"gemini-2.5-pro\"\n      ]\n    }\n  ],\n  \"Router\": {\n    \"default\": \"deepseek,deepseek-chat\",\n    \"background\": \"ollama,qwen2.5-coder:latest\",\n    \"think\": \"deepseek,deepseek-reasoner\",\n    \"longContext\": \"openrouter,google/gemini-2.5-pro-preview\",\n    \"longContextThreshold\": 60000,\n    \"webSearch\": \"gemini,gemini-2.5-flash\"\n  }\n}\n```\n\n### 3. Running Claude Code with the Router\n\nStart Claude Code using the router:\n\n```shell\nccr code\n```\n\n> **Note**: After modifying the configuration file, you need to restart the service for the changes to take effect:\n>\n> ```shell\n> ccr restart\n> ```\n\n### 4. UI Mode\n\nFor a more intuitive experience, you can use the UI mode to manage your configuration:\n\n```shell\nccr ui\n```\n\nThis will open a web-based interface where you can easily view and edit your `config.json` file.\n\n![UI](/blog/images/ui.png)\n\n#### Providers\n\nThe `Providers` array is where you define the different model providers you want to use. Each provider object requires:\n\n- `name`: A unique name for the provider.\n- `api_base_url`: The full API endpoint for chat completions.\n- `api_key`: Your API key for the provider.\n- `models`: A list of model names available from this provider.\n- `transformer` (optional): Specifies transformers to process requests and responses.\n\n#### Transformers\n\nTransformers allow you to modify the request and response payloads to ensure compatibility with different provider APIs.\n\n- **Global Transformer**: Apply a transformer to all models from a provider. In this example, the `openrouter` transformer is applied to all models under the `openrouter` provider.\n  ```json\n  {\n    \"name\": \"openrouter\",\n    \"api_base_url\": \"https://openrouter.ai/api/v1/chat/completions\",\n    \"api_key\": \"sk-xxx\",\n    \"models\": [\n      \"google/gemini-2.5-pro-preview\",\n      \"anthropic/claude-sonnet-4\",\n      \"anthropic/claude-3.5-sonnet\"\n    ],\n    \"transformer\": { \"use\": [\"openrouter\"] }\n  }\n  ```\n- **Model-Specific Transformer**: Apply a transformer to a specific model. In this example, the `deepseek` transformer is applied to all models, and an additional `tooluse` transformer is applied only to the `deepseek-chat` model.\n\n  ```json\n  {\n    \"name\": \"deepseek\",\n    \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n    \"api_key\": \"sk-xxx\",\n    \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n    \"transformer\": {\n      \"use\": [\"deepseek\"],\n      \"deepseek-chat\": { \"use\": [\"tooluse\"] }\n    }\n  }\n  ```\n\n- **Passing Options to a Transformer**: Some transformers, like `maxtoken`, accept options. To pass options, use a nested array where the first element is the transformer name and the second is an options object.\n  ```json\n  {\n    \"name\": \"siliconflow\",\n    \"api_base_url\": \"https://api.siliconflow.cn/v1/chat/completions\",\n    \"api_key\": \"sk-xxx\",\n    \"models\": [\"moonshotai/Kimi-K2-Instruct\"],\n    \"transformer\": {\n      \"use\": [\n        [\n          \"maxtoken\",\n          {\n            \"max_tokens\": 16384\n          }\n        ]\n      ]\n    }\n  }\n  ```\n\n**Available Built-in Transformers:**\n\n- `Anthropic`:If you use only the `Anthropic` transformer, it will preserve the original request and response parameters(you can use it to connect directly to an Anthropic endpoint).\n- `deepseek`: Adapts requests/responses for DeepSeek API.\n- `gemini`: Adapts requests/responses for Gemini API.\n- `openrouter`: Adapts requests/responses for OpenRouter API. It can also accept a `provider` routing parameter to specify which underlying providers OpenRouter should use. For more details, refer to the [OpenRouter documentation](https://openrouter.ai/docs/features/provider-routing). See an example below:\n  ```json\n    \"transformer\": {\n      \"use\": [\"openrouter\"],\n      \"moonshotai/kimi-k2\": {\n        \"use\": [\n          [\n            \"openrouter\",\n            {\n              \"provider\": {\n                \"only\": [\"moonshotai/fp8\"]\n              }\n            }\n          ]\n        ]\n      }\n    }\n  ```\n- `groq`: Adapts requests/responses for groq API.\n- `maxtoken`: Sets a specific `max_tokens` value.\n- `tooluse`: Optimizes tool usage for certain models via `tool_choice`.\n- `gemini-cli` (experimental): Unofficial support for Gemini via Gemini CLI [gemini-cli.js](https://gist.github.com/musistudio/1c13a65f35916a7ab690649d3df8d1cd).\n- `reasoning`: Used to process the `reasoning_content` field.\n- `sampling`: Used to process sampling information fields such as `temperature`, `top_p`, `top_k`, and `repetition_penalty`.\n- `enhancetool`: Adds a layer of error tolerance to the tool call parameters returned by the LLM (this will cause the tool call information to no longer be streamed).\n- `cleancache`: Clears the `cache_control` field from requests.\n- `vertex-gemini`: Handles the Gemini API using Vertex authentication.\n- `qwen-cli` (experimental): Unofficial support for qwen3-coder-plus model via Qwen CLI [qwen-cli.js](https://gist.github.com/musistudio/f5a67841ced39912fd99e42200d5ca8b).\n- `rovo-cli` (experimental): Unofficial support for gpt-5 via Atlassian Rovo Dev CLI [rovo-cli.js](https://gist.github.com/SaseQ/c2a20a38b11276537ec5332d1f7a5e53).\n\n**Custom Transformers:**\n\nYou can also create your own transformers and load them via the `transformers` field in `config.json`.\n\n```json\n{\n  \"transformers\": [\n    {\n      \"path\": \"/User/xxx/.claude-code-router/plugins/gemini-cli.js\",\n      \"options\": {\n        \"project\": \"xxx\"\n      }\n    }\n  ]\n}\n```\n\n#### Router\n\nThe `Router` object defines which model to use for different scenarios:\n\n- `default`: The default model for general tasks.\n- `background`: A model for background tasks. This can be a smaller, local model to save costs.\n- `think`: A model for reasoning-heavy tasks, like Plan Mode.\n- `longContext`: A model for handling long contexts (e.g., > 60K tokens).\n- `longContextThreshold` (optional): The token count threshold for triggering the long context model. Defaults to 60000 if not specified.\n- `webSearch`: Used for handling web search tasks and this requires the model itself to support the feature. If you're using openrouter, you need to add the `:online` suffix after the model name.\n\nYou can also switch models dynamically in Claude Code with the `/model` command:\n`/model provider_name,model_name`\nExample: `/model openrouter,anthropic/claude-3.5-sonnet`\n\n#### Custom Router\n\nFor more advanced routing logic, you can specify a custom router script via the `CUSTOM_ROUTER_PATH` in your `config.json`. This allows you to implement complex routing rules beyond the default scenarios.\n\nIn your `config.json`:\n\n```json\n{\n  \"CUSTOM_ROUTER_PATH\": \"/User/xxx/.claude-code-router/custom-router.js\"\n}\n```\n\nThe custom router file must be a JavaScript module that exports an `async` function. This function receives the request object and the config object as arguments and should return the provider and model name as a string (e.g., `\"provider_name,model_name\"`), or `null` to fall back to the default router.\n\nHere is an example of a `custom-router.js` based on `custom-router.example.js`:\n\n```javascript\n// /User/xxx/.claude-code-router/custom-router.js\n\n/**\n * A custom router function to determine which model to use based on the request.\n *\n * @param {object} req - The request object from Claude Code, containing the request body.\n * @param {object} config - The application's config object.\n * @returns {Promise<string|null>} - A promise that resolves to the \"provider,model_name\" string, or null to use the default router.\n */\nmodule.exports = async function router(req, config) {\n  const userMessage = req.body.messages.find((m) => m.role === \"user\")?.content;\n\n  if (userMessage && userMessage.includes(\"explain this code\")) {\n    // Use a powerful model for code explanation\n    return \"openrouter,anthropic/claude-3.5-sonnet\";\n  }\n\n  // Fallback to the default router configuration\n  return null;\n};\n```\n\n##### Subagent Routing\n\nFor routing within subagents, you must specify a particular provider and model by including `<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>` at the **beginning** of the subagent's prompt. This allows you to direct specific subagent tasks to designated models.\n\n**Example:**\n\n```\n<CCR-SUBAGENT-MODEL>openrouter,anthropic/claude-3.5-sonnet</CCR-SUBAGENT-MODEL>\nPlease help me analyze this code snippet for potential optimizations...\n```\n\n## Status Line (Beta)\nTo better monitor the status of claude-code-router at runtime, version v1.0.40 includes a built-in statusline tool, which you can enable in the UI.\n![statusline-config.png](/blog/images/statusline-config.png)\n\nThe effect is as follows:\n![statusline](/blog/images/statusline.png)\n\n### Integration with Powerlevel10k\n\nIf you're using Powerlevel10k as your ZSH theme, you might encounter issues with StatusLine not displaying correctly due to conflicts between Powerlevel10k's prompt system and the standard RPROMPT variable.\n\nTo properly integrate Claude Code Router StatusLine with Powerlevel10k, follow these steps:\n\n1. Remove any existing StatusLine configuration from your `.zshrc` file that sets RPROMPT directly.\n\n2. Add a custom element to your Powerlevel10k configuration in `~/.p10k.zsh`:\n\n   ```bash\n   # Add claude_statusline to the right prompt elements\n   typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(\n     # ... your existing elements\n     time                      # current time\n     claude_statusline         # Claude Code Router StatusLine\n   )\n\n   # Define the custom element for Claude Code Router StatusLine\n   typeset -g POWERLEVEL9K_CLAUDE_STATUSLINE_CONTENT_EXPANSION='$(\"$HOME/.claude-code-router/statusline.sh\")'\n   typeset -g POWERLEVEL9K_CLAUDE_STATUSLINE_BACKGROUND=\n   typeset -g POWERLEVEL9K_CLAUDE_STATUSLINE_FOREGROUND=white\n   ```\n\n3. Make sure the StatusLine integration comes after Powerlevel10k initialization in your `.zshrc`:\n\n   ```bash\n   # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.\n   [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh\n\n   # Claude Code Router StatusLine integration is handled via Powerlevel10k custom element\n   ```\n\n4. Reload your shell configuration:\n   ```bash\n   source ~/.zshrc\n   ```\n\nThis approach integrates StatusLine as a native Powerlevel10k element, avoiding conflicts with the theme's prompt system.\n\n## 🤖 GitHub Actions\n\nIntegrate Claude Code Router into your CI/CD pipeline. After setting up [Claude Code Actions](https://docs.anthropic.com/en/docs/claude-code/github-actions), modify your `.github/workflows/claude.yaml` to use the router:\n\n```yaml\nname: Claude Code\n\non:\n  issue_comment:\n    types: [created]\n  # ... other triggers\n\njobs:\n  claude:\n    if: |\n      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||\n      # ... other conditions\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: read\n      issues: read\n      id-token: write\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 1\n\n      - name: Prepare Environment\n        run: |\n          curl -fsSL https://bun.sh/install | bash\n          mkdir -p $HOME/.claude-code-router\n          cat << 'EOF' > $HOME/.claude-code-router/config.json\n          {\n            \"log\": true,\n            \"NON_INTERACTIVE_MODE\": true,\n            \"OPENAI_API_KEY\": \"${{ secrets.OPENAI_API_KEY }}\",\n            \"OPENAI_BASE_URL\": \"https://api.deepseek.com\",\n            \"OPENAI_MODEL\": \"deepseek-chat\"\n          }\n          EOF\n        shell: bash\n\n      - name: Start Claude Code Router\n        run: |\n          nohup ~/.bun/bin/bunx @musistudio/claude-code-router@1.0.8 start &\n        shell: bash\n\n      - name: Run Claude Code\n        id: claude\n        uses: anthropics/claude-code-action@beta\n        env:\n          ANTHROPIC_BASE_URL: http://localhost:3456\n        with:\n          anthropic_api_key: \"any-string-is-ok\"\n```\n\n> **Note**: When running in GitHub Actions or other automation environments, make sure to set `\"NON_INTERACTIVE_MODE\": true` in your configuration to prevent the process from hanging due to stdin handling issues.\n\nThis setup allows for interesting automations, like running tasks during off-peak hours to reduce API costs.\n\n## 📝 Further Reading\n\n- [Project Motivation and How It Works](blog/en/project-motivation-and-how-it-works.md)\n- [Maybe We Can Do More with the Router](blog/en/maybe-we-can-do-more-with-the-route.md)\n\n## ❤️ Support & Sponsoring\n\nIf you find this project helpful, please consider sponsoring its development. Your support is greatly appreciated!\n\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/F1F31GN2GM)\n\n[Paypal](https://paypal.me/musistudio1999)\n\n<table>\n  <tr>\n    <td><img src=\"/blog/images/alipay.jpg\" width=\"200\" alt=\"Alipay\" /></td>\n    <td><img src=\"/blog/images/wechat.jpg\" width=\"200\" alt=\"WeChat Pay\" /></td>\n  </tr>\n</table>\n\n### Our Sponsors\n\nA huge thank you to all our sponsors for their generous support!\n\n\n- [AIHubmix](https://aihubmix.com/)\n- [BurnCloud](https://ai.burncloud.com)\n- @Simon Leischnig\n- [@duanshuaimin](https://github.com/duanshuaimin)\n- [@vrgitadmin](https://github.com/vrgitadmin)\n- @\\*o\n- [@ceilwoo](https://github.com/ceilwoo)\n- @\\*说\n- @\\*更\n- @K\\*g\n- @R\\*R\n- [@bobleer](https://github.com/bobleer)\n- @\\*苗\n- @\\*划\n- [@Clarence-pan](https://github.com/Clarence-pan)\n- [@carter003](https://github.com/carter003)\n- @S\\*r\n- @\\*晖\n- @\\*敏\n- @Z\\*z\n- @\\*然\n- [@cluic](https://github.com/cluic)\n- @\\*苗\n- [@PromptExpert](https://github.com/PromptExpert)\n- @\\*应\n- [@yusnake](https://github.com/yusnake)\n- @\\*飞\n- @董\\*\n- @\\*汀\n- @\\*涯\n- @\\*:-）\n- @\\*\\*磊\n- @\\*琢\n- @\\*成\n- @Z\\*o\n- @\\*琨\n- [@congzhangzh](https://github.com/congzhangzh)\n- @\\*\\_\n- @Z\\*m\n- @*鑫\n- @c\\*y\n- @\\*昕\n- [@witsice](https://github.com/witsice)\n- @b\\*g\n- @\\*亿\n- @\\*辉\n- @JACK \n- @\\*光\n- @W\\*l\n- [@kesku](https://github.com/kesku)\n- @水\\*丫\n- @二吉吉\n- @a\\*g\n- @\\*林\n- @\\*咸\n- @\\*明\n- @S\\*y\n- @f\\*o\n- @\\*智\n- @F\\*t\n- @r\\*c\n- [@qierkang](http://github.com/qierkang)\n- @\\*军\n\n(If your name is masked, please contact me via my homepage email to update it with your GitHub username.)\n","readmeFilename":"README.md"}