@simonyea/holysheep-cli 2.1.52 → 2.1.54

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.
@@ -1399,7 +1399,7 @@ var require_codex = __commonJS({
1399
1399
  }
1400
1400
  const content = stripManagedTomlConfig(readTomlConfig());
1401
1401
  const newConfig = [
1402
- `model = "${model || "gpt-5.4"}"`,
1402
+ `model = "${model || "gpt-5.5"}"`,
1403
1403
  `model_provider = "holysheep"`,
1404
1404
  "",
1405
1405
  content,
@@ -1422,7 +1422,7 @@ var require_codex = __commonJS({
1422
1422
  if (fs.existsSync(CONFIG_FILE_JSON)) {
1423
1423
  jsonConfig = JSON.parse(fs.readFileSync(CONFIG_FILE_JSON, "utf8"));
1424
1424
  }
1425
- jsonConfig.model = model || "gpt-5.4";
1425
+ jsonConfig.model = model || "gpt-5.5";
1426
1426
  jsonConfig.model_provider = "holysheep";
1427
1427
  jsonConfig.provider = "holysheep";
1428
1428
  if (!jsonConfig.model_providers) jsonConfig.model_providers = {};
@@ -1479,7 +1479,7 @@ var require_codex = __commonJS({
1479
1479
  return isConfiguredInToml();
1480
1480
  },
1481
1481
  configure(apiKey, _baseUrlAnthropicNoV1, baseUrlOpenAI) {
1482
- const model = "gpt-5.4";
1482
+ const model = "gpt-5.5";
1483
1483
  writeTomlConfig(apiKey, baseUrlOpenAI, model);
1484
1484
  writeJsonConfigIfNeeded(apiKey, baseUrlOpenAI, model);
1485
1485
  neutralizeAuthJson();
@@ -4019,11 +4019,11 @@ var require_package = __commonJS({
4019
4019
  "package.json"(exports2, module2) {
4020
4020
  module2.exports = {
4021
4021
  name: "@simonyea/holysheep-cli",
4022
- version: "2.1.52",
4022
+ version: "2.1.54",
4023
4023
  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.",
4024
4024
  scripts: {
4025
4025
  build: "node scripts/build.mjs",
4026
- 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/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/version-check.test.js && node tests/runclaude-missing-binary.test.js",
4026
+ 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/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/version-check.test.js && node tests/runclaude-missing-binary.test.js",
4027
4027
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
4028
4028
  },
4029
4029
  keywords: [
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.52",
15
+ version: "2.1.54",
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/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/version-check.test.js && node tests/runclaude-missing-binary.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/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/version-check.test.js && node tests/runclaude-missing-binary.test.js",
20
20
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
21
21
  },
22
22
  keywords: [
@@ -1945,7 +1945,7 @@ var require_codex = __commonJS({
1945
1945
  }
1946
1946
  const content = stripManagedTomlConfig(readTomlConfig());
1947
1947
  const newConfig = [
1948
- `model = "${model || "gpt-5.4"}"`,
1948
+ `model = "${model || "gpt-5.5"}"`,
1949
1949
  `model_provider = "holysheep"`,
1950
1950
  "",
1951
1951
  content,
@@ -1968,7 +1968,7 @@ var require_codex = __commonJS({
1968
1968
  if (fs.existsSync(CONFIG_FILE_JSON)) {
1969
1969
  jsonConfig = JSON.parse(fs.readFileSync(CONFIG_FILE_JSON, "utf8"));
1970
1970
  }
1971
- jsonConfig.model = model || "gpt-5.4";
1971
+ jsonConfig.model = model || "gpt-5.5";
1972
1972
  jsonConfig.model_provider = "holysheep";
1973
1973
  jsonConfig.provider = "holysheep";
1974
1974
  if (!jsonConfig.model_providers) jsonConfig.model_providers = {};
@@ -2025,7 +2025,7 @@ var require_codex = __commonJS({
2025
2025
  return isConfiguredInToml();
2026
2026
  },
2027
2027
  configure(apiKey, _baseUrlAnthropicNoV1, baseUrlOpenAI) {
2028
- const model = "gpt-5.4";
2028
+ const model = "gpt-5.5";
2029
2029
  writeTomlConfig(apiKey, baseUrlOpenAI, model);
2030
2030
  writeJsonConfigIfNeeded(apiKey, baseUrlOpenAI, model);
2031
2031
  neutralizeAuthJson();
@@ -8849,6 +8849,21 @@ var require_aionui_wrapper = __commonJS({
8849
8849
  var cachedAionUiCookie = null;
8850
8850
  var cachedAionUiCookieAt = 0;
8851
8851
  var AIONUI_COOKIE_TTL_MS = 10 * 60 * 1e3;
8852
+ var _startupWarnings = {
8853
+ notInstalled: [],
8854
+ // tool ids that are installed but not configured
8855
+ openclawNeedsPairing: false
8856
+ };
8857
+ var _aionuiUpgrade = {
8858
+ status: "idle",
8859
+ // idle | running | success | error
8860
+ pid: null,
8861
+ logFile: null,
8862
+ startedAt: null,
8863
+ finishedAt: null,
8864
+ exitCode: null,
8865
+ message: ""
8866
+ };
8852
8867
  function log(msg) {
8853
8868
  console.log(`[holysheep-web] ${msg}`);
8854
8869
  }
@@ -9194,6 +9209,92 @@ var require_aionui_wrapper = __commonJS({
9194
9209
  }
9195
9210
  }
9196
9211
  __name(rewriteCspHeaders, "rewriteCspHeaders");
9212
+ function _getStartupWarningMessages() {
9213
+ const notInstalled = _startupWarnings.notInstalled || [];
9214
+ const needsPairing = _startupWarnings.openclawNeedsPairing;
9215
+ const lines = [];
9216
+ if (notInstalled.length > 0) {
9217
+ const names = notInstalled.map((id) => {
9218
+ const map = { codex: "Codex", droid: "Droid", hermes: "Hermes", "gemini-cli": "Gemini CLI" };
9219
+ return map[id] || id;
9220
+ });
9221
+ lines.push(`\u26A0\uFE0F \u4EE5\u4E0B CLI \u5DE5\u5177\u672A\u5B89\u88C5\uFF1A${names.join("\u3001")}\u3002\u8BF7\u8FD0\u884C <code>hs setup</code> \u5B89\u88C5\u5E76\u914D\u7F6E\u3002`);
9222
+ }
9223
+ if (needsPairing) {
9224
+ lines.push("\u26A0\uFE0F OpenClaw Gateway \u9700\u8981 Pairing \u8BA4\u8BC1\u3002\u8BF7\u8FD0\u884C <code>hs openclaw</code> \u5B8C\u6210\u914D\u7F6E\uFF0C\u5426\u5219 OpenClaw \u5BF9\u8BDD\u5C06\u6301\u7EED\u62A5\u9519\u3002");
9225
+ }
9226
+ return lines;
9227
+ }
9228
+ __name(_getStartupWarningMessages, "_getStartupWarningMessages");
9229
+ function _buildStartupBannerScript() {
9230
+ const startupMsgs = _getStartupWarningMessages();
9231
+ const startupJson = JSON.stringify(startupMsgs);
9232
+ return `<script>
9233
+ (function(){
9234
+ if(window.__hsBannerInstalled) return; window.__hsBannerInstalled=true;
9235
+ var DISMISS_KEY='hs-startup-banner-dismissed';
9236
+ var UPGRADE_DISMISS_KEY='hs-upgrade-banner-dismissed';
9237
+ function el(tag,style,html){var x=document.createElement(tag);if(style)x.style.cssText=style;if(html!=null)x.innerHTML=html;return x}
9238
+ function showBanner(opts){
9239
+ var bg=opts.color||'#ff8c00';
9240
+ var d=el('div','position:fixed;bottom:16px;right:16px;z-index:99999;max-width:440px;background:'+bg+';color:#fff;padding:12px 16px;border-radius:8px;font-size:13px;line-height:1.5;box-shadow:0 4px 16px rgba(0,0,0,.3)');
9241
+ d.innerHTML=opts.html;
9242
+ document.body.appendChild(d);
9243
+ return d;
9244
+ }
9245
+ // 1) Static startup warnings
9246
+ (function(){
9247
+ if(sessionStorage.getItem(DISMISS_KEY))return;
9248
+ var msgs=${startupJson}; if(!msgs.length)return;
9249
+ var d=showBanner({html:msgs.join('<br><br>')+'<br><span style="font-size:11px;opacity:.8;cursor:pointer">\u70B9\u51FB\u5173\u95ED (\u672C\u6B21\u4F1A\u8BDD\u4E0D\u518D\u663E\u793A)</span>'});
9250
+ d.style.cursor='pointer';
9251
+ d.addEventListener('click',function(){if(d.parentNode)d.parentNode.removeChild(d);sessionStorage.setItem(DISMISS_KEY,'1')});
9252
+ setTimeout(function(){if(d.parentNode)d.parentNode.removeChild(d);},30000);
9253
+ })();
9254
+ // 2) AionUi/CLI upgrade banner \u2014 async fetch
9255
+ (function(){
9256
+ if(sessionStorage.getItem(UPGRADE_DISMISS_KEY))return;
9257
+ fetch('/api/holysheep/__wrapper/version-status').then(function(r){return r.json()}).catch(function(){return null}).then(function(j){
9258
+ if(!j||!j.upgradeAvailable)return;
9259
+ var current=j.cli&&j.cli.current||'?';
9260
+ var latest=j.cli&&j.cli.latest||'?';
9261
+ var bannerHtml='\u2728 <b>AionUi \u6709\u65B0\u7248\u672C\u53EF\u7528</b><br>\u5F53\u524D: v'+current+' \u2192 \u6700\u65B0: v'+latest+'<br><br>'+
9262
+ '<button id="hs-upgrade-btn" style="background:#fff;color:#1976d2;border:0;padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer;font-weight:600">\u7ACB\u5373\u66F4\u65B0</button> '+
9263
+ '<button id="hs-upgrade-dismiss" style="background:transparent;color:#fff;border:1px solid rgba(255,255,255,.5);padding:6px 12px;border-radius:4px;font-size:12px;cursor:pointer">\u7A0D\u540E</button>'+
9264
+ '<div id="hs-upgrade-progress" style="margin-top:10px;font-size:11px;display:none"></div>';
9265
+ var d=showBanner({color:'#1976d2',html:bannerHtml});
9266
+ var btn=d.querySelector('#hs-upgrade-btn');
9267
+ var dis=d.querySelector('#hs-upgrade-dismiss');
9268
+ var prog=d.querySelector('#hs-upgrade-progress');
9269
+ dis.addEventListener('click',function(){if(d.parentNode)d.parentNode.removeChild(d);sessionStorage.setItem(UPGRADE_DISMISS_KEY,'1')});
9270
+ btn.addEventListener('click',function(){
9271
+ btn.disabled=true;btn.style.opacity='.6';btn.textContent='\u6B63\u5728\u542F\u52A8...';
9272
+ prog.style.display='block';prog.textContent='\u63D0\u4EA4\u540E\u53F0\u66F4\u65B0\u4EFB\u52A1...';
9273
+ fetch('/api/holysheep/__wrapper/aionui-update',{method:'POST'}).then(function(r){return r.json()}).then(function(res){
9274
+ if(!res||!res.ok){prog.textContent='\u542F\u52A8\u5931\u8D25: '+((res&&res.message)||'unknown');return}
9275
+ prog.textContent='\u5347\u7EA7\u4E2D (pid='+res.pid+')... \u5B8C\u6210\u540E\u8BF7\u5173\u95ED\u5E76\u91CD\u542F hs web';
9276
+ var poll=setInterval(function(){
9277
+ fetch('/api/holysheep/__wrapper/aionui-update').then(function(r){return r.json()}).then(function(s){
9278
+ if(!s)return;
9279
+ if(s.status==='running'){prog.textContent='\u5347\u7EA7\u4E2D (pid='+s.pid+')...';return}
9280
+ clearInterval(poll);
9281
+ if(s.status==='success'){
9282
+ btn.style.display='none';dis.textContent='\u6211\u77E5\u9053\u4E86';
9283
+ prog.innerHTML='\u2705 \u5347\u7EA7\u5B8C\u6210 (exit='+s.exitCode+')<br>\u8BF7<b>\u5173\u95ED\u5E76\u91CD\u65B0\u542F\u52A8 hs web</b> \u4EE5\u4F7F\u7528\u65B0\u7248\u672C\u3002';
9284
+ }else{
9285
+ prog.innerHTML='\u274C \u5347\u7EA7\u5931\u8D25 (exit='+s.exitCode+')<br>\u8BF7\u6253\u5F00\u7EC8\u7AEF\u8FD0\u884C: <code>npm i -g @simonyea/holysheep-cli@latest</code><br>\u65E5\u5FD7: <code>'+(s.logFile||'-')+'</code>';
9286
+ btn.disabled=false;btn.style.opacity='1';btn.textContent='\u91CD\u8BD5';
9287
+ }
9288
+ }).catch(function(){})
9289
+ },2000);
9290
+ }).catch(function(e){prog.textContent='\u8BF7\u6C42\u5931\u8D25: '+e.message});
9291
+ });
9292
+ });
9293
+ })();
9294
+ })();
9295
+ </script>`;
9296
+ }
9297
+ __name(_buildStartupBannerScript, "_buildStartupBannerScript");
9197
9298
  var BODYLESS_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
9198
9299
  function proxyHttp(req, res, internalPort) {
9199
9300
  const headers = { ...req.headers };
@@ -9218,6 +9319,32 @@ var require_aionui_wrapper = __commonJS({
9218
9319
  delete outHeaders["keep-alive"];
9219
9320
  delete outHeaders["proxy-connection"];
9220
9321
  rewriteCspHeaders(outHeaders);
9322
+ const contentType = (outHeaders["content-type"] || "").toLowerCase();
9323
+ const isHtml = contentType.includes("text/html");
9324
+ const bannerScript = isHtml ? _buildStartupBannerScript() : "";
9325
+ if (bannerScript) {
9326
+ delete outHeaders["content-length"];
9327
+ res.writeHead(upRes.statusCode, upRes.statusMessage, outHeaders);
9328
+ const chunks = [];
9329
+ upRes.on("data", (c) => chunks.push(c));
9330
+ upRes.on("end", () => {
9331
+ let html = Buffer.concat(chunks).toString("utf8");
9332
+ const idx = html.lastIndexOf("</body>");
9333
+ if (idx !== -1) {
9334
+ html = html.slice(0, idx) + bannerScript + html.slice(idx);
9335
+ } else {
9336
+ html += bannerScript;
9337
+ }
9338
+ res.end(html);
9339
+ });
9340
+ upRes.on("error", () => {
9341
+ try {
9342
+ res.end();
9343
+ } catch {
9344
+ }
9345
+ });
9346
+ return;
9347
+ }
9221
9348
  res.writeHead(upRes.statusCode, upRes.statusMessage, outHeaders);
9222
9349
  upRes.pipe(res);
9223
9350
  });
@@ -9398,6 +9525,30 @@ var require_aionui_wrapper = __commonJS({
9398
9525
  aionuiSource: ctx.runtimeSource
9399
9526
  });
9400
9527
  }
9528
+ if (route === "/api/holysheep/__wrapper/startup-warnings" && req.method === "GET") {
9529
+ return sendJson(res, 200, {
9530
+ notInstalled: _startupWarnings.notInstalled,
9531
+ openclawNeedsPairing: _startupWarnings.openclawNeedsPairing
9532
+ });
9533
+ }
9534
+ if (route === "/api/holysheep/__wrapper/version-status" && req.method === "GET") {
9535
+ return sendJson(res, 200, _getVersionStatus());
9536
+ }
9537
+ if (route === "/api/holysheep/__wrapper/aionui-update" && req.method === "POST") {
9538
+ const result = _startDetachedNpmUpgrade();
9539
+ return sendJson(res, result.ok ? 200 : 409, result);
9540
+ }
9541
+ if (route === "/api/holysheep/__wrapper/aionui-update" && req.method === "GET") {
9542
+ return sendJson(res, 200, {
9543
+ status: _aionuiUpgrade.status,
9544
+ pid: _aionuiUpgrade.pid,
9545
+ logFile: _aionuiUpgrade.logFile,
9546
+ startedAt: _aionuiUpgrade.startedAt,
9547
+ finishedAt: _aionuiUpgrade.finishedAt,
9548
+ exitCode: _aionuiUpgrade.exitCode,
9549
+ message: _aionuiUpgrade.message
9550
+ });
9551
+ }
9401
9552
  return proxyHttp(req, res, ctx.internalPort);
9402
9553
  } catch (e) {
9403
9554
  try {
@@ -9479,7 +9630,7 @@ var require_aionui_wrapper = __commonJS({
9479
9630
  log("skipping auto-config for all CLI tools: no HolySheep apiKey available");
9480
9631
  return;
9481
9632
  }
9482
- const summary = { configured: [], skipped: [], failed: [] };
9633
+ const summary = { configured: [], skipped: [], failed: [], notInstalled: [] };
9483
9634
  try {
9484
9635
  _ensureClaudeProxyConfig(apiKey);
9485
9636
  summary.configured.push("claude-code");
@@ -9515,6 +9666,17 @@ var require_aionui_wrapper = __commonJS({
9515
9666
  ];
9516
9667
  for (const s of siblings) {
9517
9668
  try {
9669
+ let installed = true;
9670
+ try {
9671
+ installed = typeof s.tool.checkInstalled === "function" ? Boolean(s.tool.checkInstalled()) : true;
9672
+ } catch {
9673
+ installed = true;
9674
+ }
9675
+ if (!installed) {
9676
+ summary.notInstalled.push(s.id);
9677
+ log(`${s.id} not installed \u2014 skipping auto-config (binary not found)`);
9678
+ continue;
9679
+ }
9518
9680
  let already = false;
9519
9681
  try {
9520
9682
  already = typeof s.tool.isConfigured === "function" ? Boolean(s.tool.isConfigured()) : false;
@@ -9539,10 +9701,133 @@ var require_aionui_wrapper = __commonJS({
9539
9701
  log(`warn: auto-config ${s.id} failed: ${err && err.message ? err.message : err}`);
9540
9702
  }
9541
9703
  }
9542
- log(`CLI auto-config summary: configured=[${summary.configured.join(",")}] skipped=[${summary.skipped.join(",")}] failed=[${summary.failed.map((f) => f.tool).join(",")}]`);
9704
+ log(`CLI auto-config summary: configured=[${summary.configured.join(",")}] skipped=[${summary.skipped.join(",")}] failed=[${summary.failed.map((f) => f.tool).join(",")}] notInstalled=[${summary.notInstalled.join(",")}]`);
9543
9705
  return summary;
9544
9706
  }
9545
9707
  __name(_ensureAllClisConfigured, "_ensureAllClisConfigured");
9708
+ function _checkOpenClawPairingNeeded() {
9709
+ var _a, _b;
9710
+ try {
9711
+ if (typeof openclawTool.checkInstalled !== "function" || !openclawTool.checkInstalled()) return false;
9712
+ if (typeof openclawTool.isConfigured !== "function" || !openclawTool.isConfigured()) return false;
9713
+ const OPENCLAW_CONFIG_FILE = path.join(os.homedir(), ".openclaw", "openclaw.json");
9714
+ if (!fs.existsSync(OPENCLAW_CONFIG_FILE)) return false;
9715
+ let cfg;
9716
+ try {
9717
+ cfg = JSON.parse(fs.readFileSync(OPENCLAW_CONFIG_FILE, "utf8"));
9718
+ } catch {
9719
+ return false;
9720
+ }
9721
+ const authMode = (_b = (_a = cfg == null ? void 0 : cfg.gateway) == null ? void 0 : _a.auth) == null ? void 0 : _b.mode;
9722
+ return authMode !== void 0 && authMode !== "none";
9723
+ } catch {
9724
+ return false;
9725
+ }
9726
+ }
9727
+ __name(_checkOpenClawPairingNeeded, "_checkOpenClawPairingNeeded");
9728
+ var VERSION_CACHE_FILE = path.join(os.homedir(), ".holysheep", "last-version-check.json");
9729
+ var UPGRADE_LOG_FILE = path.join(os.homedir(), ".holysheep", "auto-update.log");
9730
+ var PACKAGE_NAME = "@simonyea/holysheep-cli";
9731
+ function _readLocalCliVersion() {
9732
+ try {
9733
+ return require_package().version || null;
9734
+ } catch {
9735
+ return null;
9736
+ }
9737
+ }
9738
+ __name(_readLocalCliVersion, "_readLocalCliVersion");
9739
+ function _readNpmCacheLatest() {
9740
+ try {
9741
+ if (!fs.existsSync(VERSION_CACHE_FILE)) return null;
9742
+ const j = JSON.parse(fs.readFileSync(VERSION_CACHE_FILE, "utf8"));
9743
+ if (j && typeof j.remote === "string") return j.remote;
9744
+ } catch {
9745
+ }
9746
+ return null;
9747
+ }
9748
+ __name(_readNpmCacheLatest, "_readNpmCacheLatest");
9749
+ function _semverCmp(a, b) {
9750
+ const pa = String(a || "").replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
9751
+ const pb = String(b || "").replace(/^v/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
9752
+ if (!pa || !pb) return 0;
9753
+ for (let i = 1; i <= 3; i++) {
9754
+ const da = Number(pa[i]) - Number(pb[i]);
9755
+ if (da !== 0) return da;
9756
+ }
9757
+ return 0;
9758
+ }
9759
+ __name(_semverCmp, "_semverCmp");
9760
+ function _getVersionStatus() {
9761
+ const current = _readLocalCliVersion();
9762
+ const latest = _readNpmCacheLatest();
9763
+ let upgradeAvailable = false;
9764
+ if (current && latest) {
9765
+ upgradeAvailable = _semverCmp(latest, current) > 0;
9766
+ }
9767
+ return {
9768
+ cli: { current, latest, upgradeAvailable },
9769
+ upgradeAvailable
9770
+ };
9771
+ }
9772
+ __name(_getVersionStatus, "_getVersionStatus");
9773
+ function _startDetachedNpmUpgrade() {
9774
+ if (_aionuiUpgrade.status === "running") {
9775
+ return { ok: false, message: "\u5DF2\u6709\u5347\u7EA7\u4EFB\u52A1\u5728\u8FD0\u884C" };
9776
+ }
9777
+ try {
9778
+ fs.mkdirSync(path.dirname(UPGRADE_LOG_FILE), { recursive: true });
9779
+ const header = `[${(/* @__PURE__ */ new Date()).toISOString()}] starting auto-update of ${PACKAGE_NAME}
9780
+ [platform=${process.platform}] [pid-parent=${process.pid}]
9781
+ `;
9782
+ fs.writeFileSync(UPGRADE_LOG_FILE, header);
9783
+ const out = fs.openSync(UPGRADE_LOG_FILE, "a");
9784
+ const isWin = process.platform === "win32";
9785
+ const cmd = isWin ? "npm.cmd" : "npm";
9786
+ const args = ["i", "-g", `${PACKAGE_NAME}@latest`];
9787
+ const child = spawn(cmd, args, {
9788
+ detached: true,
9789
+ stdio: ["ignore", out, out],
9790
+ windowsHide: true,
9791
+ shell: isWin
9792
+ // npm.cmd is a .cmd shim on Windows; needs shell to resolve via PATH
9793
+ });
9794
+ child.on("error", (err) => {
9795
+ _aionuiUpgrade.status = "error";
9796
+ _aionuiUpgrade.message = err.message;
9797
+ _aionuiUpgrade.finishedAt = nowMs();
9798
+ try {
9799
+ fs.appendFileSync(UPGRADE_LOG_FILE, `[error] spawn failed: ${err.message}
9800
+ `);
9801
+ } catch {
9802
+ }
9803
+ });
9804
+ child.on("exit", (code) => {
9805
+ _aionuiUpgrade.status = code === 0 ? "success" : "error";
9806
+ _aionuiUpgrade.exitCode = code;
9807
+ _aionuiUpgrade.finishedAt = nowMs();
9808
+ try {
9809
+ fs.appendFileSync(UPGRADE_LOG_FILE, `[done] exit code=${code}
9810
+ `);
9811
+ } catch {
9812
+ }
9813
+ });
9814
+ child.unref();
9815
+ _aionuiUpgrade.status = "running";
9816
+ _aionuiUpgrade.pid = child.pid;
9817
+ _aionuiUpgrade.logFile = UPGRADE_LOG_FILE;
9818
+ _aionuiUpgrade.startedAt = nowMs();
9819
+ _aionuiUpgrade.finishedAt = null;
9820
+ _aionuiUpgrade.exitCode = null;
9821
+ _aionuiUpgrade.message = "";
9822
+ log(`detached npm upgrade started (pid=${child.pid}, log=${UPGRADE_LOG_FILE})`);
9823
+ return { ok: true, pid: child.pid, logFile: UPGRADE_LOG_FILE };
9824
+ } catch (e) {
9825
+ _aionuiUpgrade.status = "error";
9826
+ _aionuiUpgrade.message = e.message;
9827
+ return { ok: false, message: e.message };
9828
+ }
9829
+ }
9830
+ __name(_startDetachedNpmUpgrade, "_startDetachedNpmUpgrade");
9546
9831
  function _ensureClaudeProxyConfig(apiKey) {
9547
9832
  const config = claudeProcessProxy.readConfig();
9548
9833
  const next = claudeCodeTool.buildBridgeConfig(apiKey, BASE_URL_ANTHROPIC, {
@@ -9667,11 +9952,25 @@ var require_aionui_wrapper = __commonJS({
9667
9952
  return null;
9668
9953
  }
9669
9954
  })();
9670
- if (__apiKeyForAutoConfig) _ensureAllClisConfigured(__apiKeyForAutoConfig);
9671
- else log("CLI auto-config skipped: no HolySheep apiKey (run `hs login`)");
9955
+ if (__apiKeyForAutoConfig) {
9956
+ const summary = _ensureAllClisConfigured(__apiKeyForAutoConfig);
9957
+ if (summary && summary.notInstalled && summary.notInstalled.length > 0) {
9958
+ _startupWarnings.notInstalled = summary.notInstalled;
9959
+ }
9960
+ } else {
9961
+ log("CLI auto-config skipped: no HolySheep apiKey (run `hs login`)");
9962
+ }
9672
9963
  } catch (e) {
9673
9964
  log("warn: CLI auto-config error (continuing): " + (e && e.message ? e.message : e));
9674
9965
  }
9966
+ try {
9967
+ _startupWarnings.openclawNeedsPairing = _checkOpenClawPairingNeeded();
9968
+ if (_startupWarnings.openclawNeedsPairing) {
9969
+ log('warn: OpenClaw gateway auth.mode is not "none" \u2014 users will see "pairing required" errors. Run `hs openclaw` to fix.');
9970
+ }
9971
+ } catch (e) {
9972
+ log("warn: OpenClaw pairing check failed (continuing): " + (e && e.message ? e.message : e));
9973
+ }
9675
9974
  const claudeProxyHandle = await ensureClaudeProcessProxyRunning();
9676
9975
  ensureOpenClawBridgeRunning();
9677
9976
  const debug = process.env.HS_WEB_DEBUG === "1";
@@ -9829,7 +10128,12 @@ ${tail.split(/\r?\n/).map((ln) => ` ${ln}`).join("\n")}
9829
10128
  ensureOpenClawBridgeRunning,
9830
10129
  rewriteCspHeaders,
9831
10130
  getOpenClawOrigins,
9832
- appendOriginsToDirective
10131
+ appendOriginsToDirective,
10132
+ // [HolySheep v2.1.54] Version-status / upgrade helpers
10133
+ _getVersionStatus,
10134
+ _semverCmp,
10135
+ _readNpmCacheLatest,
10136
+ VERSION_CACHE_FILE
9833
10137
  };
9834
10138
  }
9835
10139
  });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "2.1.52",
3
+ "version": "2.1.54",
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/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/version-check.test.js && node tests/runclaude-missing-binary.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/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/version-check.test.js && node tests/runclaude-missing-binary.test.js",
8
8
  "prepublishOnly": "npm run build && npm test && node scripts/check-tarball-size.js"
9
9
  },
10
10
  "keywords": [