chatccc 0.2.163 → 0.2.165
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/package.json +1 -1
- package/src/orchestrator.ts +38 -24
package/package.json
CHANGED
package/src/orchestrator.ts
CHANGED
|
@@ -177,39 +177,47 @@ function updLog(msg: string): void {
|
|
|
177
177
|
try { appendFileSync(UPDATEG_LOG, `${ts} [UPG-SYNC] ${msg}\n`, "utf-8"); } catch {}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
/** 同步更新 npm
|
|
180
|
+
/** 同步更新 npm 全局包。不自行 spawn 新进程,而是 exit(1) 让 systemd Restart=on-failure 拉起新版本。 */
|
|
181
181
|
function syncUpdateAndRestart(): void {
|
|
182
182
|
updLog(`sync update start, pid=${process.pid}`);
|
|
183
|
+
appendStartupTrace("updateg: sync update start", { pid: process.pid });
|
|
183
184
|
|
|
184
|
-
// 1. npm update
|
|
185
185
|
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
186
|
+
|
|
187
|
+
// 1. npm update
|
|
188
|
+
updLog(`running: ${npmCmd} update -g chatccc`);
|
|
189
|
+
appendStartupTrace("updateg: npm update begin", { npmCmd });
|
|
190
|
+
const t0 = Date.now();
|
|
186
191
|
try {
|
|
187
|
-
const out = execSync(`${npmCmd} update -g chatccc`, { encoding: "utf8", timeout: 120000, windowsHide: true });
|
|
188
|
-
|
|
192
|
+
const out = execSync(`${npmCmd} update -g chatccc 2>&1`, { encoding: "utf8", timeout: 120000, windowsHide: true });
|
|
193
|
+
const elapsed = Date.now() - t0;
|
|
194
|
+
updLog(`npm update OK (${elapsed}ms): ${out.slice(0, 500)}`);
|
|
195
|
+
appendStartupTrace("updateg: npm update OK", { elapsedMs: elapsed, outputLen: out.length });
|
|
189
196
|
} catch (e) {
|
|
190
|
-
const
|
|
191
|
-
|
|
197
|
+
const elapsed = Date.now() - t0;
|
|
198
|
+
const err = e as Error & { stderr?: string; stdout?: string; status?: number };
|
|
199
|
+
updLog(`npm update failed (${elapsed}ms): message=${err.message}, stderr=${(err.stderr || "").slice(0, 500)}, stdout=${(err.stdout || "").slice(0, 200)}`);
|
|
200
|
+
appendStartupTrace("updateg: npm update failed", { elapsedMs: elapsed, message: err.message, stderrLen: (err.stderr || "").length });
|
|
201
|
+
|
|
202
|
+
// fallback
|
|
203
|
+
updLog(`fallback: ${npmCmd} install -g chatccc@latest`);
|
|
204
|
+
appendStartupTrace("updateg: npm install fallback begin", { npmCmd });
|
|
205
|
+
const t1 = Date.now();
|
|
192
206
|
try {
|
|
193
|
-
const out2 = execSync(`${npmCmd} install -g chatccc@latest`, { encoding: "utf8", timeout: 120000, windowsHide: true });
|
|
194
|
-
|
|
207
|
+
const out2 = execSync(`${npmCmd} install -g chatccc@latest 2>&1`, { encoding: "utf8", timeout: 120000, windowsHide: true });
|
|
208
|
+
const elapsed2 = Date.now() - t1;
|
|
209
|
+
updLog(`npm install fallback OK (${elapsed2}ms): ${out2.slice(0, 500)}`);
|
|
210
|
+
appendStartupTrace("updateg: npm install fallback OK", { elapsedMs: elapsed2, outputLen: out2.length });
|
|
195
211
|
} catch (e2) {
|
|
196
|
-
|
|
212
|
+
const elapsed2 = Date.now() - t1;
|
|
213
|
+
const err2 = e2 as Error & { stderr?: string; stdout?: string };
|
|
214
|
+
updLog(`npm install fallback also failed (${elapsed2}ms): message=${err2.message}, stderr=${(err2.stderr || "").slice(0, 500)}`);
|
|
215
|
+
appendStartupTrace("updateg: npm install fallback failed", { elapsedMs: elapsed2, message: err2.message });
|
|
197
216
|
}
|
|
198
217
|
}
|
|
199
218
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const binName = process.platform === "win32" ? "chatccc.cmd" : "chatccc";
|
|
203
|
-
const binPath = npmPrefix ? join(npmPrefix, binName) : "chatccc";
|
|
204
|
-
try {
|
|
205
|
-
const child = spawn(binPath, [], { detached: true, stdio: "ignore", shell: true });
|
|
206
|
-
child.unref();
|
|
207
|
-
updLog(`spawn new chatccc OK, childPid=${child.pid}, bin=${binPath}`);
|
|
208
|
-
} catch (e) {
|
|
209
|
-
updLog(`spawn new chatccc failed: ${(e as Error).message}`);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
updLog("sync update done, parent exiting in 2s");
|
|
219
|
+
updLog("sync update done, exiting with code 1 to trigger systemd restart");
|
|
220
|
+
appendStartupTrace("updateg: sync update done, will exit(1) for systemd restart", { pid: process.pid });
|
|
213
221
|
}
|
|
214
222
|
|
|
215
223
|
// ---------------------------------------------------------------------------
|
|
@@ -267,7 +275,9 @@ export async function handleCommand(
|
|
|
267
275
|
|
|
268
276
|
if (textLower === "/updateg") {
|
|
269
277
|
logTrace(tid, "BRANCH", { cmd: "/updateg" });
|
|
270
|
-
|
|
278
|
+
const isGlobal = isRunningFromGlobalNpm();
|
|
279
|
+
appendStartupTrace("updateg: command received", { isGlobal, chatId });
|
|
280
|
+
if (!isGlobal) {
|
|
271
281
|
await platform.sendText(chatId, "当前进程非 npm 全局安装,无法使用 /updateg 更新。请通过 npm install -g chatccc 安装后使用。").catch(() => {});
|
|
272
282
|
logTrace(tid, "DONE", { outcome: "updateg_not_global" });
|
|
273
283
|
return;
|
|
@@ -276,7 +286,11 @@ export async function handleCommand(
|
|
|
276
286
|
logTrace(tid, "DONE", { outcome: "updateg" });
|
|
277
287
|
appendStartupTrace("updateg: sync update begin", { fromPid: process.pid });
|
|
278
288
|
syncUpdateAndRestart();
|
|
279
|
-
|
|
289
|
+
// exit(1) 而非 exit(0):systemd KillMode=control-group 下,exit(0) 会让
|
|
290
|
+
// systemd 判定服务正常结束并清理整个 cgroup(杀死刚 spawn 的子进程)。
|
|
291
|
+
// exit(1) 触发 Restart=on-failure,由 systemd 重新拉起 ExecStart,此时
|
|
292
|
+
// npm 已更新到新版本,服务正常重启。
|
|
293
|
+
setTimeout(() => process.exit(1), 2000);
|
|
280
294
|
return;
|
|
281
295
|
}
|
|
282
296
|
|