@simonyea/holysheep-cli 1.7.16 → 1.7.18

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 CHANGED
@@ -73,7 +73,6 @@ You'll be prompted for your API Key (`cr_xxx`), then select the tools to configu
73
73
  4. Open the exact dashboard URL shown in the terminal and start chatting — do not use a blank browser shell or `about:blank`
74
74
 
75
75
  **Default OpenClaw model:** `gpt-5.4`
76
- HolySheep keeps GPT as the OpenClaw primary model by default and leaves Claude models available for manual switching inside OpenClaw.
77
76
 
78
77
  > **Keep the gateway window open** while using OpenClaw. The gateway must be running for the browser UI to work.
79
78
  > If only `npx openclaw` is available, HolySheep will start Gateway as a direct process and will not install a persistent daemon from a temporary `npx` cache path.
@@ -163,7 +162,6 @@ hs setup
163
162
  4. 按终端里显示的准确 dashboard 地址打开浏览器,直接开始聊天,不要打开空白浏览器壳窗口或 `about:blank`
164
163
 
165
164
  **OpenClaw 默认模型:** `gpt-5.4`
166
- HolySheep 会默认把 GPT 设为 OpenClaw 主模型,同时保留 Claude 模型供你在 OpenClaw 内手动切换。
167
165
 
168
166
  > ⚠️ **保持 Gateway 窗口开启**,关闭后 Gateway 停止,浏览器界面无法使用。
169
167
  > 如果机器上只有 `npx openclaw`,HolySheep 会直接启动 Gateway 进程,不会把 daemon 安装到临时 `npx` 缓存路径上。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "1.7.16",
3
+ "version": "1.7.18",
4
4
  "description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
5
5
  "keywords": [
6
6
  "openai-china",
@@ -143,6 +143,13 @@ function printOpenClawDetails(tool, installState, nodeMajor) {
143
143
  })
144
144
  }
145
145
 
146
+ if (bridgePort && bridgePort === gatewayPort) {
147
+ details.push({
148
+ level: 'warn',
149
+ text: `Bridge 端口和 Gateway 端口都被配置成了 ${gatewayPort};这会让 OpenClaw provider 请求打回 Gateway 自己并触发 404`,
150
+ })
151
+ }
152
+
146
153
  if (launchAgent?.unstable) {
147
154
  details.push({
148
155
  level: 'warn',
@@ -82,19 +82,6 @@ function getPreferredLaunchCmd(tool) {
82
82
  return tool.launchCmd.replace(/^hs\b/, prefix)
83
83
  }
84
84
 
85
- function pickPrimaryModelForTool(tool, selectedModels) {
86
- const models = Array.isArray(selectedModels) ? selectedModels : []
87
- const fallback = models[0] || 'gpt-5.4'
88
-
89
- if (tool?.id === 'openclaw') {
90
- return models.find((m) => m === 'gpt-5.4')
91
- || models.find((m) => m.startsWith('gpt-'))
92
- || fallback
93
- }
94
-
95
- return models.find((m) => m.startsWith('claude-')) || fallback
96
- }
97
-
98
85
  function canAutoInstall(toolId) {
99
86
  return !!AUTO_INSTALL[toolId]
100
87
  }
@@ -212,6 +199,7 @@ async function setup(options) {
212
199
  choices: MODEL_CHOICES,
213
200
  pageSize: 5,
214
201
  }])
202
+ const primaryModel = selectedModels.find(m => m.startsWith('claude-')) || selectedModels[0] || 'claude-sonnet-4-6'
215
203
 
216
204
  // Step 2: 选择工具(已安装 + 未安装分组显示)
217
205
  const installedTools = TOOLS.filter(t => t.checkInstalled())
@@ -304,7 +292,6 @@ async function setup(options) {
304
292
  for (const tool of toConfigureTools) {
305
293
  const spinner = ora(`配置 ${tool.name}...`).start()
306
294
  try {
307
- const primaryModel = pickPrimaryModelForTool(tool, selectedModels)
308
295
  const result = tool.configure(apiKey, BASE_URL_ANTHROPIC, BASE_URL_OPENAI, primaryModel, selectedModels)
309
296
 
310
297
  if (result.manual) {
@@ -613,9 +613,8 @@ async function checkGatewayHealth(config) {
613
613
 
614
614
  try {
615
615
  const response = await fetch(`http://${host}:${gatewayPort}/`, { method: 'GET', timeout })
616
- return response.ok
617
- ? { ok: true, reason: 'gateway_http_ok' }
618
- : { ok: false, reason: `gateway_http_${response.status}` }
616
+ // 任何 HTTP 响应都说明 Gateway 进程存活(4xx 可能是正常的路由/auth 行为)
617
+ return { ok: true, reason: `gateway_http_${response.status}` }
619
618
  } catch {
620
619
  return { ok: false, reason: 'gateway_http_unreachable' }
621
620
  }
@@ -311,9 +311,11 @@ function listPortListeners(port) {
311
311
  }
312
312
  }
313
313
 
314
- function findAvailableGatewayPort(startPort = DEFAULT_GATEWAY_PORT) {
314
+ function findAvailableGatewayPort(startPort = DEFAULT_GATEWAY_PORT, excludedPorts = []) {
315
+ const excluded = new Set((excludedPorts || []).map((value) => Number(value)).filter((value) => Number.isInteger(value) && value > 0))
315
316
  for (let offset = 0; offset < MAX_PORT_SCAN; offset++) {
316
317
  const port = startPort + offset
318
+ if (excluded.has(port)) continue
317
319
  if (!isPortInUse(port)) return port
318
320
  }
319
321
  return null
@@ -616,7 +618,7 @@ module.exports = {
616
618
  }
617
619
  this._lastGatewayPort = gatewayPort
618
620
 
619
- const bridgePort = findAvailableGatewayPort(DEFAULT_BRIDGE_PORT)
621
+ const bridgePort = findAvailableGatewayPort(DEFAULT_BRIDGE_PORT, [gatewayPort])
620
622
  if (!bridgePort) {
621
623
  throw new Error(`找不到可用桥接端口(已检查 ${DEFAULT_BRIDGE_PORT}-${DEFAULT_BRIDGE_PORT + MAX_PORT_SCAN - 1})`)
622
624
  }
@@ -11,7 +11,7 @@
11
11
  * "provider": {
12
12
  * "anthropic": {
13
13
  * "options": {
14
- * "baseURL": "https://api.holysheep.ai",
14
+ * "baseURL": "https://api.holysheep.ai/v1",
15
15
  * "apiKey": "cr_xxx"
16
16
  * }
17
17
  * },
@@ -26,6 +26,8 @@
26
26
  *
27
27
  * 安装方式(推荐): brew install anomalyco/tap/opencode
28
28
  * 或: npm i -g opencode-ai@latest
29
+ * 说明:OpenCode 的 anthropic provider 会自行拼接 /messages,
30
+ * 因此这里必须写 /v1 基地址,最终才会落到 /v1/messages。
29
31
  * 官方文档: https://opencode.ai/docs/config
30
32
  */
31
33
  const fs = require('fs')
@@ -88,10 +90,10 @@ module.exports = {
88
90
  // 设置 schema(方便编辑器自动补全)
89
91
  if (!config['$schema']) config['$schema'] = 'https://opencode.ai/config.json'
90
92
 
91
- // 配置 Anthropic provider(Claude 模型)
93
+ // OpenCode anthropic provider 需要 /v1 基地址,否则会打到 /messages 并返回 404。
92
94
  config.provider.anthropic = {
93
95
  options: {
94
- baseURL: baseUrlAnthropicNoV1, // https://api.holysheep.ai ( /v1)
96
+ baseURL: `${String(baseUrlAnthropicNoV1 || '').replace(/\/+$/, '')}/v1`,
95
97
  apiKey,
96
98
  },
97
99
  }