Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/add-sight-more-preset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@ccman/core': minor
'ccman': minor
---

feat(presets): add Sight More built-in preset

Add the Sight More API relay (`https://2api.sight-more.com`) as a built-in
preset across Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw
(OpenClaw uses the `/v1` suffix, matching the existing GMN convention).
14 changes: 9 additions & 5 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
## ✨ 核心特性

- 🔄 **一键切换**:一条命令切换服务商,自动修改配置文件
- 📦 **内置预设**:提供常用预设(Claude: 1 个,Gemini: 2 个,Codex: 2 个,OpenCode: 1 个,MCP: 多个),只需填写 API Key
- 📦 **内置预设**:提供常用预设(Claude: 1 个,Gemini: 2 个,Codex: 2 个,OpenCode: 1 个,Sight More: 全工具支持,MCP: 多个),只需填写 API Key
- 🛠️ **自定义配置**:支持添加任意第三方服务商
- 🔐 **安全写入**:常规管理命令默认增量更新;GMN/GMN1 等快捷配置命令对所涉及工具执行覆盖式写入
- 🎯 **多工具支持**:同时管理 Codex、Claude Code、Gemini CLI、OpenCode 和 MCP 服务器
Expand Down Expand Up @@ -260,36 +260,40 @@ ccman sync upload --yes

添加服务商时可以选择"使用预设模板",只需填写 API Key:

### Claude Code 预设(3 个)
### Claude Code 预设(4 个)

| 预设名称 | Base URL |
| ------------------ | --------------------------- |
| Anthropic Official | `https://api.anthropic.com` |
| GMN | `https://ai.gmncode.com` |
| GMN1 | `https://gmncode.cn` |
| Sight More | `https://2api.sight-more.com` |

### Gemini CLI 预设(3 个)
### Gemini CLI 预设(4 个)

| 预设名称 | Base URL |
| ----------------------- | ----------------------------- |
| Google Gemini (API Key) | 官方默认 |
| GMN | `https://ai.gmncode.com` |
| GMN1 | `https://gmncode.cn` |
| Sight More | `https://2api.sight-more.com` |

### Codex 预设(3 个)
### Codex 预设(4 个)

| 预设名称 | Base URL |
| --------------- | ----------------------------- |
| OpenAI Official | `https://api.openai.com/v1` |
| GMN | `https://ai.gmncode.com` |
| GMN1 | `https://gmncode.cn` |
| Sight More | `https://2api.sight-more.com` |

### OpenCode 预设(2 个)
### OpenCode 预设(3 个)

| 预设名称 | Base URL |
| -------- | ----------------------------- |
| GMN | `https://ai.gmncode.com` |
| GMN1 | `https://gmncode.cn` |
| Sight More | `https://2api.sight-more.com` |

### MCP 预设(多个)

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/presets/claude.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createDualGmnPresets } from './gmn.js'
import { createSightPreset } from './sight.js'

/**
* Claude Code 预设模板(不包含 API Key 和 isBuiltIn)
Expand All @@ -23,4 +24,5 @@ export const CC_PRESETS: PresetTemplate[] = [
description: 'Anthropic 官方 API',
},
...createDualGmnPresets(),
...createSightPreset(),
]
2 changes: 2 additions & 0 deletions packages/core/src/presets/codex.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createDualGmnPresets } from './gmn.js'
import { createSightPreset } from './sight.js'

/**
* Codex 预设模板(不包含 API Key 和 isBuiltIn)
Expand All @@ -23,4 +24,5 @@ export const CODEX_PRESETS: PresetTemplate[] = [
description: 'OpenAI 官方 API',
},
...createDualGmnPresets(),
...createSightPreset(),
]
2 changes: 2 additions & 0 deletions packages/core/src/presets/gemini.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { InternalPresetTemplate } from '../tool-manager.types.js'
import { createDualGmnPresets } from './gmn.js'
import { createSightPreset } from './sight.js'

/**
* Gemini CLI 预置服务商
Expand All @@ -16,4 +17,5 @@ export const GEMINI_PRESETS: InternalPresetTemplate[] = [
description: '使用官方 Gemini API(通过 GEMINI_API_KEY 或 GOOGLE_API_KEY 认证)',
},
...createDualGmnPresets(),
...createSightPreset(),
]
2 changes: 2 additions & 0 deletions packages/core/src/presets/openclaw.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { InternalPresetTemplate } from '../tool-manager.types.js'
import { createDualGmnPresets } from './gmn.js'
import { createSightPreset } from './sight.js'

/**
* OpenClaw 预置服务商
*/
export const OPENCLAW_PRESETS: InternalPresetTemplate[] = [
...createDualGmnPresets((baseUrl) => `${baseUrl}/v1`),
...createSightPreset((baseUrl) => `${baseUrl}/v1`),
]
6 changes: 5 additions & 1 deletion packages/core/src/presets/opencode.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { InternalPresetTemplate } from '../tool-manager.types.js'
import { createDualGmnPresets } from './gmn.js'
import { createSightPreset } from './sight.js'

/**
* OpenCode 预置服务商
*/
export const OPENCODE_PRESETS: InternalPresetTemplate[] = [...createDualGmnPresets()]
export const OPENCODE_PRESETS: InternalPresetTemplate[] = [
...createDualGmnPresets(),
...createSightPreset(),
]
26 changes: 26 additions & 0 deletions packages/core/src/presets/sight.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from 'vitest'
import { CC_PRESETS } from './claude.js'
import { CODEX_PRESETS } from './codex.js'
import { GEMINI_PRESETS } from './gemini.js'
import { OPENCODE_PRESETS } from './opencode.js'
import { OPENCLAW_PRESETS } from './openclaw.js'
import { SIGHT_MORE_ROOT_URL } from './sight.js'

function getPresetBaseUrl(
presets: Array<{ name: string; baseUrl: string }>,
name: string
): string | undefined {
return presets.find((preset) => preset.name === name)?.baseUrl
}

describe('Sight More built-in preset', () => {
it('should expose Sight More for Claude/Codex/Gemini/OpenCode with root URL', () => {
for (const presets of [CC_PRESETS, CODEX_PRESETS, GEMINI_PRESETS, OPENCODE_PRESETS]) {
expect(getPresetBaseUrl(presets, 'Sight More')).toBe(SIGHT_MORE_ROOT_URL)
}
})

it('should expose Sight More for OpenClaw with /v1 URL', () => {
expect(getPresetBaseUrl(OPENCLAW_PRESETS, 'Sight More')).toBe(`${SIGHT_MORE_ROOT_URL}/v1`)
})
})
29 changes: 29 additions & 0 deletions packages/core/src/presets/sight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const SIGHT_MORE_ROOT_URL = 'https://2api.sight-more.com'

interface SightPresetTemplate {
name: string
baseUrl: string
description: string
}

type BaseUrlTransformer = (baseUrl: string) => string

/**
* 创建 Sight More 预设
*
* Sight More 是一个多协议 API 中转服务,同一域名同时兼容
* Anthropic(Claude Code)、OpenAI(Codex / OpenCode)与 Gemini 协议。
*
* @param transformBaseUrl 可选的 Base URL 变换函数(例如 OpenClaw 需要追加 /v1)
*/
export function createSightPreset(
transformBaseUrl: BaseUrlTransformer = (baseUrl) => baseUrl
): SightPresetTemplate[] {
return [
{
name: 'Sight More',
baseUrl: transformBaseUrl(SIGHT_MORE_ROOT_URL),
description: 'Sight More API 中转服务 (2api.sight-more.com)',
},
]
}