@simonyea/holysheep-cli 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/commands/setup.js +12 -15
- package/src/tools/openclaw.js +75 -48
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ Instead of manually editing config files and environment variables for each tool
|
|
|
41
41
|
| [Aider](https://aider.chat) | `pip install aider-install && aider-install` | `~/.aider.conf.yml` | ✅ Auto |
|
|
42
42
|
| [Continue.dev](https://continue.dev) | VS Code marketplace | `~/.continue/config.yaml` | ✅ Auto |
|
|
43
43
|
| [OpenCode](https://opencode.ai) | `brew install anomalyco/tap/opencode` | `~/.config/opencode/opencode.json` | ✅ Auto |
|
|
44
|
-
| [OpenClaw](https://github.com/
|
|
44
|
+
| [OpenClaw](https://github.com/openclaw/openclaw) | `npm i -g openclaw@latest` | `~/.openclaw/openclaw.json` | ✅ Auto |
|
|
45
45
|
| [Cursor](https://cursor.sh) | Download from website | GUI only (encrypted storage) | ⚠️ Manual |
|
|
46
46
|
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `npm i -g @google/gemini-cli` | Google protocol only | ❌ Not supported |
|
|
47
47
|
|
|
@@ -135,7 +135,7 @@ HolySheep 是面向中国开发者的 Claude/GPT/Gemini 官方 API 中转服务
|
|
|
135
135
|
| [Aider](https://aider.chat) | `pip install aider-install && aider-install` | `~/.aider.conf.yml` | ✅ 自动 |
|
|
136
136
|
| [Continue.dev](https://continue.dev) | VS Code 插件市场 | `~/.continue/config.yaml` | ✅ 自动 |
|
|
137
137
|
| [OpenCode](https://opencode.ai) | `brew install anomalyco/tap/opencode` | `~/.config/opencode/opencode.json` | ✅ 自动 |
|
|
138
|
-
| [OpenClaw](https://github.com/
|
|
138
|
+
| [OpenClaw](https://github.com/openclaw/openclaw) | `npm i -g openclaw@latest` | `~/.openclaw/openclaw.json` | ✅ 自动 |
|
|
139
139
|
| [Cursor](https://cursor.sh) | 官网下载 | GUI 手动配置(加密存储) | ⚠️ 手动 |
|
|
140
140
|
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `npm i -g @google/gemini-cli` | 仅支持 Google 官方协议 | ❌ 不支持 |
|
|
141
141
|
|
package/package.json
CHANGED
package/src/commands/setup.js
CHANGED
|
@@ -15,6 +15,7 @@ const AUTO_INSTALL = {
|
|
|
15
15
|
'codex': { cmd: 'npm install -g @openai/codex', mgr: 'npm' },
|
|
16
16
|
'gemini-cli': { cmd: 'npm install -g @google/gemini-cli', mgr: 'npm' },
|
|
17
17
|
'opencode': { cmd: 'npm install -g opencode-ai', mgr: 'npm' },
|
|
18
|
+
'openclaw': { cmd: 'npm install -g openclaw@latest', mgr: 'npm' },
|
|
18
19
|
'aider': { cmd: 'pip install aider-chat', mgr: 'pip' },
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -44,19 +45,13 @@ async function tryAutoInstall(tool) {
|
|
|
44
45
|
spinner.fail(`安装失败,请手动运行: ${chalk.cyan(info.cmd)}`)
|
|
45
46
|
return false
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// 安装后重新检测
|
|
53
|
-
if (tool.checkInstalled()) {
|
|
54
|
-
spinner.succeed(`${tool.name} 安装成功`)
|
|
55
|
-
return true
|
|
56
|
-
} else {
|
|
57
|
-
spinner.fail(`${tool.name} 安装后仍未检测到,请手动安装: ${chalk.cyan(info.cmd)}`)
|
|
58
|
-
return false
|
|
48
|
+
spinner.succeed(`${tool.name} 安装成功`)
|
|
49
|
+
// Windows PATH 在当前进程内不会刷新,但安装已成功,直接继续配置
|
|
50
|
+
// 非 Windows 再额外做一次检测
|
|
51
|
+
if (process.platform !== 'win32' && !tool.checkInstalled()) {
|
|
52
|
+
console.log(chalk.yellow(` ⚠ 安装后未检测到命令,尝试直接配置...`))
|
|
59
53
|
}
|
|
54
|
+
return true // 安装成功就视为可配置
|
|
60
55
|
} catch (e) {
|
|
61
56
|
spinner.fail(`安装失败: ${e.message}`)
|
|
62
57
|
return false
|
|
@@ -137,6 +132,7 @@ async function setup(options) {
|
|
|
137
132
|
const selectedTools = TOOLS.filter(t => toolIds.includes(t.id))
|
|
138
133
|
const needInstall = selectedTools.filter(t => !t.checkInstalled() && canAutoInstall(t.id))
|
|
139
134
|
const cantInstall = selectedTools.filter(t => !t.checkInstalled() && !canAutoInstall(t.id))
|
|
135
|
+
const justInstalled = new Set() // 记录本次刚安装成功的工具 id
|
|
140
136
|
|
|
141
137
|
// 提示不能自动安装的工具
|
|
142
138
|
if (cantInstall.length) {
|
|
@@ -156,16 +152,17 @@ async function setup(options) {
|
|
|
156
152
|
|
|
157
153
|
if (doInstall) {
|
|
158
154
|
for (const tool of needInstall) {
|
|
159
|
-
await tryAutoInstall(tool)
|
|
155
|
+
const ok = await tryAutoInstall(tool)
|
|
156
|
+
if (ok) justInstalled.add(tool.id)
|
|
160
157
|
}
|
|
161
158
|
console.log()
|
|
162
159
|
}
|
|
163
160
|
}
|
|
164
161
|
|
|
165
|
-
// Step 4:
|
|
162
|
+
// Step 4: 配置每个已安装的工具(包含刚刚安装成功的)
|
|
166
163
|
const envVarsToWrite = {}
|
|
167
164
|
const results = []
|
|
168
|
-
const toConfigureTools = selectedTools.filter(t => t.checkInstalled())
|
|
165
|
+
const toConfigureTools = selectedTools.filter(t => t.checkInstalled() || justInstalled.has(t.id))
|
|
169
166
|
|
|
170
167
|
if (toConfigureTools.length === 0) {
|
|
171
168
|
console.log(chalk.yellow('没有可配置的工具(请先安装),退出。'))
|
package/src/tools/openclaw.js
CHANGED
|
@@ -1,43 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenClaw 适配器
|
|
3
|
-
* OpenClaw 是基于 Claude Code 架构的开源 AI 编程助手
|
|
4
|
-
* 配置方式与 Claude Code 几乎相同,使用 Anthropic API 格式
|
|
2
|
+
* OpenClaw 适配器 (github.com/openclaw/openclaw)
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* OpenClaw 是个人 AI 助手 + 多渠道消息网关
|
|
5
|
+
* 支持 WhatsApp/Telegram/Signal/Discord/iMessage 等 20+ 渠道
|
|
8
6
|
*
|
|
9
|
-
*
|
|
7
|
+
* 安装方式: npm install -g openclaw@latest
|
|
8
|
+
* 配置文件: ~/.openclaw/openclaw.json (JSON5 格式)
|
|
9
|
+
* 文档: https://docs.openclaw.ai
|
|
10
|
+
*
|
|
11
|
+
* HolySheep 接入方式:通过 env.ANTHROPIC_API_KEY + env.ANTHROPIC_BASE_URL
|
|
12
|
+
* 设置 Anthropic provider 自定义 base URL 指向 HolySheep 中继
|
|
10
13
|
*/
|
|
11
|
-
const fs
|
|
14
|
+
const fs = require('fs')
|
|
12
15
|
const path = require('path')
|
|
13
|
-
const os
|
|
16
|
+
const os = require('os')
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const openclaw = path.join(os.homedir(), '.openclaw', 'settings.json')
|
|
18
|
-
const claude = path.join(os.homedir(), '.claude', 'settings.json')
|
|
19
|
-
if (fs.existsSync(openclaw)) return openclaw
|
|
20
|
-
// 检查是否安装了 openclaw
|
|
21
|
-
try {
|
|
22
|
-
require('child_process').execSync('which openclaw', { stdio: 'ignore' })
|
|
23
|
-
return openclaw
|
|
24
|
-
} catch {
|
|
25
|
-
return openclaw // 默认路径
|
|
26
|
-
}
|
|
27
|
-
}
|
|
18
|
+
const OPENCLAW_DIR = path.join(os.homedir(), '.openclaw')
|
|
19
|
+
const CONFIG_FILE = path.join(OPENCLAW_DIR, 'openclaw.json')
|
|
28
20
|
|
|
29
|
-
function
|
|
21
|
+
function readConfig() {
|
|
30
22
|
try {
|
|
31
|
-
if (fs.existsSync(
|
|
32
|
-
|
|
23
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
24
|
+
// openclaw.json 是 JSON5 格式,先去掉注释再 parse
|
|
25
|
+
const raw = fs.readFileSync(CONFIG_FILE, 'utf8')
|
|
26
|
+
return JSON.parse(raw.replace(/\/\/[^\n]*/g, '').replace(/\/\*[\s\S]*?\*\//g, ''))
|
|
33
27
|
}
|
|
34
28
|
} catch {}
|
|
35
29
|
return {}
|
|
36
30
|
}
|
|
37
31
|
|
|
38
|
-
function
|
|
39
|
-
fs.mkdirSync(
|
|
40
|
-
fs.writeFileSync(
|
|
32
|
+
function writeConfig(data) {
|
|
33
|
+
fs.mkdirSync(OPENCLAW_DIR, { recursive: true })
|
|
34
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8')
|
|
41
35
|
}
|
|
42
36
|
|
|
43
37
|
module.exports = {
|
|
@@ -47,30 +41,63 @@ module.exports = {
|
|
|
47
41
|
return require('../utils/which').commandExists('openclaw')
|
|
48
42
|
},
|
|
49
43
|
isConfigured() {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
const c = readConfig()
|
|
45
|
+
return !!(
|
|
46
|
+
c.env?.ANTHROPIC_BASE_URL?.includes('holysheep') ||
|
|
47
|
+
c.models?.providers?.holysheep
|
|
48
|
+
)
|
|
53
49
|
},
|
|
54
|
-
configure(apiKey, baseUrlAnthropicNoV1) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
51
|
+
const config = readConfig()
|
|
52
|
+
|
|
53
|
+
// 设置环境变量 — Anthropic provider 使用 ANTHROPIC_BASE_URL 覆盖默认地址
|
|
54
|
+
if (!config.env) config.env = {}
|
|
55
|
+
config.env.ANTHROPIC_API_KEY = apiKey
|
|
56
|
+
config.env.ANTHROPIC_BASE_URL = baseUrlAnthropicNoV1 // https://api.holysheep.ai
|
|
57
|
+
|
|
58
|
+
// 设置默认模型(如果未配置)
|
|
59
|
+
if (!config.agents) config.agents = {}
|
|
60
|
+
if (!config.agents.defaults) config.agents.defaults = {}
|
|
61
|
+
if (!config.agents.defaults.model) {
|
|
62
|
+
config.agents.defaults.model = { primary: 'anthropic/claude-sonnet-4-5' }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 同时注册一个 holysheep 自定义 provider(支持所有模型)
|
|
66
|
+
if (!config.models) config.models = {}
|
|
67
|
+
config.models.mode = 'merge'
|
|
68
|
+
if (!config.models.providers) config.models.providers = {}
|
|
69
|
+
config.models.providers.holysheep = {
|
|
70
|
+
baseUrl: baseUrlOpenAI, // https://api.holysheep.ai/v1
|
|
71
|
+
apiKey,
|
|
72
|
+
api: 'openai-completions',
|
|
73
|
+
models: [
|
|
74
|
+
{ id: 'claude-sonnet-4-5', name: 'Claude Sonnet 4.5 (HolySheep)' },
|
|
75
|
+
{ id: 'claude-opus-4-5', name: 'Claude Opus 4.5 (HolySheep)' },
|
|
76
|
+
{ id: 'gpt-5.4', name: 'GPT-5.4 (HolySheep)' },
|
|
77
|
+
{ id: 'gpt-5', name: 'GPT-5 (HolySheep)' },
|
|
78
|
+
],
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
writeConfig(config)
|
|
82
|
+
return { file: CONFIG_FILE, hot: false }
|
|
62
83
|
},
|
|
63
84
|
reset() {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
delete
|
|
68
|
-
|
|
85
|
+
const config = readConfig()
|
|
86
|
+
if (config.env) {
|
|
87
|
+
delete config.env.ANTHROPIC_API_KEY
|
|
88
|
+
delete config.env.ANTHROPIC_BASE_URL
|
|
89
|
+
}
|
|
90
|
+
if (config.models?.providers) {
|
|
91
|
+
delete config.models.providers.holysheep
|
|
92
|
+
}
|
|
93
|
+
// 如果默认模型是 anthropic/xxx,清掉
|
|
94
|
+
if (config.agents?.defaults?.model?.primary?.startsWith('anthropic/')) {
|
|
95
|
+
delete config.agents.defaults.model
|
|
69
96
|
}
|
|
70
|
-
|
|
97
|
+
writeConfig(config)
|
|
71
98
|
},
|
|
72
|
-
getConfigPath() { return
|
|
73
|
-
hint: '
|
|
74
|
-
installCmd: '
|
|
75
|
-
docsUrl: 'https://
|
|
99
|
+
getConfigPath() { return CONFIG_FILE },
|
|
100
|
+
hint: '切换后重启 OpenClaw 生效;支持 /model 命令切换模型',
|
|
101
|
+
installCmd: 'npm install -g openclaw@latest',
|
|
102
|
+
docsUrl: 'https://docs.openclaw.ai',
|
|
76
103
|
}
|