@simonyea/holysheep-cli 1.7.119 → 1.7.121
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 +1 -1
- package/src/commands/webui.js +6 -0
- package/src/webui/server.js +83 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simonyea/holysheep-cli",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.121",
|
|
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",
|
package/src/commands/webui.js
CHANGED
|
@@ -31,6 +31,12 @@ async function webui(opts) {
|
|
|
31
31
|
} catch {}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// 后台拉起 OpenClaw Bridge + Claude Proxy
|
|
35
|
+
const { bootstrapBackgroundServices } = require('../webui/server')
|
|
36
|
+
bootstrapBackgroundServices().then(() => {
|
|
37
|
+
console.log(chalk.gray(' 后台服务已就绪'))
|
|
38
|
+
}).catch(() => {})
|
|
39
|
+
|
|
34
40
|
// Keep alive
|
|
35
41
|
await new Promise(() => {})
|
|
36
42
|
} catch (err) {
|
package/src/webui/server.js
CHANGED
|
@@ -523,13 +523,11 @@ async function handleUpgrade(_req, res) {
|
|
|
523
523
|
} catch {}
|
|
524
524
|
}
|
|
525
525
|
try {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
fs.writeFileSync(bridgeMod.BRIDGE_CONFIG_FILE, JSON.stringify(bc, null, 2), 'utf8')
|
|
532
|
-
}
|
|
526
|
+
const bridgeMod = require('../tools/openclaw-bridge')
|
|
527
|
+
const bc = bridgeMod.readBridgeConfig()
|
|
528
|
+
bc.gatewayPid = gPid // null 也写入,清除旧死 PID
|
|
529
|
+
bc.gatewayStartedAt = new Date().toISOString()
|
|
530
|
+
fs.writeFileSync(bridgeMod.BRIDGE_CONFIG_FILE, JSON.stringify(bc, null, 2), 'utf8')
|
|
533
531
|
} catch {}
|
|
534
532
|
try { openclawTool?.ensureBridgeRunning?.() } catch {}
|
|
535
533
|
}
|
|
@@ -711,15 +709,13 @@ async function handleToolUpgrade(req, res) {
|
|
|
711
709
|
}
|
|
712
710
|
} catch {}
|
|
713
711
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
} catch {}
|
|
722
|
-
}
|
|
712
|
+
try {
|
|
713
|
+
const bridgeMod = require('../tools/openclaw-bridge')
|
|
714
|
+
const bc = bridgeMod.readBridgeConfig()
|
|
715
|
+
bc.gatewayPid = gPid // null 也写入,清除旧死 PID
|
|
716
|
+
bc.gatewayStartedAt = new Date().toISOString()
|
|
717
|
+
fs.writeFileSync(bridgeMod.BRIDGE_CONFIG_FILE, JSON.stringify(bc, null, 2), 'utf8')
|
|
718
|
+
} catch {}
|
|
723
719
|
// 启动 Bridge
|
|
724
720
|
if (openclawTool?.ensureBridgeRunning) {
|
|
725
721
|
try {
|
|
@@ -867,20 +863,15 @@ async function handleToolRollback(req, res) {
|
|
|
867
863
|
}
|
|
868
864
|
} catch {}
|
|
869
865
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
sseEmit(res, { type: 'progress', message: `⚠️ 写入 Bridge 配置失败: ${e.message}` })
|
|
880
|
-
}
|
|
881
|
-
} else {
|
|
882
|
-
sseEmit(res, { type: 'progress', message: '⚠️ 未检测到 Gateway PID,Bridge 可能无��启动' })
|
|
883
|
-
}
|
|
866
|
+
// PID 检测不到时设为 null(和 hs setup 一致),watchdog 不杀 null PID 的 bridge
|
|
867
|
+
try {
|
|
868
|
+
const bridgeMod = require('../tools/openclaw-bridge')
|
|
869
|
+
const bc = bridgeMod.readBridgeConfig()
|
|
870
|
+
bc.gatewayPid = gatewayPid // null 也写入,清除旧死 PID
|
|
871
|
+
bc.gatewayStartedAt = new Date().toISOString()
|
|
872
|
+
fs.writeFileSync(bridgeMod.BRIDGE_CONFIG_FILE, JSON.stringify(bc, null, 2), 'utf8')
|
|
873
|
+
sseEmit(res, { type: 'progress', message: gatewayPid ? `Gateway PID: ${gatewayPid}` : 'Gateway PID cleared' })
|
|
874
|
+
} catch {}
|
|
884
875
|
// 3. 启动 Bridge
|
|
885
876
|
if (openclawTool?.ensureBridgeRunning) {
|
|
886
877
|
try {
|
|
@@ -1132,4 +1123,65 @@ function startServer(port) {
|
|
|
1132
1123
|
})
|
|
1133
1124
|
}
|
|
1134
1125
|
|
|
1135
|
-
|
|
1126
|
+
// ── 后台服务自动拉起 ─────────────────────────────────────────────────────────
|
|
1127
|
+
|
|
1128
|
+
async function bootstrapBackgroundServices() {
|
|
1129
|
+
const { getApiKey } = require('../utils/config')
|
|
1130
|
+
const apiKey = getApiKey()
|
|
1131
|
+
if (!apiKey) return // 未登录,跳过
|
|
1132
|
+
|
|
1133
|
+
// 1. OpenClaw Bridge
|
|
1134
|
+
try {
|
|
1135
|
+
const openclawTool = TOOLS.find(t => t.id === 'openclaw')
|
|
1136
|
+
if (openclawTool?.checkInstalled() && openclawTool?.isConfigured()) {
|
|
1137
|
+
const bridgePort = openclawTool.getBridgePort?.() || 18788
|
|
1138
|
+
// 检查是否已在运行
|
|
1139
|
+
let bridgeAlive = false
|
|
1140
|
+
try {
|
|
1141
|
+
const http = require('http')
|
|
1142
|
+
await new Promise((resolve, reject) => {
|
|
1143
|
+
const req = http.get({ hostname: '127.0.0.1', port: bridgePort, path: '/health', family: 4 }, resolve)
|
|
1144
|
+
req.setTimeout(2000, () => { req.destroy(); reject() })
|
|
1145
|
+
req.on('error', reject)
|
|
1146
|
+
})
|
|
1147
|
+
bridgeAlive = true
|
|
1148
|
+
} catch {}
|
|
1149
|
+
|
|
1150
|
+
if (!bridgeAlive) {
|
|
1151
|
+
// 更新 bridge config 里的 gateway PID,防止 watchdog 误杀
|
|
1152
|
+
// 关键:检测不到 PID 时设为 null(和 hs setup 一致),watchdog 不会杀 null PID 的 bridge
|
|
1153
|
+
const gatewayPort = openclawTool.getGatewayPort?.() || 18789
|
|
1154
|
+
const bridgeMod = require('../tools/openclaw-bridge')
|
|
1155
|
+
const bc = bridgeMod.readBridgeConfig()
|
|
1156
|
+
let gPid = null
|
|
1157
|
+
try {
|
|
1158
|
+
if (process.platform === 'win32') {
|
|
1159
|
+
const o = execSync(`powershell -NonInteractive -Command "(Get-NetTCPConnection -LocalPort ${gatewayPort} -State Listen -ErrorAction SilentlyContinue).OwningProcess"`, { stdio: 'pipe', timeout: 5000 }).toString().trim()
|
|
1160
|
+
gPid = Number(o.split(/\r?\n/)[0]) || null
|
|
1161
|
+
} else {
|
|
1162
|
+
const o = execSync(`lsof -iTCP:${gatewayPort} -sTCP:LISTEN -t 2>/dev/null | head -1`, { stdio: 'pipe', timeout: 5000 }).toString().trim()
|
|
1163
|
+
gPid = Number(o) || null
|
|
1164
|
+
}
|
|
1165
|
+
} catch {}
|
|
1166
|
+
// 无论是否检测到,都写入(null 或真实 PID),清除旧的死 PID
|
|
1167
|
+
bc.gatewayPid = gPid
|
|
1168
|
+
bc.gatewayStartedAt = new Date().toISOString()
|
|
1169
|
+
try { fs.writeFileSync(bridgeMod.BRIDGE_CONFIG_FILE, JSON.stringify(bc, null, 2), 'utf8') } catch {}
|
|
1170
|
+
openclawTool.ensureBridgeRunning?.(bridgePort)
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
} catch {}
|
|
1174
|
+
|
|
1175
|
+
// 2. Claude Proxy
|
|
1176
|
+
try {
|
|
1177
|
+
const claudeTool = TOOLS.find(t => t.id === 'claude-code')
|
|
1178
|
+
if (claudeTool?.checkInstalled() && claudeTool?.isConfigured()) {
|
|
1179
|
+
if (!isClaudeProxyRunning().running) {
|
|
1180
|
+
const claudeProxy = require('../commands/claude-proxy')
|
|
1181
|
+
await claudeProxy(['--daemon'])
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
} catch {}
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
module.exports = { startServer, bootstrapBackgroundServices }
|