@simonyea/holysheep-cli 1.7.92 → 1.7.94

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "1.7.92",
3
+ "version": "1.7.94",
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",
@@ -12,11 +12,13 @@
12
12
  * [model_providers.holysheep]
13
13
  * name = "HolySheep"
14
14
  * base_url = "https://api.holysheep.ai/v1"
15
- * env_key = "HOLYSHEEP_API_KEY"
16
15
  * wire_api = "responses"
17
16
  *
18
- * 注意:Codex RS 不支持 api_key 字段!必须用 env_key 指向环境变量。
19
- * 注意:旧的 config.json 会被 Rust Codex 忽略!
17
+ * [model_providers.holysheep.http_headers]
18
+ * Authorization = "Bearer cr_xxx"
19
+ *
20
+ * 注意:Codex RS 不支持 api_key 字段,env_key 需要环境变量(Windows 需重启终端)。
21
+ * 改用 http_headers 直接设置 Authorization header,配置即生效。
20
22
  */
21
23
  const fs = require('fs')
22
24
  const path = require('path')
@@ -48,7 +50,8 @@ function stripManagedTomlConfig(content) {
48
50
  const trimmed = line.trim()
49
51
 
50
52
  if (/^\[[^\]]+\]$/.test(trimmed)) {
51
- if (trimmed === '[model_providers.holysheep]') {
53
+ if (trimmed === '[model_providers.holysheep]' ||
54
+ trimmed === '[model_providers.holysheep.http_headers]') {
52
55
  currentSection = trimmed
53
56
  skipHolySheepBlock = true
54
57
  continue
@@ -96,7 +99,7 @@ function isConfiguredInToml() {
96
99
  /**
97
100
  * 写入 TOML config(合并方式:保留已有内容,只更新 holysheep 部分)
98
101
  */
99
- function writeTomlConfig(_apiKey, baseUrlOpenAI, model) {
102
+ function writeTomlConfig(apiKey, baseUrlOpenAI, model) {
100
103
  if (!fs.existsSync(CONFIG_DIR)) {
101
104
  fs.mkdirSync(CONFIG_DIR, { recursive: true })
102
105
  }
@@ -104,6 +107,7 @@ function writeTomlConfig(_apiKey, baseUrlOpenAI, model) {
104
107
  const content = stripManagedTomlConfig(readTomlConfig())
105
108
 
106
109
  // 在开头插入 holysheep 配置
110
+ // 使用 http_headers 直接设置 Authorization,不依赖环境变量
107
111
  const newConfig = [
108
112
  `model = "${model || 'gpt-5.4'}"`,
109
113
  `model_provider = "holysheep"`,
@@ -113,9 +117,11 @@ function writeTomlConfig(_apiKey, baseUrlOpenAI, model) {
113
117
  `[model_providers.holysheep]`,
114
118
  `name = "HolySheep"`,
115
119
  `base_url = "${baseUrlOpenAI}"`,
116
- `env_key = "HOLYSHEEP_API_KEY"`,
117
120
  `wire_api = "responses"`,
118
121
  '',
122
+ `[model_providers.holysheep.http_headers]`,
123
+ `Authorization = "Bearer ${apiKey}"`,
124
+ '',
119
125
  ].join('\n')
120
126
 
121
127
  fs.writeFileSync(CONFIG_FILE, cleanupToml(newConfig) + '\n', 'utf8')
@@ -194,14 +200,9 @@ module.exports = {
194
200
  // 清除 auth.json 中的 ChatGPT OAuth 认证,避免干扰
195
201
  neutralizeAuthJson()
196
202
 
197
- // 写入 HOLYSHEEP_API_KEY 环境变量(Codex RS 通过 env_key 读取)
198
- const { writeEnvToShell } = require('../utils/shell')
199
- writeEnvToShell({ HOLYSHEEP_API_KEY: apiKey })
200
-
201
203
  return {
202
204
  file: CONFIG_FILE,
203
205
  hot: false,
204
- envVars: { HOLYSHEEP_API_KEY: apiKey },
205
206
  }
206
207
  },
207
208
  reset() {
@@ -227,11 +228,6 @@ module.exports = {
227
228
  fs.writeFileSync(CONFIG_FILE_JSON, JSON.stringify(c, null, 2), 'utf8')
228
229
  } catch {}
229
230
  }
230
- // 清理环境变量
231
- try {
232
- const { removeEnvFromShell } = require('../utils/shell')
233
- removeEnvFromShell(['HOLYSHEEP_API_KEY'])
234
- } catch {}
235
231
  },
236
232
  getConfigPath() { return CONFIG_FILE },
237
233
  hint: '切换后重开终端生效;Rust Codex (v0.111+) 使用 config.toml',
@@ -773,6 +773,27 @@ module.exports = {
773
773
  getConfigPath() { return CONFIG_FILE },
774
774
  getBridgePort() { return getConfiguredBridgePort() },
775
775
  getGatewayPort() { return getConfiguredGatewayPort() },
776
+ ensureBridgeRunning(port) {
777
+ port = port || getConfiguredBridgePort()
778
+ return startBridge(port)
779
+ },
780
+ ensureGatewayRunning(port) {
781
+ port = port || getConfiguredGatewayPort()
782
+ // 先检查是否已在运行
783
+ try {
784
+ execSync(
785
+ isWin
786
+ ? `powershell -NonInteractive -Command "try{(Invoke-WebRequest -Uri http://127.0.0.1:${port}/ -TimeoutSec 1 -UseBasicParsing).StatusCode}catch{exit 1}"`
787
+ : `curl -sf http://127.0.0.1:${port}/ -o /dev/null --max-time 1`,
788
+ { stdio: 'ignore', timeout: 3000 }
789
+ )
790
+ return true
791
+ } catch {}
792
+ // 未运行,启动它
793
+ const preferNpx = !hasOpenClawBinary()
794
+ const result = _startGateway(port, preferNpx, !preferNpx)
795
+ return result.ok
796
+ },
776
797
  getPrimaryModel() { return getConfiguredPrimaryModel() },
777
798
  getPrimaryModelRoute() { return getPrimaryModelRoute() },
778
799
  getPortListeners(port = getConfiguredGatewayPort()) { return listPortListeners(port) },
@@ -654,10 +654,21 @@ async function handleToolLaunch(req, res) {
654
654
  const tool = TOOLS.find(t => t.id === toolId)
655
655
  if (!tool) return json(res, { error: '未知工具' }, 400)
656
656
 
657
- // OpenClaw: 打开浏览器 dashboard 而非终端
657
+ // OpenClaw: 先启动 Bridge + Gateway,再打开浏览器
658
658
  if (toolId === 'openclaw') {
659
- const port = tool.getGatewayPort?.() || 18789
660
- const url = `http://127.0.0.1:${port}/`
659
+ const gatewayPort = tool.getGatewayPort?.() || 18789
660
+ const bridgePort = tool.getBridgePort?.() || 18788
661
+
662
+ // 确保 Bridge 在运行
663
+ const bridgeUp = tool.ensureBridgeRunning?.(bridgePort)
664
+ // 确保 Gateway 在运行
665
+ const gatewayUp = tool.ensureGatewayRunning?.(gatewayPort)
666
+
667
+ if (!gatewayUp) {
668
+ return json(res, { ok: false, error: 'Gateway 启动失败,请先运行 hs setup 配置 OpenClaw' }, 500)
669
+ }
670
+
671
+ const url = `http://127.0.0.1:${gatewayPort}/`
661
672
  if (process.platform === 'darwin') spawn('open', [url], { detached: true, stdio: 'ignore' }).unref()
662
673
  else if (process.platform === 'win32') spawn('cmd.exe', ['/c', 'start', '', url], { detached: true, stdio: 'ignore', shell: true }).unref()
663
674
  else spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref()