panrouter 6.3.7 → 6.3.9

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pool-worker.mjs +38 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panrouter",
3
- "version": "6.3.7",
3
+ "version": "6.3.9",
4
4
  "description": "让 Claude Code 免费使用 DeepSeek 等模型,无需 API Key",
5
5
  "type": "module",
6
6
  "bin": {
package/pool-worker.mjs CHANGED
@@ -17,7 +17,13 @@ import path from "node:path";
17
17
  import fs from "node:fs";
18
18
  import { fileURLToPath } from "node:url";
19
19
  import crypto from "node:crypto";
20
+ import { createRequire } from "node:module";
20
21
  import WebSocket from "ws";
22
+
23
+ const _require = createRequire(import.meta.url);
24
+ const _pkg = _require("./package.json");
25
+ const NODE_VERSION = _pkg.version;
26
+
21
27
  const ROUTER_PORT = 20128;
22
28
 
23
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -109,9 +115,10 @@ function connectToHub() {
109
115
 
110
116
  const registerMsg = JSON.stringify({
111
117
  type: "register",
112
- nodeId: assignedId || FINGERPRINT, // 已有分配 ID 就用它
118
+ nodeId: assignedId || FINGERPRINT,
113
119
  fingerprint: FINGERPRINT,
114
120
  deviceType: DEVICE_TYPE,
121
+ version: NODE_VERSION,
115
122
  secret: AUTH_SECRET,
116
123
  });
117
124
  ws.send(registerMsg);
@@ -145,6 +152,9 @@ function connectToHub() {
145
152
  ws.send(JSON.stringify({ type: "pong" }));
146
153
  break;
147
154
 
155
+ case "pong":
156
+ break;
157
+
148
158
  case "upgrade":
149
159
  handleUpgrade();
150
160
  break;
@@ -208,7 +218,9 @@ function handleUpgrade() {
208
218
  hasNewer = true;
209
219
  }
210
220
 
211
- if (hasNewer) {
221
+ // ponytail: Windows 跳过内联 install(当前进程锁着 npm 目录必 EBUSY)
222
+ // 后续 start /b 脚本在进程退出后再执行 install
223
+ if (hasNewer && process.platform !== 'win32') {
212
224
  try {
213
225
  execSync("npm install -g panrouter@latest", { stdio: "inherit", timeout: 120000 });
214
226
  } catch (e) {
@@ -216,26 +228,25 @@ function handleUpgrade() {
216
228
  }
217
229
  }
218
230
 
219
- // 从磁盘重新读(跳过 require 缓存)
220
- const newVersion = JSON.parse(fs.readFileSync(pkgPath, "utf-8")).version;
221
-
222
231
  log("正在重启 9router...");
223
232
  killPort(SERVER_PORT);
224
233
 
234
+ // Windows:无论如何走 start /b 脚本(当前进程锁着 npm 目录无法内联升级)
235
+ if (process.platform === 'win32') {
236
+ const tmpDir = process.env.TEMP || process.env.TMP || "C:\\Windows\\Temp";
237
+ // 如果已经是最新版也跳过 install
238
+ const noInstall = hasNewer ? "" : "& npm cache clean --force 2>nul & npm install -g panrouter@latest";
239
+ // 先 ping 等当前进程退出锁释放 → 杀残留 node → 切 tmp 目录避免被删 → install → 启动
240
+ const upgradeCmd = `start /b cmd /c "@ping 127.0.0.1 -n 3 >nul && taskkill /f /im node.exe 2>nul & ping 127.0.0.1 -n 3 >nul & cd /d \"${tmpDir}\"${noInstall} && panrouter --pool"`;
241
+ try { execSync(upgradeCmd, { stdio: 'pipe', timeout: 5000, shell: true }); } catch {}
242
+ log("升级脚本已提交 (当前进程退出后自动执行),旧进程退出", "OFF");
243
+ process.exit(0);
244
+ }
245
+
246
+ // Unix:检查版本,需要就 install,然后 spawn 新实例
247
+ const newVersion = JSON.parse(fs.readFileSync(pkgPath, "utf-8")).version;
225
248
  if (oldVersion !== newVersion) {
226
249
  log(`版本变更: v${oldVersion} → v${newVersion},升级并重启`, "OK");
227
-
228
- // Windows 下当前进程锁住了 npm 目录 → 先 exit 释放锁再 npm install
229
- // 用 start /b 提交一个后台脚本,等 2 秒(进程退出锁释放)后执行升级 + 启动
230
- // start /b 的输出会打到当前终端,用户能看到进度
231
- if (process.platform === 'win32') {
232
- const cmd = `start /b cmd /c "@ping 127.0.0.1 -n 3 >nul && npm install -g panrouter@latest && panrouter --pool"`;
233
- try { execSync(cmd, { stdio: 'pipe', timeout: 5000, shell: true }); } catch {}
234
- log("升级脚本已提交 (当前进程退出后自动执行),旧进程退出", "OFF");
235
- process.exit(0);
236
- }
237
-
238
- // Unix 可以直接 spawn(不会锁)
239
250
  spawn(process.execPath, [process.argv[1], "--pool"], {
240
251
  cwd: __dirname,
241
252
  stdio: "inherit",
@@ -577,13 +588,20 @@ export async function start() {
577
588
 
578
589
  log("节点看门狗已启动,等待公网入口...", "ON");
579
590
 
580
- // 等 9router 起来后打开守护
591
+ // 等 9router 起来后打开守护 + 通知主控就绪
581
592
  const checkReady = setInterval(async () => {
582
593
  if (_serverReady || (await isPortOpen(SERVER_PORT))) {
583
594
  _serverReady = true;
584
- clearInterval(checkReady);
585
595
  startWatchdog();
586
- log("9router 已就绪,节点可正常处理请求", "ON");
596
+ // 持续发 ready 直到 WebSocket 连通(注册可能还没完成)
597
+ const tryReady = setInterval(() => {
598
+ if (ws && ws.readyState === WebSocket.OPEN) {
599
+ ws.send(JSON.stringify({ type: "ready" }));
600
+ clearInterval(tryReady);
601
+ clearInterval(checkReady);
602
+ log("9router 已就绪,节点可正常处理请求", "ON");
603
+ }
604
+ }, 1000);
587
605
  }
588
606
  }, 3000);
589
607
  }