@simonyea/holysheep-cli 2.1.67 → 2.1.69

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.
@@ -4135,11 +4135,11 @@ var require_package = __commonJS({
4135
4135
  "package.json"(exports2, module2) {
4136
4136
  module2.exports = {
4137
4137
  name: "@simonyea/holysheep-cli",
4138
- version: "2.1.67",
4138
+ version: "2.1.69",
4139
4139
  description: "Claude Code/Cursor/Cline API relay for China \u2014 \xA51=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
4140
4140
  scripts: {
4141
4141
  build: "node scripts/build.mjs",
4142
- test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js",
4142
+ test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js",
4143
4143
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
4144
4144
  },
4145
4145
  keywords: [
package/dist/index.html CHANGED
@@ -470,6 +470,27 @@ button { cursor: pointer; }
470
470
  color: var(--muted);
471
471
  line-height: 1.6;
472
472
  }
473
+ .tool-substatus {
474
+ margin-top: 12px;
475
+ border: 1px solid var(--line);
476
+ background: rgba(208, 110, 43, 0.08);
477
+ border-radius: 14px;
478
+ padding: 12px;
479
+ display: flex;
480
+ justify-content: space-between;
481
+ gap: 12px;
482
+ align-items: center;
483
+ }
484
+ .tool-substatus-title {
485
+ font-size: 13px;
486
+ font-weight: 700;
487
+ color: var(--text);
488
+ }
489
+ .tool-substatus-meta {
490
+ margin-top: 4px;
491
+ font-size: 12px;
492
+ color: var(--muted);
493
+ }
473
494
  .tool-actions {
474
495
  margin-top: 16px;
475
496
  display: flex;
@@ -1038,7 +1059,7 @@ function renderTools() {
1038
1059
  </div>
1039
1060
  </div>
1040
1061
  <div class="panel-body tool-grid">
1041
- ${tools.map((tool) => `
1062
+ ${tools.filter((tool) => tool.id !== 'claude-proxy').map((tool) => `
1042
1063
  <div class="tool-card">
1043
1064
  <div class="tool-head">
1044
1065
  <div>
@@ -1055,6 +1076,7 @@ function renderTools() {
1055
1076
  </div>
1056
1077
  </div>
1057
1078
  <div class="tool-hint">${esc(tool.hint || 'No additional hint')}</div>
1079
+ ${tool.id === 'claude-code' ? renderClaudeProxySubstatus(tool.vsCodeProxy) : ''}
1058
1080
  </div>
1059
1081
  `).join('')}
1060
1082
  </div>
@@ -1062,6 +1084,25 @@ function renderTools() {
1062
1084
  `
1063
1085
  }
1064
1086
 
1087
+ function renderClaudeProxySubstatus(proxy) {
1088
+ const running = !!proxy?.running
1089
+ const meta = running
1090
+ ? `127.0.0.1:${proxy.port || '?'} · PID ${proxy.pid || '?'}`
1091
+ : '未启动 · Windows 启动后需要完全退出 Code.exe 再重开 VS Code'
1092
+ return `
1093
+ <div class="tool-substatus">
1094
+ <div>
1095
+ <div class="tool-substatus-title">VS Code Claude 代理</div>
1096
+ <div class="tool-substatus-meta">${esc(meta)}</div>
1097
+ </div>
1098
+ <div class="inline-actions">
1099
+ <button class="btn ${running ? '' : 'primary'}" onclick="startClaudeProxy()">${running ? '重新校准' : '启动代理'}</button>
1100
+ ${running ? '<button class="btn danger" onclick="stopClaudeProxy()">停止</button>' : ''}
1101
+ </div>
1102
+ </div>
1103
+ `
1104
+ }
1105
+
1065
1106
  function renderAccount() {
1066
1107
  const status = state.status || {}
1067
1108
  const balance = state.balance || {}
@@ -1344,6 +1385,7 @@ function copyLoginKey() {
1344
1385
  }
1345
1386
 
1346
1387
  async function launchTool(toolId) {
1388
+ if (toolId === 'claude-proxy') return startClaudeProxy()
1347
1389
  const result = await api('tool/launch', {
1348
1390
  method: 'POST',
1349
1391
  headers: { 'Content-Type': 'application/json' },
@@ -1352,6 +1394,33 @@ async function launchTool(toolId) {
1352
1394
  if (result?.url) alert(`Opened: ${result.url}`)
1353
1395
  }
1354
1396
 
1397
+ async function startClaudeProxy() {
1398
+ openConsole('Start VS Code Claude proxy')
1399
+ appendConsole('正在启动 claude-proxy...', 'warn')
1400
+ try {
1401
+ const result = await api('claude-proxy/start', { method: 'POST' })
1402
+ appendConsole(result.message || `代理已启动: 127.0.0.1:${result.port || '?'}`, 'ok')
1403
+ appendConsole('Windows 用户:请完全退出所有 Code.exe,再重新打开 VS Code。', 'warn')
1404
+ await loadBaseState()
1405
+ render()
1406
+ } catch (error) {
1407
+ appendConsole(error.message, 'error')
1408
+ }
1409
+ }
1410
+
1411
+ async function stopClaudeProxy() {
1412
+ openConsole('Stop VS Code Claude proxy')
1413
+ appendConsole('正在停止 claude-proxy...', 'warn')
1414
+ try {
1415
+ const result = await api('claude-proxy/stop', { method: 'POST' })
1416
+ appendConsole(result.message || '代理已停止', 'ok')
1417
+ await loadBaseState()
1418
+ render()
1419
+ } catch (error) {
1420
+ appendConsole(error.message, 'error')
1421
+ }
1422
+ }
1423
+
1355
1424
  async function launchCurrentTool() {
1356
1425
  if (!state.currentConversation?.toolId) return
1357
1426
  return launchTool(state.currentConversation.toolId)
package/dist/index.js CHANGED
@@ -12,11 +12,11 @@ var require_package = __commonJS({
12
12
  "package.json"(exports2, module2) {
13
13
  module2.exports = {
14
14
  name: "@simonyea/holysheep-cli",
15
- version: "2.1.67",
15
+ version: "2.1.69",
16
16
  description: "Claude Code/Cursor/Cline API relay for China \u2014 \xA51=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
17
17
  scripts: {
18
18
  build: "node scripts/build.mjs",
19
- test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js",
19
+ test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js",
20
20
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
21
21
  },
22
22
  keywords: [
@@ -7107,7 +7107,7 @@ var require_claude_proxy = __commonJS({
7107
7107
  var path = require("path");
7108
7108
  var os = require("os");
7109
7109
  var http2 = require("http");
7110
- var { spawn, execSync } = require("child_process");
7110
+ var { spawn, execSync, execFileSync } = require("child_process");
7111
7111
  var chalk2 = require("chalk");
7112
7112
  var {
7113
7113
  startProcessProxy,
@@ -7136,6 +7136,7 @@ var require_claude_proxy = __commonJS({
7136
7136
  ];
7137
7137
  var platformOverride = null;
7138
7138
  var winUserEnvWriterOverride = null;
7139
+ var execFileSyncOverride = null;
7139
7140
  function effectivePlatform() {
7140
7141
  return platformOverride || process.env.HS_CLAUDE_PROXY_TEST_PLATFORM || process.platform;
7141
7142
  }
@@ -7260,6 +7261,25 @@ ${logTail}` : message);
7260
7261
  return `'${String(value).replace(/'/g, "''")}'`;
7261
7262
  }
7262
7263
  __name(quotePowerShellString, "quotePowerShellString");
7264
+ function tailText(value, max = 1200) {
7265
+ const text = String(value || "").trim();
7266
+ return text.length > max ? text.slice(-max) : text;
7267
+ }
7268
+ __name(tailText, "tailText");
7269
+ function runPowerShellUserEnvScript(script) {
7270
+ const runner = execFileSyncOverride || execFileSync;
7271
+ try {
7272
+ runner("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], {
7273
+ encoding: "utf8",
7274
+ windowsHide: true
7275
+ });
7276
+ } catch (err) {
7277
+ const stderr = tailText((err == null ? void 0 : err.stderr) || (err == null ? void 0 : err.stdout) || (err == null ? void 0 : err.message) || err);
7278
+ const code = err && (err.status ?? err.code ?? err.signal ?? "unknown");
7279
+ throw new Error(`Windows \u7528\u6237\u7EA7\u73AF\u5883\u53D8\u91CF\u5199\u5165\u5931\u8D25 (powershell exit=${code}): ${stderr || "no stderr"}`);
7280
+ }
7281
+ }
7282
+ __name(runPowerShellUserEnvScript, "runPowerShellUserEnvScript");
7263
7283
  function defaultWinUserEnvWriter(action, key, value) {
7264
7284
  if (process.env.HS_CLAUDE_PROXY_TEST_WIN_ENV_FILE) {
7265
7285
  const file = process.env.HS_CLAUDE_PROXY_TEST_WIN_ENV_FILE;
@@ -7277,7 +7297,7 @@ ${logTail}` : message);
7277
7297
  if (effectivePlatform() !== "win32") return;
7278
7298
  if (!/^[A-Z0-9_]+$/i.test(String(key))) throw new Error(`Invalid env var name: ${key}`);
7279
7299
  const ps = action === "delete" ? `[Environment]::SetEnvironmentVariable(${quotePowerShellString(key)}, $null, 'User')` : `[Environment]::SetEnvironmentVariable(${quotePowerShellString(key)}, ${quotePowerShellString(value || "")}, 'User')`;
7280
- execSync(`powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ${quotePowerShellString(ps)}`, { stdio: "ignore", windowsHide: true });
7300
+ runPowerShellUserEnvScript(ps);
7281
7301
  }
7282
7302
  __name(defaultWinUserEnvWriter, "defaultWinUserEnvWriter");
7283
7303
  function getWinUserEnvWriter() {
@@ -7530,6 +7550,9 @@ ${logTail}` : message);
7530
7550
  },
7531
7551
  setWinUserEnvWriterForTest(writer) {
7532
7552
  winUserEnvWriterOverride = writer || null;
7553
+ },
7554
+ setExecFileSyncForTest(runner) {
7555
+ execFileSyncOverride = runner || null;
7533
7556
  }
7534
7557
  };
7535
7558
  module2.exports = claudeProxy;
@@ -7662,7 +7685,7 @@ var require_server = __commonJS({
7662
7685
  async function buildToolSummary(tool) {
7663
7686
  var _a, _b;
7664
7687
  const installed = await detectToolInstalled(tool);
7665
- return {
7688
+ const summary = {
7666
7689
  id: tool.id,
7667
7690
  name: tool.name,
7668
7691
  installed,
@@ -7675,6 +7698,18 @@ var require_server = __commonJS({
7675
7698
  canUpgrade: !!UPGRADABLE_TOOLS.find((item) => item.id === tool.id),
7676
7699
  npmPkg: ((_b = UPGRADABLE_TOOLS.find((item) => item.id === tool.id)) == null ? void 0 : _b.npmPkg) || null
7677
7700
  };
7701
+ if (tool.id === "claude-code") {
7702
+ const proxyState = isClaudeProxyRunning();
7703
+ summary.vsCodeProxy = {
7704
+ running: proxyState.running,
7705
+ configured: proxyState.running,
7706
+ port: proxyState.port || null,
7707
+ pid: proxyState.pid || null,
7708
+ launchCmd: "hs claude-proxy --daemon",
7709
+ hint: proxyState.running ? `VS Code \u4EE3\u7406\u8FD0\u884C\u4E2D\uFF1A127.0.0.1:${proxyState.port}` : "VS Code Claude Code \u9700\u8981\u542F\u52A8\u672C\u5730\u4EE3\u7406\uFF1B\u542F\u52A8\u540E\u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u5F00 VS Code\u3002"
7710
+ };
7711
+ }
7712
+ return summary;
7678
7713
  }
7679
7714
  __name(buildToolSummary, "buildToolSummary");
7680
7715
  function json(res, data, status = 200) {
@@ -7920,23 +7955,85 @@ var require_server = __commonJS({
7920
7955
  __name(isClaudeProxyRunning, "isClaudeProxyRunning");
7921
7956
  async function handleTools(_req, res) {
7922
7957
  const tools = await Promise.all(TOOLS.map((tool) => buildToolSummary(tool)));
7923
- const proxyState = isClaudeProxyRunning();
7924
- tools.push({
7925
- id: "claude-proxy",
7926
- name: "Claude \u4EE3\u7406\uFF08VS Code\uFF09",
7927
- installed: true,
7928
- configured: proxyState.running,
7929
- version: proxyState.running ? `\u7AEF\u53E3 ${proxyState.port}` : null,
7930
- installCmd: null,
7931
- hint: "\u542F\u52A8\u540E VS Code Claude \u6269\u5C55\u5373\u53EF\u901A\u8FC7 HolySheep \u4F7F\u7528",
7932
- launchCmd: "hs claude-proxy",
7933
- canAutoInstall: false,
7934
- canUpgrade: false,
7935
- isProxy: true
7936
- });
7937
7958
  json(res, tools);
7938
7959
  }
7939
7960
  __name(handleTools, "handleTools");
7961
+ function isClaudeProxyToolId(toolId) {
7962
+ return toolId === "claude-proxy";
7963
+ }
7964
+ __name(isClaudeProxyToolId, "isClaudeProxyToolId");
7965
+ function emitClaudeProxyUnsupportedSse(res, action) {
7966
+ sseStart(res);
7967
+ sseEmit(res, {
7968
+ type: "progress",
7969
+ status: "error",
7970
+ message: `Claude Code / VS Code \u4EE3\u7406\u4E0D\u652F\u6301 ${action}\uFF1B\u8BF7\u4F7F\u7528\u201C\u542F\u52A8 VS Code \u4EE3\u7406\u201D\u6216\u8FD0\u884C hs claude-proxy --daemon\u3002`
7971
+ });
7972
+ sseEmit(res, { type: "done", success: false, message: "unsupported-claude-proxy-action" });
7973
+ res.end();
7974
+ }
7975
+ __name(emitClaudeProxyUnsupportedSse, "emitClaudeProxyUnsupportedSse");
7976
+ async function handleClaudeProxyToolStart(res) {
7977
+ sseStart(res);
7978
+ const state = isClaudeProxyRunning();
7979
+ if (state.running) {
7980
+ sseEmit(res, { type: "progress", status: "ok", message: `VS Code \u4EE3\u7406\u5DF2\u5728\u8FD0\u884C\uFF1A127.0.0.1:${state.port} (PID ${state.pid})` });
7981
+ sseEmit(res, { type: "done", success: true, port: state.port, pid: state.pid });
7982
+ return res.end();
7983
+ }
7984
+ try {
7985
+ sseEmit(res, { type: "progress", message: "\u6B63\u5728\u542F\u52A8 VS Code \u4EE3\u7406..." });
7986
+ const claudeProxy = require_claude_proxy();
7987
+ await claudeProxy(["--daemon"]);
7988
+ await new Promise((r) => setTimeout(r, 1200));
7989
+ const newState = isClaudeProxyRunning();
7990
+ if (!newState.running) {
7991
+ throw new Error("claude-proxy daemon \u542F\u52A8\u540E\u672A\u5199\u5165\u5065\u5EB7 PID\uFF1B\u8BF7\u67E5\u770B ~/.holysheep/claude-proxy.log");
7992
+ }
7993
+ sseEmit(res, { type: "progress", status: "ok", message: `VS Code \u4EE3\u7406\u5DF2\u542F\u52A8\uFF1A127.0.0.1:${newState.port} (PID ${newState.pid})` });
7994
+ sseEmit(res, { type: "progress", message: "Windows \u7528\u6237\uFF1A\u8BF7\u5B8C\u5168\u9000\u51FA\u6240\u6709 Code.exe\uFF0C\u518D\u91CD\u65B0\u6253\u5F00 VS Code\u3002" });
7995
+ sseEmit(res, { type: "done", success: true, port: newState.port, pid: newState.pid });
7996
+ res.end();
7997
+ } catch (e) {
7998
+ sseEmit(res, { type: "progress", status: "error", message: e && e.message ? e.message : String(e) });
7999
+ sseEmit(res, { type: "done", success: false, error: e && e.message ? e.message : String(e) });
8000
+ res.end();
8001
+ }
8002
+ }
8003
+ __name(handleClaudeProxyToolStart, "handleClaudeProxyToolStart");
8004
+ async function handleClaudeProxyToolStop(res) {
8005
+ sseStart(res);
8006
+ try {
8007
+ const claudeProxy = require_claude_proxy();
8008
+ await claudeProxy(["--stop"]);
8009
+ sseEmit(res, { type: "progress", status: "ok", message: "VS Code \u4EE3\u7406\u5DF2\u505C\u6B62" });
8010
+ sseEmit(res, { type: "done", success: true });
8011
+ res.end();
8012
+ } catch (e) {
8013
+ sseEmit(res, { type: "progress", status: "error", message: e && e.message ? e.message : String(e) });
8014
+ sseEmit(res, { type: "done", success: false, error: e && e.message ? e.message : String(e) });
8015
+ res.end();
8016
+ }
8017
+ }
8018
+ __name(handleClaudeProxyToolStop, "handleClaudeProxyToolStop");
8019
+ async function handleClaudeProxyVirtualToolAction(req, res, action) {
8020
+ const body = await parseBody(req);
8021
+ if (!isClaudeProxyToolId(body.toolId)) return false;
8022
+ if (action === "launch" || action === "configure" || action === "install") {
8023
+ await handleClaudeProxyToolStart(res);
8024
+ return true;
8025
+ }
8026
+ if (action === "reset") {
8027
+ await handleClaudeProxyToolStop(res);
8028
+ return true;
8029
+ }
8030
+ if (action === "upgrade" || action === "rollback") {
8031
+ emitClaudeProxyUnsupportedSse(res, "\u5347\u7EA7/\u56DE\u9000");
8032
+ return true;
8033
+ }
8034
+ return false;
8035
+ }
8036
+ __name(handleClaudeProxyVirtualToolAction, "handleClaudeProxyVirtualToolAction");
7940
8037
  async function handleSetup(req, res) {
7941
8038
  const body = await parseBody(req);
7942
8039
  const { apiKey, models, toolIds, autoInstall } = body;
@@ -8112,6 +8209,7 @@ var require_server = __commonJS({
8112
8209
  }
8113
8210
  __name(handleUpgrade, "handleUpgrade");
8114
8211
  async function handleToolInstall(req, res) {
8212
+ if (await handleClaudeProxyVirtualToolAction(req, res, "install")) return;
8115
8213
  const body = await parseBody(req);
8116
8214
  const { toolId } = body;
8117
8215
  if (!toolId || !AUTO_INSTALL[toolId]) {
@@ -8270,6 +8368,7 @@ ${installCmd}
8270
8368
  }
8271
8369
  __name(handleToolInstall, "handleToolInstall");
8272
8370
  async function handleToolConfigure(req, res) {
8371
+ if (await handleClaudeProxyVirtualToolAction(req, res, "configure")) return;
8273
8372
  const body = await parseBody(req);
8274
8373
  const { toolId } = body;
8275
8374
  const apiKey = getApiKey();
@@ -8329,6 +8428,7 @@ ${installCmd}
8329
8428
  __name(handleToolConfigure, "handleToolConfigure");
8330
8429
  async function handleToolUpgrade(req, res) {
8331
8430
  var _a;
8431
+ if (await handleClaudeProxyVirtualToolAction(req, res, "upgrade")) return;
8332
8432
  const body = await parseBody(req);
8333
8433
  const { toolId } = body;
8334
8434
  const entry = UPGRADABLE_TOOLS.find((t) => t.id === toolId);
@@ -8436,6 +8536,7 @@ ${installCmd}
8436
8536
  __name(handleToolUpgrade, "handleToolUpgrade");
8437
8537
  async function handleToolRollback(req, res) {
8438
8538
  var _a;
8539
+ if (await handleClaudeProxyVirtualToolAction(req, res, "rollback")) return;
8439
8540
  const body = await parseBody(req);
8440
8541
  const { toolId } = body;
8441
8542
  const entry = UPGRADABLE_TOOLS.find((t) => t.id === toolId);
@@ -8590,6 +8691,7 @@ ${installCmd}
8590
8691
  }
8591
8692
  __name(handleToolRollback, "handleToolRollback");
8592
8693
  async function handleToolReset(req, res) {
8694
+ if (await handleClaudeProxyVirtualToolAction(req, res, "reset")) return;
8593
8695
  const body = await parseBody(req);
8594
8696
  const { toolId } = body;
8595
8697
  const tool = TOOLS.find((t) => t.id === toolId);
@@ -8604,6 +8706,7 @@ ${installCmd}
8604
8706
  __name(handleToolReset, "handleToolReset");
8605
8707
  async function handleToolLaunch(req, res) {
8606
8708
  var _a, _b;
8709
+ if (await handleClaudeProxyVirtualToolAction(req, res, "launch")) return;
8607
8710
  const body = await parseBody(req);
8608
8711
  const { toolId } = body;
8609
8712
  const tool = TOOLS.find((t) => t.id === toolId);
@@ -8653,7 +8756,10 @@ ${installCmd}
8653
8756
  await claudeProxy(["--daemon"]);
8654
8757
  await new Promise((r) => setTimeout(r, 2e3));
8655
8758
  const newState = isClaudeProxyRunning();
8656
- json(res, { ok: newState.running, port: newState.port, pid: newState.pid });
8759
+ if (!newState.running) {
8760
+ return json(res, { ok: false, error: "claude-proxy daemon \u542F\u52A8\u540E\u672A\u5199\u5165\u5065\u5EB7 PID\uFF1B\u8BF7\u67E5\u770B ~/.holysheep/claude-proxy.log" }, 500);
8761
+ }
8762
+ json(res, { ok: true, port: newState.port, pid: newState.pid });
8657
8763
  } catch (e) {
8658
8764
  json(res, { ok: false, error: e.message }, 500);
8659
8765
  }
@@ -9068,6 +9174,8 @@ ${installCmd}
9068
9174
  handleToolReset,
9069
9175
  handleToolLaunch,
9070
9176
  handleToolUpgrade,
9177
+ handleClaudeProxyStart,
9178
+ handleClaudeProxyStop,
9071
9179
  handleUpgrade,
9072
9180
  handleBalance,
9073
9181
  handleDoctor,
@@ -9633,7 +9741,13 @@ var require_aionui_wrapper = __commonJS({
9633
9741
  if(t.installed&&!t.configured)btns+='<button data-act="configure" data-id="'+t.id+'" style="'+btnSty+';background:#8b5cf6">\u914D\u7F6E</button>';
9634
9742
  // [v2.1.63] \u542F\u52A8 button \u2014 installed + has launchCmd (covers OpenClaw etc.)
9635
9743
  if(t.installed&&t.launchCmd)btns+='<button data-act="launch" data-id="'+t.id+'" style="'+btnSty+';background:#f59e0b">\u542F\u52A8</button>';
9636
- return '<div style="padding:8px 0;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center"><div><b>'+t.name+'</b> '+statusBadge+' '+verText+'</div><div>'+btns+'</div></div>';
9744
+ var proxy='';
9745
+ if(t.id==='claude-code'&&t.vsCodeProxy){
9746
+ var p=t.vsCodeProxy;
9747
+ var pText=p.running?('\u8FD0\u884C\u4E2D 127.0.0.1:'+p.port+' \xB7 PID '+p.pid):'\u672A\u542F\u52A8\uFF08Windows \u542F\u52A8\u540E\u9700\u5B8C\u5168\u9000\u51FA Code.exe \u518D\u91CD\u5F00 VS Code\uFF09';
9748
+ proxy='<div style="margin-top:6px;padding:6px 8px;background:#fff7ed;border:1px solid #fed7aa;border-radius:6px;font-size:11px;color:#9a3412">VS Code \u4EE3\u7406\uFF1A'+pText+' <button data-act="launch" data-id="claude-proxy" style="'+btnSty+';background:#f59e0b">'+(p.running?'\u91CD\u65B0\u6821\u51C6':'\u542F\u52A8\u4EE3\u7406')+'</button>'+(p.running?' <button data-act="reset" data-id="claude-proxy" style="'+btnSty+';background:#dc2626">\u505C\u6B62</button>':'')+'</div>';
9749
+ }
9750
+ return '<div style="padding:8px 0;border-bottom:1px solid #eee"><div style="display:flex;justify-content:space-between;align-items:center"><div><b>'+t.name+'</b> '+statusBadge+' '+verText+'</div><div>'+btns+'</div></div>'+proxy+'</div>';
9637
9751
  }).join('')+'<div style="padding-top:10px"><button id="hs-cli-upgrade-all" style="width:100%;padding:8px;background:#16a34a;color:#fff;border:0;border-radius:4px;cursor:pointer;font-weight:600">\u4E00\u952E\u5347\u7EA7\u5168\u90E8\u5DF2\u5B89\u88C5\u7684 CLI</button></div>';
9638
9752
  Array.prototype.forEach.call(panel.querySelectorAll('button[data-act]'),function(b){
9639
9753
  b.addEventListener('click',function(){runAction(b.dataset.act,b.dataset.id,b)});
@@ -9671,7 +9785,7 @@ var require_aionui_wrapper = __commonJS({
9671
9785
  }
9672
9786
  b.disabled=true;b.style.opacity='.5';b.textContent=act==='install'?'\u5B89\u88C5\u4E2D...':act==='upgrade'?'\u5347\u7EA7\u4E2D...':'\u914D\u7F6E\u4E2D...';
9673
9787
  logEl.style.display='block';logEl.textContent='';
9674
- var path=act==='install'?'tool/install':act==='upgrade'?'tool/upgrade':'tool/configure';
9788
+ var path=act==='install'?'tool/install':act==='upgrade'?'tool/upgrade':act==='reset'?'tool/reset':'tool/configure';
9675
9789
  consumeSse('/api/holysheep/'+path,{toolId:id},logEl,function(ok){
9676
9790
  b.disabled=false;b.style.opacity='1';b.textContent=ok?'\u2713 \u5B8C\u6210':'\u2717 \u5931\u8D25 (\u91CD\u8BD5)';
9677
9791
  setTimeout(loadTools,500);
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "2.1.67",
3
+ "version": "2.1.69",
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
  "scripts": {
6
6
  "build": "node scripts/build.mjs",
7
- "test": "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js",
7
+ "test": "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js",
8
8
  "prepublishOnly": "npm run build && npm test && node scripts/check-tarball-size.js"
9
9
  },
10
10
  "keywords": [