@simonyea/holysheep-cli 2.1.40 → 2.1.42
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/dist/configure-worker.js +4510 -0
- package/dist/index.js +9610 -0
- package/dist/process-proxy-inject.js +117 -0
- package/package.json +19 -6
- package/.gitea/workflows/sanity.yml +0 -125
- package/scripts/check-tarball-size.js +0 -44
- package/src/commands/balance.js +0 -57
- package/src/commands/claude-proxy.js +0 -248
- package/src/commands/claude.js +0 -135
- package/src/commands/doctor.js +0 -282
- package/src/commands/login.js +0 -211
- package/src/commands/openclaw.js +0 -258
- package/src/commands/reset.js +0 -53
- package/src/commands/setup.js +0 -493
- package/src/commands/upgrade.js +0 -168
- package/src/commands/webui.js +0 -622
- package/src/index.js +0 -226
- package/src/tools/aider.js +0 -78
- package/src/tools/antigravity.js +0 -42
- package/src/tools/claude-code.js +0 -228
- package/src/tools/claude-process-proxy.js +0 -1030
- package/src/tools/codex.js +0 -254
- package/src/tools/continue.js +0 -146
- package/src/tools/cursor.js +0 -71
- package/src/tools/droid.js +0 -281
- package/src/tools/env-config.js +0 -185
- package/src/tools/gemini-cli.js +0 -82
- package/src/tools/hermes.js +0 -354
- package/src/tools/index.js +0 -13
- package/src/tools/openclaw-bridge.js +0 -987
- package/src/tools/openclaw.js +0 -925
- package/src/tools/opencode.js +0 -227
- package/src/tools/process-proxy-inject.js +0 -142
- package/src/utils/config.js +0 -54
- package/src/utils/shell.js +0 -342
- package/src/utils/which.js +0 -176
- package/src/webui/aionui-runtime-fetcher.js +0 -429
- package/src/webui/aionui-runtime.js +0 -139
- package/src/webui/aionui-wrapper.js +0 -734
- package/src/webui/configure-worker.js +0 -67
- package/src/webui/server.js +0 -1572
- package/src/webui/workspace-runtime.js +0 -288
- package/src/webui/workspace-store.js +0 -325
- /package/{src/webui → dist}/index.html +0 -0
- /package/{src/tools → dist}/pty-hermes-wrapper.py +0 -0
package/src/commands/openclaw.js
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { execSync, spawn, spawnSync } = require('child_process')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const chalk = require('chalk')
|
|
6
|
-
const openclawTool = require('../tools/openclaw')
|
|
7
|
-
const { readBridgeConfig } = require('../tools/openclaw-bridge')
|
|
8
|
-
|
|
9
|
-
const isWin = process.platform === 'win32'
|
|
10
|
-
|
|
11
|
-
function checkBridgeHealth(port) {
|
|
12
|
-
try {
|
|
13
|
-
execSync(
|
|
14
|
-
isWin
|
|
15
|
-
? `powershell -NonInteractive -Command "try{(Invoke-WebRequest -Uri http://127.0.0.1:${port}/health -TimeoutSec 1 -UseBasicParsing).StatusCode}catch{exit 1}"`
|
|
16
|
-
: `curl -sf http://127.0.0.1:${port}/health -o /dev/null --max-time 1`,
|
|
17
|
-
{ stdio: 'ignore', timeout: 3000 }
|
|
18
|
-
)
|
|
19
|
-
return true
|
|
20
|
-
} catch {
|
|
21
|
-
return false
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function checkGatewayHealth(port) {
|
|
26
|
-
try {
|
|
27
|
-
execSync(
|
|
28
|
-
isWin
|
|
29
|
-
? `powershell -NonInteractive -Command "try{(Invoke-WebRequest -Uri http://127.0.0.1:${port}/ -TimeoutSec 1 -UseBasicParsing).StatusCode}catch{exit 1}"`
|
|
30
|
-
: `curl -sf http://127.0.0.1:${port}/ -o /dev/null --max-time 1`,
|
|
31
|
-
{ stdio: 'ignore', timeout: 3000 }
|
|
32
|
-
)
|
|
33
|
-
return true
|
|
34
|
-
} catch {
|
|
35
|
-
return false
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function waitForPort(checkFn, maxTries, intervalMs) {
|
|
40
|
-
for (let i = 0; i < maxTries; i++) {
|
|
41
|
-
if (checkFn()) return true
|
|
42
|
-
const t0 = Date.now()
|
|
43
|
-
while (Date.now() - t0 < intervalMs) {}
|
|
44
|
-
}
|
|
45
|
-
return false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function killPortListeners(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
|
-
// 在 kill gateway 之前调用:禁用 watchdog,bridge 不会因 gateway 短暂下线而自杀
|
|
76
|
-
function disableWatchdog() {
|
|
77
|
-
const { BRIDGE_CONFIG_FILE } = require('../tools/openclaw-bridge')
|
|
78
|
-
const fs = require('fs')
|
|
79
|
-
try {
|
|
80
|
-
const raw = JSON.parse(fs.readFileSync(BRIDGE_CONFIG_FILE, 'utf8'))
|
|
81
|
-
if (!raw.watchdog) raw.watchdog = {}
|
|
82
|
-
raw.watchdog.enabled = false
|
|
83
|
-
raw.gatewayPid = null // 清旧 PID,防止 PID 检查误判
|
|
84
|
-
fs.writeFileSync(BRIDGE_CONFIG_FILE, JSON.stringify(raw, null, 2), 'utf8')
|
|
85
|
-
} catch (e) {
|
|
86
|
-
console.log(chalk.yellow(` ⚠ 无法更新 Bridge 配置: ${e.message}`))
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 在 gateway 确认就绪后调用:重新启用 watchdog,写入真实 gatewayStartedAt
|
|
91
|
-
function refreshGatewayStartedAt(gatewayPort) {
|
|
92
|
-
const { BRIDGE_CONFIG_FILE } = require('../tools/openclaw-bridge')
|
|
93
|
-
const fs = require('fs')
|
|
94
|
-
try {
|
|
95
|
-
const raw = JSON.parse(fs.readFileSync(BRIDGE_CONFIG_FILE, 'utf8'))
|
|
96
|
-
raw.gatewayStartedAt = new Date().toISOString()
|
|
97
|
-
raw.gatewayPid = null
|
|
98
|
-
raw.gatewayPort = gatewayPort
|
|
99
|
-
raw.gatewayLaunchMode = 'direct-process'
|
|
100
|
-
if (!raw.watchdog) raw.watchdog = {}
|
|
101
|
-
raw.watchdog.startupGraceMs = 30000
|
|
102
|
-
raw.watchdog.enabled = true // gateway 已就绪,安全地重新启用 watchdog
|
|
103
|
-
fs.writeFileSync(BRIDGE_CONFIG_FILE, JSON.stringify(raw, null, 2), 'utf8')
|
|
104
|
-
} catch {}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function findChrome() {
|
|
108
|
-
const { existsSync } = require('fs')
|
|
109
|
-
if (process.platform === 'darwin') {
|
|
110
|
-
const p = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
|
|
111
|
-
return existsSync(p) ? p : null
|
|
112
|
-
}
|
|
113
|
-
if (isWin) {
|
|
114
|
-
const candidates = [
|
|
115
|
-
process.env.LOCALAPPDATA && `${process.env.LOCALAPPDATA}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
116
|
-
process.env.PROGRAMFILES && `${process.env.PROGRAMFILES}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
117
|
-
process.env['PROGRAMFILES(X86)'] && `${process.env['PROGRAMFILES(X86)']}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
118
|
-
].filter(Boolean)
|
|
119
|
-
return candidates.find(existsSync) || null
|
|
120
|
-
}
|
|
121
|
-
for (const bin of ['google-chrome', 'chromium-browser', 'chromium']) {
|
|
122
|
-
try { execSync(`which ${bin}`, { stdio: 'ignore' }); return bin } catch {}
|
|
123
|
-
}
|
|
124
|
-
return null
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function openBrowser(url) {
|
|
128
|
-
const chrome = findChrome()
|
|
129
|
-
if (chrome) {
|
|
130
|
-
spawn(chrome, ['--disable-gpu', '--disable-gpu-sandbox', url], {
|
|
131
|
-
detached: true,
|
|
132
|
-
stdio: 'ignore',
|
|
133
|
-
shell: false,
|
|
134
|
-
}).unref()
|
|
135
|
-
return
|
|
136
|
-
}
|
|
137
|
-
const cmd = isWin ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open'
|
|
138
|
-
try {
|
|
139
|
-
spawn(cmd, [url], { detached: true, stdio: 'ignore', shell: isWin }).unref()
|
|
140
|
-
} catch {}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function openclaw() {
|
|
144
|
-
console.log()
|
|
145
|
-
|
|
146
|
-
const runtime = openclawTool.detectRuntime()
|
|
147
|
-
if (!runtime.available) {
|
|
148
|
-
console.log(chalk.red('✗ 未检测到 OpenClaw'))
|
|
149
|
-
console.log(chalk.gray(` 安装命令: ${openclawTool.installCmd}`))
|
|
150
|
-
console.log(chalk.gray(' 安装后运行 hs setup 完成配置'))
|
|
151
|
-
process.exit(1)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!openclawTool.isConfigured()) {
|
|
155
|
-
console.log(chalk.yellow('⚠ OpenClaw 尚未配置 HolySheep,请先运行 hs setup'))
|
|
156
|
-
process.exit(1)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let bridgeConfig
|
|
160
|
-
try {
|
|
161
|
-
bridgeConfig = readBridgeConfig()
|
|
162
|
-
} catch {
|
|
163
|
-
console.log(chalk.yellow('⚠ 未找到 Bridge 配置,请先运行 hs setup'))
|
|
164
|
-
process.exit(1)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const bridgePort = openclawTool.getBridgePort()
|
|
168
|
-
const gatewayPort = openclawTool.getGatewayPort()
|
|
169
|
-
|
|
170
|
-
// 先禁用 watchdog,防止后续 kill gateway 期间 bridge 误判自杀
|
|
171
|
-
disableWatchdog()
|
|
172
|
-
|
|
173
|
-
// Bridge:只确保运行,不重启
|
|
174
|
-
if (checkBridgeHealth(bridgePort)) {
|
|
175
|
-
console.log(chalk.green(`✓ Bridge 已运行 (端口 ${bridgePort})`))
|
|
176
|
-
} else {
|
|
177
|
-
process.stdout.write(chalk.gray(` 正在启动 Bridge (端口 ${bridgePort})... `))
|
|
178
|
-
const scriptPath = path.join(__dirname, '..', 'index.js')
|
|
179
|
-
const spawnCmd = isWin ? 'node' : process.execPath
|
|
180
|
-
const child = spawn(spawnCmd, [scriptPath, 'openclaw-bridge', '--port', String(bridgePort)], {
|
|
181
|
-
detached: true,
|
|
182
|
-
stdio: 'ignore',
|
|
183
|
-
windowsHide: true,
|
|
184
|
-
})
|
|
185
|
-
child.unref()
|
|
186
|
-
|
|
187
|
-
const bridgeReady = waitForPort(() => checkBridgeHealth(bridgePort), 10, 1000)
|
|
188
|
-
if (bridgeReady) {
|
|
189
|
-
console.log(chalk.green('✓'))
|
|
190
|
-
} else {
|
|
191
|
-
console.log(chalk.red('✗'))
|
|
192
|
-
console.log(chalk.red(` Bridge 启动失败,请手动运行: hs openclaw-bridge --port ${bridgePort}`))
|
|
193
|
-
process.exit(1)
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Gateway:kill 旧的,直接 spawn 新的(明确 --port,避免 service 配置不一致)
|
|
198
|
-
const existingGatewayListeners = openclawTool.getPortListeners(gatewayPort)
|
|
199
|
-
if (existingGatewayListeners.length > 0) {
|
|
200
|
-
process.stdout.write(chalk.gray(` 正在重启 Gateway (端口 ${gatewayPort})... `))
|
|
201
|
-
killPortListeners(gatewayPort)
|
|
202
|
-
waitPortFree(gatewayPort, 10, 200)
|
|
203
|
-
} else {
|
|
204
|
-
process.stdout.write(chalk.gray(` 正在启动 Gateway (端口 ${gatewayPort})... `))
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const preferNpx = runtime.via === 'npx'
|
|
208
|
-
const gatewayArgs = preferNpx
|
|
209
|
-
? ['openclaw', 'gateway', '--port', String(gatewayPort)]
|
|
210
|
-
: ['gateway', '--port', String(gatewayPort)]
|
|
211
|
-
const gatewayCmd = preferNpx ? 'npx' : 'openclaw'
|
|
212
|
-
const gatewayChild = spawn(gatewayCmd, gatewayArgs, {
|
|
213
|
-
detached: true,
|
|
214
|
-
stdio: 'ignore',
|
|
215
|
-
shell: isWin,
|
|
216
|
-
windowsHide: true,
|
|
217
|
-
})
|
|
218
|
-
gatewayChild.unref()
|
|
219
|
-
|
|
220
|
-
const gatewayReady = waitForPort(() => checkGatewayHealth(gatewayPort), 12, 1500)
|
|
221
|
-
if (gatewayReady) {
|
|
222
|
-
console.log(chalk.green('✓'))
|
|
223
|
-
} else {
|
|
224
|
-
console.log(chalk.yellow('⚠'))
|
|
225
|
-
console.log(chalk.yellow(' Gateway 未就绪,仍将尝试打开 Dashboard'))
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Gateway 就绪后重新启用 watchdog,写入真实 gatewayStartedAt
|
|
229
|
-
refreshGatewayStartedAt(gatewayPort)
|
|
230
|
-
|
|
231
|
-
// 获取 Dashboard URL
|
|
232
|
-
const fallbackUrl = `http://127.0.0.1:${gatewayPort}/`
|
|
233
|
-
let dashUrl = fallbackUrl
|
|
234
|
-
try {
|
|
235
|
-
const dashArgs = preferNpx ? ['openclaw', 'dashboard', '--no-open'] : ['dashboard', '--no-open']
|
|
236
|
-
const dashCmd = preferNpx ? 'npx' : 'openclaw'
|
|
237
|
-
const result = spawnSync(dashCmd, dashArgs, {
|
|
238
|
-
timeout: preferNpx ? 60000 : 20000,
|
|
239
|
-
shell: isWin,
|
|
240
|
-
encoding: 'utf8',
|
|
241
|
-
stdio: 'pipe',
|
|
242
|
-
})
|
|
243
|
-
if (result.status === 0) {
|
|
244
|
-
const output = String(result.stdout || '')
|
|
245
|
-
const match = output.match(/Dashboard URL:\s*(\S+)/) || output.match(/(https?:\/\/\S+)/)
|
|
246
|
-
if (match) dashUrl = match[1]
|
|
247
|
-
}
|
|
248
|
-
} catch {}
|
|
249
|
-
|
|
250
|
-
console.log()
|
|
251
|
-
console.log(chalk.cyan.bold(`🌐 正在打开 OpenClaw Dashboard: ${dashUrl}`))
|
|
252
|
-
openBrowser(dashUrl)
|
|
253
|
-
console.log(chalk.gray(` Bridge: http://127.0.0.1:${bridgePort}/v1`))
|
|
254
|
-
console.log(chalk.gray(` Gateway: http://127.0.0.1:${gatewayPort}/`))
|
|
255
|
-
console.log()
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
module.exports = openclaw
|
package/src/commands/reset.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* hs reset — 清除所有工具的 HolySheep 配置,恢复默认
|
|
3
|
-
*/
|
|
4
|
-
const inquirer = require('inquirer')
|
|
5
|
-
const chalk = require('chalk')
|
|
6
|
-
const ora = require('ora')
|
|
7
|
-
const { removeEnvFromShell } = require('../utils/shell')
|
|
8
|
-
const { saveConfig } = require('../utils/config')
|
|
9
|
-
const TOOLS = require('../tools')
|
|
10
|
-
|
|
11
|
-
async function reset(options) {
|
|
12
|
-
console.log()
|
|
13
|
-
if (!options.yes) {
|
|
14
|
-
const { confirm } = await inquirer.prompt([{
|
|
15
|
-
type: 'confirm',
|
|
16
|
-
name: 'confirm',
|
|
17
|
-
message: chalk.yellow('将清除所有工具的 HolySheep 配置和环境变量,继续?'),
|
|
18
|
-
default: false,
|
|
19
|
-
}])
|
|
20
|
-
if (!confirm) { console.log('已取消\n'); return }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
console.log()
|
|
24
|
-
for (const tool of TOOLS) {
|
|
25
|
-
if (!tool.checkInstalled() && !tool.isConfigured?.()) continue
|
|
26
|
-
const spinner = ora(`清除 ${tool.name}...`).start()
|
|
27
|
-
try {
|
|
28
|
-
tool.reset()
|
|
29
|
-
spinner.succeed(`${tool.name} 已清除`)
|
|
30
|
-
} catch (e) {
|
|
31
|
-
spinner.fail(`${tool.name}: ${e.message}`)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 清除 shell 环境变量
|
|
36
|
-
const spinner = ora('清除 shell 环境变量...').start()
|
|
37
|
-
try {
|
|
38
|
-
const cleaned = removeEnvFromShell()
|
|
39
|
-
if (cleaned.length) spinner.succeed(`已清除: ${cleaned.join(', ')}`)
|
|
40
|
-
else spinner.info('无 shell 环境变量需要清除')
|
|
41
|
-
} catch (e) {
|
|
42
|
-
spinner.fail(e.message)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 清除本地保存的 API Key
|
|
46
|
-
saveConfig({ apiKey: '' })
|
|
47
|
-
|
|
48
|
-
console.log()
|
|
49
|
-
console.log(chalk.green('✅ 清除完成,所有工具已恢复默认配置'))
|
|
50
|
-
console.log(chalk.gray('重新配置: hs setup\n'))
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
module.exports = reset
|