@simonyea/holysheep-cli 1.7.34 → 1.7.36

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.34",
3
+ "version": "1.7.36",
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",
@@ -45,7 +45,63 @@ function waitForPort(checkFn, maxTries, intervalMs) {
45
45
  return false
46
46
  }
47
47
 
48
+ function killBridge(port) {
49
+ const listeners = openclawTool.getPortListeners(port)
50
+ let killed = 0
51
+ for (const item of listeners) {
52
+ const pid = parseInt(item.pid, 10)
53
+ if (!pid) continue
54
+ try {
55
+ if (isWin) {
56
+ spawnSync('taskkill', ['/PID', String(pid), '/F'], { stdio: 'ignore', shell: true })
57
+ } else {
58
+ process.kill(pid, 'SIGTERM')
59
+ }
60
+ killed++
61
+ } catch {}
62
+ }
63
+ return killed
64
+ }
65
+
66
+ function waitPortFree(port, maxTries, intervalMs) {
67
+ for (let i = 0; i < maxTries; i++) {
68
+ if (openclawTool.getPortListeners(port).length === 0) return true
69
+ const t0 = Date.now()
70
+ while (Date.now() - t0 < intervalMs) {}
71
+ }
72
+ return openclawTool.getPortListeners(port).length === 0
73
+ }
74
+
75
+ function findChrome() {
76
+ const { existsSync } = require('fs')
77
+ if (process.platform === 'darwin') {
78
+ const p = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
79
+ return existsSync(p) ? p : null
80
+ }
81
+ if (isWin) {
82
+ const candidates = [
83
+ process.env.LOCALAPPDATA && `${process.env.LOCALAPPDATA}\\Google\\Chrome\\Application\\chrome.exe`,
84
+ process.env.PROGRAMFILES && `${process.env.PROGRAMFILES}\\Google\\Chrome\\Application\\chrome.exe`,
85
+ process.env['PROGRAMFILES(X86)'] && `${process.env['PROGRAMFILES(X86)']}\\Google\\Chrome\\Application\\chrome.exe`,
86
+ ].filter(Boolean)
87
+ return candidates.find(existsSync) || null
88
+ }
89
+ for (const bin of ['google-chrome', 'chromium-browser', 'chromium']) {
90
+ try { execSync(`which ${bin}`, { stdio: 'ignore' }); return bin } catch {}
91
+ }
92
+ return null
93
+ }
94
+
48
95
  function openBrowser(url) {
96
+ const chrome = findChrome()
97
+ if (chrome) {
98
+ spawn(chrome, ['--disable-gpu', '--disable-gpu-sandbox', url], {
99
+ detached: true,
100
+ stdio: 'ignore',
101
+ shell: false,
102
+ }).unref()
103
+ return
104
+ }
49
105
  const cmd = isWin ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open'
50
106
  try {
51
107
  spawn(cmd, [url], { detached: true, stdio: 'ignore', shell: isWin }).unref()
@@ -79,28 +135,32 @@ async function openclaw() {
79
135
  const bridgePort = openclawTool.getBridgePort()
80
136
  const gatewayPort = openclawTool.getGatewayPort()
81
137
 
82
- // 确保 Bridge 运行
83
- if (checkBridgeHealth(bridgePort)) {
84
- console.log(chalk.green(`✓ Bridge 已运行 (端口 ${bridgePort})`))
138
+ // 先杀掉旧 Bridge,再启动新的
139
+ const existingListeners = openclawTool.getPortListeners(bridgePort)
140
+ if (existingListeners.length > 0) {
141
+ process.stdout.write(chalk.gray(` 正在重启 Bridge (端口 ${bridgePort})... `))
142
+ killBridge(bridgePort)
143
+ waitPortFree(bridgePort, 10, 200)
85
144
  } else {
86
145
  process.stdout.write(chalk.gray(` 正在启动 Bridge (端口 ${bridgePort})... `))
87
- const scriptPath = path.join(__dirname, '..', 'index.js')
88
- const spawnCmd = isWin ? 'node' : process.execPath
89
- const child = spawn(spawnCmd, [scriptPath, 'openclaw-bridge', '--port', String(bridgePort)], {
90
- detached: true,
91
- stdio: 'ignore',
92
- windowsHide: true,
93
- })
94
- child.unref()
146
+ }
95
147
 
96
- const bridgeReady = waitForPort(() => checkBridgeHealth(bridgePort), 10, 1000)
97
- if (bridgeReady) {
98
- console.log(chalk.green(''))
99
- } else {
100
- console.log(chalk.red(''))
101
- console.log(chalk.red(` Bridge 启动失败,请手动运行: hs openclaw-bridge --port ${bridgePort}`))
102
- process.exit(1)
103
- }
148
+ const scriptPath = path.join(__dirname, '..', 'index.js')
149
+ const spawnCmd = isWin ? 'node' : process.execPath
150
+ const child = spawn(spawnCmd, [scriptPath, 'openclaw-bridge', '--port', String(bridgePort)], {
151
+ detached: true,
152
+ stdio: 'ignore',
153
+ windowsHide: true,
154
+ })
155
+ child.unref()
156
+
157
+ const bridgeReady = waitForPort(() => checkBridgeHealth(bridgePort), 10, 1000)
158
+ if (bridgeReady) {
159
+ console.log(chalk.green('✓'))
160
+ } else {
161
+ console.log(chalk.red('✗'))
162
+ console.log(chalk.red(` Bridge 启动失败,请手动运行: hs openclaw-bridge --port ${bridgePort}`))
163
+ process.exit(1)
104
164
  }
105
165
 
106
166
  // 确保 Gateway 运行