mirror of
https://github.com/musistudio/claude-code-router.git
synced 2026-01-29 22:02:05 +00:00
fix doc
This commit is contained in:
@@ -185,7 +185,7 @@ Located in `packages/shared/src/preset/`:
|
||||
|
||||
- **sensitiveFields.ts**: Identify and sanitize sensitive fields
|
||||
- Detects api_key, password, secret fields automatically
|
||||
- Creates `requiredInputs` array for installation prompts
|
||||
- Replaces sensitive values with environment variable placeholders
|
||||
|
||||
### Preset File Format
|
||||
|
||||
@@ -206,12 +206,6 @@ Located in `packages/shared/src/preset/`:
|
||||
"label": "OpenAI API Key",
|
||||
"prompt": "Enter your OpenAI API key"
|
||||
}
|
||||
],
|
||||
"requiredInputs": [
|
||||
{
|
||||
"field": "Providers[0].api_key",
|
||||
"placeholder": "Enter your API key"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -141,14 +141,14 @@ A preset is a directory containing a `manifest.json` file:
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "{{apiKey}}",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
|
||||
"Router": {
|
||||
"default": "openai:gpt-4"
|
||||
"default": "openai,gpt-4"
|
||||
},
|
||||
|
||||
"schema": [
|
||||
@@ -251,4 +251,4 @@ ccr preset export my-preset --include-sensitive
|
||||
|
||||
- [Configuration Guide](/docs/cli/config/basic) - Basic configuration
|
||||
- [Project-Level Configuration](/docs/cli/config/project-level) - Project-specific settings
|
||||
- [Server: Presets](/docs/server/advanced/presets) - Advanced preset topics
|
||||
- [Presets](/docs/presets/intro) - Advanced preset topics
|
||||
|
||||
@@ -370,7 +370,7 @@ Output: ` feature/auth 📝 +150/-25 ⏱️ 2m34s`
|
||||
|
||||
Statusline themes can be included in presets. When you install a preset with statusline configuration, it will automatically apply when you activate that preset.
|
||||
|
||||
See [Presets](/docs/server/advanced/presets) for more information.
|
||||
See [Presets](/docs/presets/intro) for more information.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ CLI uses the same configuration file as Server: `~/.claude-code-router/config.js
|
||||
|
||||
## Configuration Methods
|
||||
|
||||
You can configure Claude Code Router in three ways:
|
||||
You can configure Claude Code Router in two ways:
|
||||
|
||||
### Option 1: Edit Configuration File Directly
|
||||
|
||||
@@ -26,20 +26,6 @@ Open the web interface and configure visually:
|
||||
ccr ui
|
||||
```
|
||||
|
||||
### Option 3: Interactive Configuration
|
||||
|
||||
Use the interactive command-line configuration:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
This will guide you through:
|
||||
1. Select LLM provider
|
||||
2. Configure API Key
|
||||
3. Select model
|
||||
4. Set routing rules
|
||||
|
||||
## Restart After Configuration Changes
|
||||
|
||||
After modifying the configuration file or making changes through the Web UI, you must restart the service:
|
||||
|
||||
@@ -21,7 +21,7 @@ Edit `~/.claude-code-router/config.json`:
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "your-api-key-here",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
|
||||
@@ -30,10 +30,6 @@ ccr preset install /path/to/preset-directory
|
||||
ccr preset install my-preset
|
||||
```
|
||||
|
||||
:::note Note
|
||||
CLI mode **does not support** installing presets directly from URLs. To install from GitHub, clone to local first or use Web UI.
|
||||
:::
|
||||
|
||||
#### Using Presets
|
||||
|
||||
After installing a preset, you can use the preset name to start Claude Code:
|
||||
@@ -41,9 +37,6 @@ After installing a preset, you can use the preset name to start Claude Code:
|
||||
```bash
|
||||
# Start with a specific preset
|
||||
ccr my-preset "your prompt"
|
||||
|
||||
# Background task with preset
|
||||
ccr my-preset --background "your prompt"
|
||||
```
|
||||
|
||||
The preset will:
|
||||
@@ -89,13 +82,6 @@ Then open `http://localhost:3000` in your browser.
|
||||
2. Select the preset you want to install from the list
|
||||
3. Click the "Install" button
|
||||
|
||||
Or manually enter a GitHub repository URL:
|
||||
|
||||
```
|
||||
Format: https://github.com/username/repo
|
||||
Example: https://github.com/example/ccr-presets
|
||||
```
|
||||
|
||||
#### Reconfigure Preset
|
||||
|
||||
1. Click the "View Details" icon next to the preset
|
||||
@@ -309,13 +295,13 @@ For complex configuration needs, use `configMappings` to precisely control value
|
||||
"Providers": [
|
||||
{
|
||||
"name": "{{primaryProvider}}",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "{{apiKey}}",
|
||||
"models": ["{{defaultModel}}"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "{{primaryProvider}}/{{defaultModel}}"
|
||||
"default": "{{primaryProvider}},{{defaultModel}}"
|
||||
},
|
||||
"PROXY_URL": "{{proxyUrl}}"
|
||||
},
|
||||
@@ -352,9 +338,6 @@ These fields describe basic information about the preset:
|
||||
| `license` | string | - | License type |
|
||||
| `keywords` | string[] | - | Keyword tags |
|
||||
| `ccrVersion` | string | - | Compatible CCR version |
|
||||
| `source` | string | - | Preset source URL |
|
||||
| `sourceType` | string | - | Source type (`local`/`gist`/`registry`) |
|
||||
| `checksum` | string | - | Content checksum (SHA256) |
|
||||
|
||||
Example:
|
||||
|
||||
@@ -382,6 +365,14 @@ These fields are directly merged into CCR's configuration. All fields supported
|
||||
| `Router` | object | Routing configuration |
|
||||
| `transformers` | array | Transformer configuration |
|
||||
| `StatusLine` | object | Status bar configuration |
|
||||
| `NON_INTERACTIVE_MODE` | boolean | Enable non-interactive mode (for CI/CD) |
|
||||
|
||||
**CLI-Only Fields** (these fields only work in CLI mode and are not used by the server):
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `noServer` | boolean | Skip local server startup and use provider's API directly |
|
||||
| `claudeCodeSettings` | object | Claude Code specific settings (env, statusLine, etc.) |
|
||||
|
||||
Example:
|
||||
|
||||
@@ -390,14 +381,14 @@ Example:
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai/gpt-4o",
|
||||
"background": "openai/gpt-4o-mini"
|
||||
"default": "openai,gpt-4o",
|
||||
"background": "openai,gpt-4o-mini"
|
||||
},
|
||||
"PORT": 8080
|
||||
}
|
||||
@@ -413,7 +404,6 @@ These fields are used to create interactive configuration templates:
|
||||
| `template` | object | Configuration template (with variable references) |
|
||||
| `configMappings` | array | Configuration mapping rules |
|
||||
| `userValues` | object | User-filled values (used at runtime) |
|
||||
| `requiredInputs` | array | Required input list (auto-generated) |
|
||||
|
||||
**Schema Field Types:**
|
||||
|
||||
@@ -483,24 +473,16 @@ cat > ~/.claude-code-router/presets/simple-openai/manifest.json << 'EOF'
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
|
||||
"Router": {
|
||||
"default": "openai/gpt-4o",
|
||||
"background": "openai/gpt-4o-mini"
|
||||
},
|
||||
|
||||
"requiredInputs": [
|
||||
{
|
||||
"id": "Providers[0].api_key",
|
||||
"prompt": "Enter OpenAI API Key",
|
||||
"placeholder": "OPENAI_API_KEY"
|
||||
"default": "openai,gpt-4o",
|
||||
"background": "openai,gpt-4o-mini"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
@@ -584,14 +566,14 @@ cat > ~/.claude-code-router/presets/advanced-config/manifest.json << 'EOF'
|
||||
"Providers": [
|
||||
{
|
||||
"name": "#{provider}",
|
||||
"api_base_url": "#{provider === 'openai' ? 'https://api.openai.com/v1' : 'https://api.deepseek.com'}",
|
||||
"api_base_url": "#{provider === 'openai' ? 'https://api.openai.com/v1/chat/completions' : 'https://api.deepseek.com/v1/chat/completions'}",
|
||||
"api_key": "#{apiKey}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "#{provider}/gpt-4o",
|
||||
"background": "#{provider}/gpt-4o-mini"
|
||||
"default": "#{provider},gpt-4o",
|
||||
"background": "#{provider},gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -639,12 +621,6 @@ ccr preset export my-exported-preset \
|
||||
--tags "production,openai"
|
||||
```
|
||||
|
||||
:::tip Share Presets
|
||||
Exported preset directories can be directly shared with others. Recipients can:
|
||||
- **CLI Mode**: Place directory in `~/.claude-code-router/presets/`, then run `ccr preset install preset-name`
|
||||
- **Web UI Mode**: Upload directory to GitHub, then install via repository URL
|
||||
:::
|
||||
|
||||
## Preset File Location
|
||||
|
||||
Presets are stored in:
|
||||
@@ -141,14 +141,14 @@ ccr preset delete my-config
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "{{apiKey}}",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
|
||||
"Router": {
|
||||
"default": "openai:gpt-4"
|
||||
"default": "openai,gpt-4"
|
||||
},
|
||||
|
||||
"schema": [
|
||||
@@ -251,4 +251,4 @@ ccr preset export my-preset --include-sensitive
|
||||
|
||||
- [配置指南](/zh/docs/cli/config/basic) - 基础配置
|
||||
- [项目级配置](/zh/docs/cli/config/project-level) - 项目特定设置
|
||||
- [服务器:预设](/zh/docs/server/advanced/presets) - 高级预设主题
|
||||
- [预设](/zh/docs/presets/intro) - 高级预设主题
|
||||
|
||||
@@ -371,7 +371,7 @@ module.exports = async function(variables, options) {
|
||||
|
||||
Statusline 主题可以包含在 presets 中。当您安装带有 statusline 配置的 preset 时,激活该 preset 时会自动应用。
|
||||
|
||||
查看 [Presets](/docs/server/advanced/presets) 了解更多信息。
|
||||
查看 [Presets](/zh/docs/presets/intro) 了解更多信息。
|
||||
|
||||
## 故障排除
|
||||
|
||||
|
||||
@@ -31,10 +31,6 @@ ccr preset install /path/to/preset-directory
|
||||
ccr preset install my-preset
|
||||
```
|
||||
|
||||
:::note 注意
|
||||
CLI 方式**不支持**从 URL 直接安装预设。如需从 GitHub 安装,请先克隆到本地或使用 Web UI。
|
||||
:::
|
||||
|
||||
#### 使用预设
|
||||
|
||||
安装预设后,可以使用预设名称启动 Claude Code:
|
||||
@@ -42,9 +38,6 @@ CLI 方式**不支持**从 URL 直接安装预设。如需从 GitHub 安装,
|
||||
```bash
|
||||
# 使用指定预设启动
|
||||
ccr my-preset "your prompt"
|
||||
|
||||
# 后台任务使用预设
|
||||
ccr my-preset --background "your prompt"
|
||||
```
|
||||
|
||||
预设会:
|
||||
@@ -90,13 +83,6 @@ ccr ui
|
||||
2. 在预设列表中选择要安装的预设
|
||||
3. 点击"安装"按钮
|
||||
|
||||
或手动输入 GitHub 仓库地址:
|
||||
|
||||
```
|
||||
格式:https://github.com/username/repo
|
||||
示例:https://github.com/example/ccr-presets
|
||||
```
|
||||
|
||||
#### 重新配置预设
|
||||
|
||||
1. 在预设列表中点击"查看详情"按钮
|
||||
@@ -310,13 +296,13 @@ CCR 引入了强大的动态配置系统,支持:
|
||||
"Providers": [
|
||||
{
|
||||
"name": "{{primaryProvider}}",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "{{apiKey}}",
|
||||
"models": ["{{defaultModel}}"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "{{primaryProvider}}/{{defaultModel}}"
|
||||
"default": "{{primaryProvider}},{{defaultModel}}"
|
||||
},
|
||||
"PROXY_URL": "{{proxyUrl}}"
|
||||
},
|
||||
@@ -353,9 +339,6 @@ CCR 引入了强大的动态配置系统,支持:
|
||||
| `license` | string | - | 许可证类型 |
|
||||
| `keywords` | string[] | - | 关键词标签 |
|
||||
| `ccrVersion` | string | - | 兼容的 CCR 版本 |
|
||||
| `source` | string | - | 预设来源 URL |
|
||||
| `sourceType` | string | - | 来源类型(`local`/`gist`/`registry`) |
|
||||
| `checksum` | string | - | 内容校验和(SHA256) |
|
||||
|
||||
示例:
|
||||
|
||||
@@ -383,6 +366,14 @@ CCR 引入了强大的动态配置系统,支持:
|
||||
| `Router` | object | 路由配置 |
|
||||
| `transformers` | array | 转换器配置 |
|
||||
| `StatusLine` | object | 状态栏配置 |
|
||||
| `NON_INTERACTIVE_MODE` | boolean | 启用非交互模式(用于 CI/CD) |
|
||||
|
||||
**CLI 专用字段**(这些字段仅在 CLI 模式下有效,服务器不使用):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `noServer` | boolean | 跳过本地服务器启动,直接使用 Provider 的 API |
|
||||
| `claudeCodeSettings` | object | Claude Code 特定设置(环境变量、状态栏等) |
|
||||
|
||||
示例:
|
||||
|
||||
@@ -391,14 +382,14 @@ CCR 引入了强大的动态配置系统,支持:
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai/gpt-4o",
|
||||
"background": "openai/gpt-4o-mini"
|
||||
"default": "openai,gpt-4o",
|
||||
"background": "openai,gpt-4o-mini"
|
||||
},
|
||||
"PORT": 8080
|
||||
}
|
||||
@@ -414,7 +405,6 @@ CCR 引入了强大的动态配置系统,支持:
|
||||
| `template` | object | 配置模板(使用变量引用) |
|
||||
| `configMappings` | array | 配置映射规则 |
|
||||
| `userValues` | object | 用户填写的值(运行时使用) |
|
||||
| `requiredInputs` | array | 必填输入项列表(自动生成) |
|
||||
|
||||
**schema 字段类型:**
|
||||
|
||||
@@ -484,24 +474,16 @@ cat > ~/.claude-code-router/presets/simple-openai/manifest.json << 'EOF'
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
|
||||
"Router": {
|
||||
"default": "openai/gpt-4o",
|
||||
"background": "openai/gpt-4o-mini"
|
||||
},
|
||||
|
||||
"requiredInputs": [
|
||||
{
|
||||
"id": "Providers[0].api_key",
|
||||
"prompt": "Enter OpenAI API Key",
|
||||
"placeholder": "OPENAI_API_KEY"
|
||||
"default": "openai,gpt-4o",
|
||||
"background": "openai,gpt-4o-mini"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
@@ -585,14 +567,14 @@ cat > ~/.claude-code-router/presets/advanced-config/manifest.json << 'EOF'
|
||||
"Providers": [
|
||||
{
|
||||
"name": "#{provider}",
|
||||
"api_base_url": "#{provider === 'openai' ? 'https://api.openai.com/v1' : 'https://api.deepseek.com'}",
|
||||
"api_base_url": "#{provider === 'openai' ? 'https://api.openai.com/v1/chat/completions' : 'https://api.deepseek.com/v1/chat/completions'}",
|
||||
"api_key": "#{apiKey}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "#{provider}/gpt-4o",
|
||||
"background": "#{provider}/gpt-4o-mini"
|
||||
"default": "#{provider},gpt-4o",
|
||||
"background": "#{provider},gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -640,12 +622,6 @@ ccr preset export my-exported-preset \
|
||||
--tags "production,openai"
|
||||
```
|
||||
|
||||
:::tip 分享预设
|
||||
导出的预设目录可以直接分享给他人。接收者可以:
|
||||
- **CLI 方式**:将目录放到 `~/.claude-code-router/presets/`,然后运行 `ccr preset install 预设名`
|
||||
- **Web UI 方式**:将目录上传到 GitHub,然后通过仓库 URL 安装
|
||||
:::
|
||||
|
||||
## 预设文件位置
|
||||
|
||||
预设保存在:
|
||||
@@ -55,7 +55,6 @@ Preset 是一个预定义的配置包,用于快速配置 Claude Code Router。
|
||||
"schema": [...],
|
||||
"template": {...},
|
||||
"configMappings": [...],
|
||||
"requiredInputs": [...],
|
||||
"userValues": {...}
|
||||
}
|
||||
```
|
||||
@@ -113,7 +112,7 @@ Provider 配置数组,定义 LLM 服务提供商。
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"],
|
||||
"transformer": "anthropic",
|
||||
@@ -159,7 +158,7 @@ Provider 配置数组,定义 LLM 服务提供商。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `default` | string | 默认路由(格式:`provider/model`) |
|
||||
| `default` | string | 默认路由(格式:`provider,model`) |
|
||||
| `background` | string | 后台任务路由 |
|
||||
| `think` | string | 思考模式路由 |
|
||||
| `longContext` | string | 长上下文路由 |
|
||||
@@ -550,27 +549,6 @@ userValues 存储用户在安装时填写的值,运行时自动应用。
|
||||
}
|
||||
```
|
||||
|
||||
### requiredInputs(必填输入)
|
||||
|
||||
requiredInputs 是导出预设时自动生成的字段列表,用于提示用户需要填写哪些信息。
|
||||
|
||||
```json
|
||||
{
|
||||
"requiredInputs": [
|
||||
{
|
||||
"id": "Providers[0].api_key",
|
||||
"prompt": "Enter api_key",
|
||||
"placeholder": "OPENAI_API_KEY"
|
||||
},
|
||||
{
|
||||
"id": "PROXY_URL",
|
||||
"prompt": "Enter proxy URL",
|
||||
"placeholder": "PROXY_URL"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 敏感字段处理
|
||||
|
||||
CCR 会自动识别敏感字段(如 `api_key`、`secret`、`password` 等),并将其替换为环境变量占位符。
|
||||
@@ -617,13 +595,6 @@ $VARIABLE_NAME
|
||||
"name": "openai",
|
||||
"api_key": "${OPENAI_API_KEY}"
|
||||
}
|
||||
],
|
||||
"requiredInputs": [
|
||||
{
|
||||
"id": "Providers[0].api_key",
|
||||
"prompt": "Enter api_key",
|
||||
"placeholder": "OPENAI_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -642,7 +613,7 @@ $VARIABLE_NAME
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"models": ["gpt-4o", "gpt-4o-mini"]
|
||||
}
|
||||
@@ -651,15 +622,7 @@ $VARIABLE_NAME
|
||||
"Router": {
|
||||
"default": "openai/gpt-4o",
|
||||
"background": "openai/gpt-4o-mini"
|
||||
},
|
||||
|
||||
"requiredInputs": [
|
||||
{
|
||||
"id": "Providers[0].api_key",
|
||||
"prompt": "Enter OpenAI API Key",
|
||||
"placeholder": "OPENAI_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -806,7 +769,7 @@ $VARIABLE_NAME
|
||||
"Providers": [
|
||||
{
|
||||
"name": "#{primaryProvider}",
|
||||
"api_base_url": "#{primaryProvider === 'openai' ? 'https://api.openai.com/v1' : 'https://api.deepseek.com'}",
|
||||
"api_base_url": "#{primaryProvider === 'openai' ? 'https://api.openai.com/v1/chat/completions' : 'https://api.deepseek.com/v1/chat/completions'}",
|
||||
"api_key": "#{apiKey}",
|
||||
"models": [
|
||||
"#{defaultModel}",
|
||||
|
||||
@@ -106,11 +106,21 @@ const sidebars: SidebarsConfig = {
|
||||
},
|
||||
items: [
|
||||
'server/advanced/custom-router',
|
||||
'server/advanced/presets',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Presets',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'CCR Presets',
|
||||
description: 'Predefined configurations for quick setup',
|
||||
slug: 'category/presets',
|
||||
},
|
||||
items: ['presets/intro'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ async function listPresets(): Promise<void> {
|
||||
const manifest = JSON5.parse(content);
|
||||
|
||||
// Extract metadata fields from manifest
|
||||
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, requiredInputs, ...metadata } = manifest;
|
||||
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, ...metadata } = manifest;
|
||||
|
||||
const name = metadata.name || dirName;
|
||||
const description = metadata.description || '';
|
||||
|
||||
@@ -234,7 +234,7 @@ export const createServer = async (config: any): Promise<any> => {
|
||||
const manifest = JSON.parse(content);
|
||||
|
||||
// Extract metadata fields
|
||||
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, requiredInputs, ...metadata } = manifest;
|
||||
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, ...metadata } = manifest;
|
||||
|
||||
presets.push({
|
||||
id: dirName, // Use directory name as unique identifier
|
||||
|
||||
@@ -26,7 +26,6 @@ export interface ExportResult {
|
||||
presetDir: string;
|
||||
sanitizedConfig: any;
|
||||
metadata: PresetMetadata;
|
||||
requiredInputs: any[];
|
||||
sanitizedCount: number;
|
||||
}
|
||||
|
||||
@@ -41,8 +40,7 @@ export function createManifest(
|
||||
presetName: string,
|
||||
config: any,
|
||||
sanitizedConfig: any,
|
||||
options: ExportOptions,
|
||||
requiredInputs: any[] = []
|
||||
options: ExportOptions
|
||||
): ManifestFile {
|
||||
const metadata: PresetMetadata = {
|
||||
name: presetName,
|
||||
@@ -55,7 +53,6 @@ export function createManifest(
|
||||
return {
|
||||
...metadata,
|
||||
...sanitizedConfig,
|
||||
requiredInputs: options.includeSensitive ? undefined : requiredInputs,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,13 +78,12 @@ export async function exportPreset(
|
||||
};
|
||||
|
||||
// 2. Sanitize configuration
|
||||
const { sanitizedConfig, requiredInputs, sanitizedCount } = await sanitizeConfig(config);
|
||||
const { sanitizedConfig, sanitizedCount } = await sanitizeConfig(config);
|
||||
|
||||
// 3. Generate manifest.json (flattened structure)
|
||||
const manifest: ManifestFile = {
|
||||
...metadata,
|
||||
...sanitizedConfig,
|
||||
requiredInputs: options.includeSensitive ? undefined : requiredInputs,
|
||||
};
|
||||
|
||||
// 4. Create preset directory
|
||||
@@ -114,7 +110,6 @@ export async function exportPreset(
|
||||
presetDir,
|
||||
sanitizedConfig,
|
||||
metadata,
|
||||
requiredInputs,
|
||||
sanitizedCount,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Sensitive field identification and sanitization functionality
|
||||
*/
|
||||
|
||||
import { RequiredInput, SanitizeResult } from './types';
|
||||
import { SanitizeResult } from './types';
|
||||
|
||||
// Sensitive field pattern list
|
||||
const SENSITIVE_PATTERNS = [
|
||||
@@ -88,17 +88,15 @@ function extractEnvVarName(value: string): string | null {
|
||||
* Recursively traverse object to identify and sanitize sensitive fields
|
||||
* @param config Configuration object
|
||||
* @param path Current field path
|
||||
* @param requiredInputs Required inputs array (cumulative)
|
||||
* @param sanitizedCount Sanitized field count
|
||||
*/
|
||||
function sanitizeObject(
|
||||
config: any,
|
||||
path: string = '',
|
||||
requiredInputs: RequiredInput[] = [],
|
||||
sanitizedCount: number = 0
|
||||
): { sanitized: any; requiredInputs: RequiredInput[]; count: number } {
|
||||
): { sanitized: any; count: number } {
|
||||
if (!config || typeof config !== 'object') {
|
||||
return { sanitized: config, requiredInputs, count: sanitizedCount };
|
||||
return { sanitized: config, count: sanitizedCount };
|
||||
}
|
||||
|
||||
if (Array.isArray(config)) {
|
||||
@@ -107,14 +105,12 @@ function sanitizeObject(
|
||||
const result = sanitizeObject(
|
||||
config[i],
|
||||
path ? `${path}[${i}]` : `[${i}]`,
|
||||
requiredInputs,
|
||||
sanitizedCount
|
||||
);
|
||||
sanitizedArray.push(result.sanitized);
|
||||
requiredInputs = result.requiredInputs;
|
||||
sanitizedCount = result.count;
|
||||
}
|
||||
return { sanitized: sanitizedArray, requiredInputs, count: sanitizedCount };
|
||||
return { sanitized: sanitizedArray, count: sanitizedCount };
|
||||
}
|
||||
|
||||
const sanitizedObj: any = {};
|
||||
@@ -126,15 +122,6 @@ function sanitizeObject(
|
||||
// If value is already an environment variable, keep unchanged
|
||||
if (isEnvPlaceholder(value)) {
|
||||
sanitizedObj[key] = value;
|
||||
// Still need to record as required input, but use existing environment variable
|
||||
const envVarName = extractEnvVarName(value);
|
||||
if (envVarName && !requiredInputs.some(input => input.id === currentPath)) {
|
||||
requiredInputs.push({
|
||||
id: currentPath,
|
||||
prompt: `Enter ${key}`,
|
||||
placeholder: envVarName,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Sanitize: replace with environment variable placeholder
|
||||
// Try to infer entity name from path
|
||||
@@ -161,20 +148,12 @@ function sanitizeObject(
|
||||
const envVarName = generateEnvVarName('global', entityName, key);
|
||||
sanitizedObj[key] = `\${${envVarName}}`;
|
||||
|
||||
// Record as required input
|
||||
requiredInputs.push({
|
||||
id: currentPath,
|
||||
prompt: `Enter ${key}`,
|
||||
placeholder: envVarName,
|
||||
});
|
||||
|
||||
sanitizedCount++;
|
||||
}
|
||||
} else if (typeof value === 'object' && value !== null) {
|
||||
// Recursively process nested objects
|
||||
const result = sanitizeObject(value, currentPath, requiredInputs, sanitizedCount);
|
||||
const result = sanitizeObject(value, currentPath, sanitizedCount);
|
||||
sanitizedObj[key] = result.sanitized;
|
||||
requiredInputs = result.requiredInputs;
|
||||
sanitizedCount = result.count;
|
||||
} else {
|
||||
// Keep original value
|
||||
@@ -182,7 +161,7 @@ function sanitizeObject(
|
||||
}
|
||||
}
|
||||
|
||||
return { sanitized: sanitizedObj, requiredInputs, count: sanitizedCount };
|
||||
return { sanitized: sanitizedObj, count: sanitizedCount };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +177,6 @@ export async function sanitizeConfig(config: any): Promise<SanitizeResult> {
|
||||
|
||||
return {
|
||||
sanitizedConfig: result.sanitized,
|
||||
requiredInputs: result.requiredInputs,
|
||||
sanitizedCount: result.count,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -147,6 +147,15 @@ export interface PresetConfigSection {
|
||||
transformers?: TransformerConfig[];
|
||||
StatusLine?: any;
|
||||
NON_INTERACTIVE_MODE?: boolean;
|
||||
|
||||
// CLI-only fields (not used by server)
|
||||
noServer?: boolean; // CLI: Whether to skip local server startup and use provider's API directly
|
||||
claudeCodeSettings?: { // CLI: Claude Code specific settings
|
||||
env?: Record<string, any>; // CLI: Environment variables to pass to Claude Code
|
||||
statusLine?: any; // CLI: Status line configuration
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@@ -244,7 +253,6 @@ export enum MergeStrategy {
|
||||
// Sanitization result
|
||||
export interface SanitizeResult {
|
||||
sanitizedConfig: any;
|
||||
requiredInputs: RequiredInput[];
|
||||
sanitizedCount: number;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user