@simonyea/holysheep-cli 2.1.43 → 2.1.45

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.
@@ -76,21 +76,25 @@ var require_claude_process_proxy = __commonJS({
76
76
  var HOLYSHEEP_DIR = path.join(os.homedir(), ".holysheep");
77
77
  var CONFIG_PATH = path.join(HOLYSHEEP_DIR, "claude-proxy.json");
78
78
  var DEFAULT_PROXY_PORT = 14556;
79
+ var LOCAL_PING_PATH = "/__hs_local_ping__";
80
+ var LOCAL_PING_HEADER = "x-hs-local-proxy";
81
+ var LOCAL_PING_HEADER_VALUE = "1";
79
82
  function ensureDir() {
80
83
  if (!fs.existsSync(HOLYSHEEP_DIR)) fs.mkdirSync(HOLYSHEEP_DIR, { recursive: true });
81
84
  }
82
85
  __name(ensureDir, "ensureDir");
83
- function readConfig() {
86
+ function readConfig(configPath) {
84
87
  try {
85
- return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
88
+ return JSON.parse(fs.readFileSync(configPath || CONFIG_PATH, "utf8"));
86
89
  } catch {
87
90
  return {};
88
91
  }
89
92
  }
90
93
  __name(readConfig, "readConfig");
91
- function writeConfig(data) {
92
- ensureDir();
93
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(data, null, 2), "utf8");
94
+ function writeConfig(data, configPath) {
95
+ const target = configPath || CONFIG_PATH;
96
+ if (!configPath) ensureDir();
97
+ fs.writeFileSync(target, JSON.stringify(data, null, 2), "utf8");
94
98
  }
95
99
  __name(writeConfig, "writeConfig");
96
100
  function getProcessProxyPort(config = readConfig()) {
@@ -572,6 +576,33 @@ var require_claude_process_proxy = __commonJS({
572
576
  __name(pipeWithCleanup, "pipeWithCleanup");
573
577
  function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH, allowAnthropicConnect = false }) {
574
578
  const server = http.createServer(async (clientReq, clientRes) => {
579
+ if (clientReq.method === "GET" && !clientReq.url.startsWith("http")) {
580
+ const u = clientReq.url.split("?")[0];
581
+ if (u === LOCAL_PING_PATH) {
582
+ const hostHeader = String(clientReq.headers.host || "").toLowerCase();
583
+ const isLoopbackHost = hostHeader.startsWith("127.0.0.1") || hostHeader.startsWith("localhost") || hostHeader.startsWith("[::1]");
584
+ if (!isLoopbackHost) {
585
+ clientRes.writeHead(404, { "content-type": "text/plain" });
586
+ clientRes.end("not found");
587
+ return;
588
+ }
589
+ const body = JSON.stringify({
590
+ hsLocalProxy: true,
591
+ sessionId: String(sessionId || ""),
592
+ pid: process.pid,
593
+ ts: Date.now()
594
+ });
595
+ clientRes.writeHead(200, {
596
+ "content-type": "application/json",
597
+ [LOCAL_PING_HEADER]: LOCAL_PING_HEADER_VALUE,
598
+ "cache-control": "no-store",
599
+ "content-length": String(Buffer.byteLength(body)),
600
+ "connection": "close"
601
+ });
602
+ clientRes.end(body);
603
+ return;
604
+ }
605
+ }
575
606
  const isDirect = !clientReq.url.startsWith("http");
576
607
  if (ENABLE_TIMING_LOG) {
577
608
  console.error(
@@ -885,7 +916,16 @@ ${body}`);
885
916
  }
886
917
  });
887
918
  server.once("listening", () => {
888
- resolve({ server, port: server.address().port, sessionId: effectiveSessionId });
919
+ const boundPort = server.address().port;
920
+ try {
921
+ const latest = readConfig(configPath);
922
+ if (Number(latest.processProxyPort) !== boundPort) {
923
+ writeConfig({ ...latest, processProxyPort: boundPort }, configPath);
924
+ }
925
+ } catch (persistErr) {
926
+ console.error("[hs-claude-proxy] warn: failed to persist processProxyPort:", persistErr && persistErr.message);
927
+ }
928
+ resolve({ server, port: boundPort, sessionId: effectiveSessionId });
889
929
  });
890
930
  server.listen(p, "127.0.0.1");
891
931
  }, "tryListen");
@@ -931,7 +971,10 @@ ${body}`);
931
971
  getControlPlaneUrl,
932
972
  readConfig,
933
973
  startProcessProxy,
934
- writeConfig
974
+ writeConfig,
975
+ LOCAL_PING_PATH,
976
+ LOCAL_PING_HEADER,
977
+ LOCAL_PING_HEADER_VALUE
935
978
  };
936
979
  }
937
980
  });
@@ -3931,11 +3974,11 @@ var require_package = __commonJS({
3931
3974
  "package.json"(exports2, module2) {
3932
3975
  module2.exports = {
3933
3976
  name: "@simonyea/holysheep-cli",
3934
- version: "2.1.43",
3977
+ version: "2.1.45",
3935
3978
  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.",
3936
3979
  scripts: {
3937
3980
  build: "node scripts/build.mjs",
3938
- 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-wrapper-claude-proxy.test.js",
3981
+ 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-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js",
3939
3982
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
3940
3983
  },
3941
3984
  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.43",
15
+ version: "2.1.45",
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-wrapper-claude-proxy.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-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js",
20
20
  prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
21
21
  },
22
22
  keywords: [
@@ -752,21 +752,25 @@ var require_claude_process_proxy = __commonJS({
752
752
  var HOLYSHEEP_DIR = path.join(os.homedir(), ".holysheep");
753
753
  var CONFIG_PATH = path.join(HOLYSHEEP_DIR, "claude-proxy.json");
754
754
  var DEFAULT_PROXY_PORT = 14556;
755
+ var LOCAL_PING_PATH = "/__hs_local_ping__";
756
+ var LOCAL_PING_HEADER = "x-hs-local-proxy";
757
+ var LOCAL_PING_HEADER_VALUE = "1";
755
758
  function ensureDir() {
756
759
  if (!fs.existsSync(HOLYSHEEP_DIR)) fs.mkdirSync(HOLYSHEEP_DIR, { recursive: true });
757
760
  }
758
761
  __name(ensureDir, "ensureDir");
759
- function readConfig() {
762
+ function readConfig(configPath) {
760
763
  try {
761
- return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
764
+ return JSON.parse(fs.readFileSync(configPath || CONFIG_PATH, "utf8"));
762
765
  } catch {
763
766
  return {};
764
767
  }
765
768
  }
766
769
  __name(readConfig, "readConfig");
767
- function writeConfig(data) {
768
- ensureDir();
769
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(data, null, 2), "utf8");
770
+ function writeConfig(data, configPath) {
771
+ const target = configPath || CONFIG_PATH;
772
+ if (!configPath) ensureDir();
773
+ fs.writeFileSync(target, JSON.stringify(data, null, 2), "utf8");
770
774
  }
771
775
  __name(writeConfig, "writeConfig");
772
776
  function getProcessProxyPort(config = readConfig()) {
@@ -1248,6 +1252,33 @@ var require_claude_process_proxy = __commonJS({
1248
1252
  __name(pipeWithCleanup, "pipeWithCleanup");
1249
1253
  function createProcessProxyServer({ sessionId, configPath = CONFIG_PATH, allowAnthropicConnect = false }) {
1250
1254
  const server = http.createServer(async (clientReq, clientRes) => {
1255
+ if (clientReq.method === "GET" && !clientReq.url.startsWith("http")) {
1256
+ const u = clientReq.url.split("?")[0];
1257
+ if (u === LOCAL_PING_PATH) {
1258
+ const hostHeader = String(clientReq.headers.host || "").toLowerCase();
1259
+ const isLoopbackHost = hostHeader.startsWith("127.0.0.1") || hostHeader.startsWith("localhost") || hostHeader.startsWith("[::1]");
1260
+ if (!isLoopbackHost) {
1261
+ clientRes.writeHead(404, { "content-type": "text/plain" });
1262
+ clientRes.end("not found");
1263
+ return;
1264
+ }
1265
+ const body = JSON.stringify({
1266
+ hsLocalProxy: true,
1267
+ sessionId: String(sessionId || ""),
1268
+ pid: process.pid,
1269
+ ts: Date.now()
1270
+ });
1271
+ clientRes.writeHead(200, {
1272
+ "content-type": "application/json",
1273
+ [LOCAL_PING_HEADER]: LOCAL_PING_HEADER_VALUE,
1274
+ "cache-control": "no-store",
1275
+ "content-length": String(Buffer.byteLength(body)),
1276
+ "connection": "close"
1277
+ });
1278
+ clientRes.end(body);
1279
+ return;
1280
+ }
1281
+ }
1251
1282
  const isDirect = !clientReq.url.startsWith("http");
1252
1283
  if (ENABLE_TIMING_LOG) {
1253
1284
  console.error(
@@ -1561,7 +1592,16 @@ ${body}`);
1561
1592
  }
1562
1593
  });
1563
1594
  server.once("listening", () => {
1564
- resolve({ server, port: server.address().port, sessionId: effectiveSessionId });
1595
+ const boundPort = server.address().port;
1596
+ try {
1597
+ const latest = readConfig(configPath);
1598
+ if (Number(latest.processProxyPort) !== boundPort) {
1599
+ writeConfig({ ...latest, processProxyPort: boundPort }, configPath);
1600
+ }
1601
+ } catch (persistErr) {
1602
+ console.error("[hs-claude-proxy] warn: failed to persist processProxyPort:", persistErr && persistErr.message);
1603
+ }
1604
+ resolve({ server, port: boundPort, sessionId: effectiveSessionId });
1565
1605
  });
1566
1606
  server.listen(p, "127.0.0.1");
1567
1607
  }, "tryListen");
@@ -1607,7 +1647,10 @@ ${body}`);
1607
1647
  getControlPlaneUrl,
1608
1648
  readConfig,
1609
1649
  startProcessProxy,
1610
- writeConfig
1650
+ writeConfig,
1651
+ LOCAL_PING_PATH,
1652
+ LOCAL_PING_HEADER,
1653
+ LOCAL_PING_HEADER_VALUE
1611
1654
  };
1612
1655
  }
1613
1656
  });
@@ -5828,9 +5871,9 @@ var require_aionui_runtime_fetcher = __commonJS({
5828
5871
  var http = require("http");
5829
5872
  var USER_CACHE_DIR = path.join(os.homedir(), ".holysheep", "aionui-runtime");
5830
5873
  var VENDOR_DIR = path.join(__dirname, "vendor", "aionui");
5831
- var DEFAULT_RUNTIME_URL = "https://mail.holysheep.ai/app/cli/aionui-runtime-v1.9.18-holysheep-hs28.tar.gz";
5832
- var DEFAULT_RUNTIME_SHA256 = "360568732da1b758fc8d1a32202d69fe03e9ac4dd8da3e3f92e8d0ec303ee8a4";
5833
- var DEFAULT_RUNTIME_VERSION = "1.9.18-holysheep-hs28";
5874
+ var DEFAULT_RUNTIME_URL = "https://mail.holysheep.ai/app/cli/aionui-runtime-v1.9.18-holysheep-hs32.tar.gz";
5875
+ var DEFAULT_RUNTIME_SHA256 = "7efafb298109f75a7e804fa1425a52cabe0d46ee39760fc54be14e80938f27c2";
5876
+ var DEFAULT_RUNTIME_VERSION = "1.9.18-holysheep-hs32";
5834
5877
  function isValidRuntimeDir(dir) {
5835
5878
  if (!dir) return false;
5836
5879
  try {
@@ -8988,10 +9031,13 @@ var require_aionui_wrapper = __commonJS({
8988
9031
  }, "onRequest");
8989
9032
  }
8990
9033
  __name(buildRouter, "buildRouter");
8991
- function probeLocalPort(port, timeoutMs = 500) {
9034
+ function probeLocalPort(port, timeoutMs = 800) {
8992
9035
  return new Promise((resolve) => {
8993
9036
  const socket = net.createConnection({ host: "127.0.0.1", port });
8994
- const timer = setTimeout(() => {
9037
+ let tcpSettled = false;
9038
+ const tcpTimer = setTimeout(() => {
9039
+ if (tcpSettled) return;
9040
+ tcpSettled = true;
8995
9041
  try {
8996
9042
  socket.destroy();
8997
9043
  } catch {
@@ -8999,15 +9045,53 @@ var require_aionui_wrapper = __commonJS({
8999
9045
  resolve(false);
9000
9046
  }, timeoutMs);
9001
9047
  socket.once("connect", () => {
9002
- clearTimeout(timer);
9048
+ if (tcpSettled) return;
9049
+ tcpSettled = true;
9050
+ clearTimeout(tcpTimer);
9003
9051
  try {
9004
9052
  socket.end();
9005
9053
  } catch {
9006
9054
  }
9007
- resolve(true);
9055
+ const req = http.request({
9056
+ host: "127.0.0.1",
9057
+ port,
9058
+ method: "GET",
9059
+ path: "/__hs_local_ping__",
9060
+ timeout: timeoutMs,
9061
+ headers: { "host": `127.0.0.1:${port}`, "connection": "close" }
9062
+ }, (res) => {
9063
+ const chunks = [];
9064
+ res.on("data", (c) => chunks.push(c));
9065
+ res.on("end", () => {
9066
+ const header = String(res.headers["x-hs-local-proxy"] || "");
9067
+ if (res.statusCode !== 200 || header !== "1") {
9068
+ resolve(false);
9069
+ return;
9070
+ }
9071
+ try {
9072
+ const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
9073
+ resolve(parsed && parsed.hsLocalProxy === true);
9074
+ } catch {
9075
+ resolve(false);
9076
+ }
9077
+ });
9078
+ res.on("error", () => resolve(false));
9079
+ });
9080
+ req.on("timeout", () => {
9081
+ try {
9082
+ req.destroy();
9083
+ } catch {
9084
+ }
9085
+ ;
9086
+ resolve(false);
9087
+ });
9088
+ req.on("error", () => resolve(false));
9089
+ req.end();
9008
9090
  });
9009
9091
  socket.once("error", () => {
9010
- clearTimeout(timer);
9092
+ if (tcpSettled) return;
9093
+ tcpSettled = true;
9094
+ clearTimeout(tcpTimer);
9011
9095
  resolve(false);
9012
9096
  });
9013
9097
  });
@@ -9019,11 +9103,31 @@ var require_aionui_wrapper = __commonJS({
9019
9103
  ...config,
9020
9104
  relayUrl: config.relayUrl || BASE_URL_CLAUDE_RELAY
9021
9105
  });
9106
+ let proxyConfigUpdated = false;
9022
9107
  if (JSON.stringify(next) !== JSON.stringify(config)) {
9023
9108
  claudeProcessProxy.writeConfig(next);
9024
- return next;
9109
+ proxyConfigUpdated = true;
9025
9110
  }
9026
- return config;
9111
+ try {
9112
+ const existing = claudeCodeTool.readSettings();
9113
+ const hasToken = existing && existing.env && existing.env.ANTHROPIC_AUTH_TOKEN === apiKey;
9114
+ const hasLauncherMark = existing && existing.env && existing.env.HOLYSHEEP_CLAUDE_LAUNCHER === "hs";
9115
+ if (!hasToken || !hasLauncherMark) {
9116
+ const settings = existing || {};
9117
+ if (!settings.env) settings.env = {};
9118
+ settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;
9119
+ delete settings.env.ANTHROPIC_BASE_URL;
9120
+ settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
9121
+ settings.env.HOLYSHEEP_CLAUDE_LAUNCHER = "hs";
9122
+ delete settings.env.ANTHROPIC_API_KEY;
9123
+ delete settings.env.HOLYSHEEP_CLAUDE_BRIDGE;
9124
+ claudeCodeTool.writeSettings(settings);
9125
+ log("auto-configured ~/.claude/settings.json with ANTHROPIC_AUTH_TOKEN (first-ever hs web for this user)");
9126
+ }
9127
+ } catch (e) {
9128
+ log("warn: failed to auto-configure ~/.claude/settings.json: " + (e && e.message ? e.message : e));
9129
+ }
9130
+ return proxyConfigUpdated ? next : config;
9027
9131
  }
9028
9132
  __name(_ensureClaudeProxyConfig, "_ensureClaudeProxyConfig");
9029
9133
  async function ensureClaudeProcessProxyRunning(opts = {}) {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "2.1.43",
3
+ "version": "2.1.45",
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-wrapper-claude-proxy.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-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js",
8
8
  "prepublishOnly": "npm run build && npm test && node scripts/check-tarball-size.js"
9
9
  },
10
10
  "keywords": [