@hienlh/ppm 0.13.30 → 0.13.31
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/CHANGELOG.md +5 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/package.json +1 -1
- package/src/cli/commands/restart.ts +8 -3
- package/src/server/index.ts +15 -4
- package/src/services/supervisor-state.ts +1 -1
- package/src/services/supervisor.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.13.31] - 2026-04-25
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Windows restart fails with SIGUSR2 error**: `ppm restart` on Windows threw `TypeError [ERR_UNKNOWN_SIGNAL]: Unknown signal: SIGUSR2` — Unix signals don't exist on Windows. Now writes command file that supervisor polls every 1s (same mechanism as upgrade). Also fixed `ppm start` sending SIGUSR1/SIGUSR2 directly on Windows for resume/upgrade paths
|
|
7
|
+
|
|
3
8
|
## [0.13.30] - 2026-04-25
|
|
4
9
|
|
|
5
10
|
### Fixed
|
|
@@ -71,4 +71,4 @@ This skill covers the `ppm` CLI, its HTTP API, and its config DB. It does **not*
|
|
|
71
71
|
- Third-party extensions (inspect via `ppm ext list`).
|
|
72
72
|
- The Claude Agent SDK internals (separate skill).
|
|
73
73
|
|
|
74
|
-
<!-- Generated for PPM v0.13.
|
|
74
|
+
<!-- Generated for PPM v0.13.31 at build time. Re-run `ppm export skill --install` to refresh. -->
|
|
@@ -201,4 +201,4 @@ _Base URL: `http://localhost:8080` (default; override via `ppm config set port <
|
|
|
201
201
|
- `ws://<host>/ws/terminal` — PTY terminal multiplexer
|
|
202
202
|
- `ws://<host>/ws/extensions` — extension host channel
|
|
203
203
|
|
|
204
|
-
<!-- Generated from src/server/routes/ for PPM v0.13.
|
|
204
|
+
<!-- Generated from src/server/routes/ for PPM v0.13.31 -->
|
package/package.json
CHANGED
|
@@ -74,9 +74,14 @@ export async function restartServer(options: { force?: boolean }) {
|
|
|
74
74
|
console.log("\n Restarting PPM server via supervisor...");
|
|
75
75
|
console.log(" If you're using PPM terminal, wait a few seconds for auto-reconnect.\n");
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
if (process.platform === "win32") {
|
|
78
|
+
const cmdFile = resolve(getPpmDir(), ".supervisor-cmd");
|
|
79
|
+
writeFileSync(cmdFile, JSON.stringify({ action: "restart" }));
|
|
80
|
+
} else {
|
|
81
|
+
try { process.kill(supervisorPid, "SIGUSR2"); } catch (e) {
|
|
82
|
+
console.error(` ✗ Failed to signal supervisor: ${e}`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
// Wait for new server PID to appear in status.json (up to 15s)
|
package/src/server/index.ts
CHANGED
|
@@ -269,15 +269,26 @@ export async function startServer(options: {
|
|
|
269
269
|
const state = status.state as string;
|
|
270
270
|
const runningVersion = status.serverVersion as string;
|
|
271
271
|
|
|
272
|
+
// Helper: send signal (Unix) or write command file (Windows)
|
|
273
|
+
const signalSupervisor = (signal: "SIGUSR1" | "SIGUSR2", cmdAction?: string) => {
|
|
274
|
+
if (process.platform === "win32") {
|
|
275
|
+
const cmdFile = resolve(ppmDir, ".supervisor-cmd");
|
|
276
|
+
const action = cmdAction ?? (signal === "SIGUSR1" ? "upgrade" : "restart");
|
|
277
|
+
writeFileSync(cmdFile, JSON.stringify({ action }));
|
|
278
|
+
} else {
|
|
279
|
+
process.kill(supervisorPid, signal);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
272
283
|
if (state === "stopped") {
|
|
273
284
|
console.log(" Supervisor is alive (stopped state). Resuming server...");
|
|
274
285
|
if (runningVersion !== VERSION) {
|
|
275
286
|
console.log(` Upgrading: ${runningVersion} -> ${VERSION}`);
|
|
276
|
-
|
|
287
|
+
signalSupervisor("SIGUSR1");
|
|
277
288
|
await waitForNewSupervisor(statusFile, supervisorPid);
|
|
278
289
|
} else {
|
|
279
290
|
writeCmd("resume");
|
|
280
|
-
|
|
291
|
+
signalSupervisor("SIGUSR2", "resume");
|
|
281
292
|
await waitForServerReady(statusFile, port);
|
|
282
293
|
}
|
|
283
294
|
return;
|
|
@@ -286,7 +297,7 @@ export async function startServer(options: {
|
|
|
286
297
|
if (state === "running") {
|
|
287
298
|
if (runningVersion !== VERSION) {
|
|
288
299
|
console.log(` Supervisor running (v${runningVersion}). Upgrading to v${VERSION}...`);
|
|
289
|
-
|
|
300
|
+
signalSupervisor("SIGUSR1");
|
|
290
301
|
await waitForNewSupervisor(statusFile, supervisorPid);
|
|
291
302
|
} else {
|
|
292
303
|
console.log(`\n PPM is already running (PID: ${supervisorPid}).`);
|
|
@@ -299,7 +310,7 @@ export async function startServer(options: {
|
|
|
299
310
|
if (state === "paused") {
|
|
300
311
|
console.log(" Supervisor is paused (max restarts). Sending resume...");
|
|
301
312
|
writeCmd("resume");
|
|
302
|
-
|
|
313
|
+
signalSupervisor("SIGUSR2", "resume");
|
|
303
314
|
await waitForServerReady(statusFile, port);
|
|
304
315
|
return;
|
|
305
316
|
}
|
|
@@ -71,7 +71,7 @@ export function writeStatus(data: Record<string, unknown>) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// ─── Command file protocol ─────────────────────────────────────────────
|
|
74
|
-
export type CmdAction = "soft_stop" | "resume";
|
|
74
|
+
export type CmdAction = "soft_stop" | "resume" | "restart";
|
|
75
75
|
|
|
76
76
|
/** Atomically claim + read command file (rename to .claimed, read, delete) */
|
|
77
77
|
export function readAndDeleteCmd(): { action: CmdAction } | null {
|
|
@@ -985,6 +985,15 @@ export async function runSupervisor(opts: {
|
|
|
985
985
|
else if (cmd.action === "resume") {
|
|
986
986
|
if (getState() === "stopped" || getState() === "paused") triggerResume();
|
|
987
987
|
}
|
|
988
|
+
else if (cmd.action === "restart") {
|
|
989
|
+
log("INFO", "Windows command: restart server only");
|
|
990
|
+
if (getState() === "paused" || getState() === "stopped") {
|
|
991
|
+
triggerResume();
|
|
992
|
+
} else if (serverChild) {
|
|
993
|
+
serverRestartRequested = true;
|
|
994
|
+
try { serverChild.kill(); } catch {}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
988
997
|
else if (cmd.action === "upgrade") {
|
|
989
998
|
log("INFO", "Windows command: upgrade, starting self-replace");
|
|
990
999
|
selfReplace().then((result) => {
|