@hienlh/ppm 0.2.5 → 0.2.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -0,0 +1,75 @@
1
+ import { resolve } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { readFileSync, writeFileSync, existsSync, openSync } from "node:fs";
4
+
5
+ const STATUS_FILE = resolve(homedir(), ".ppm", "status.json");
6
+ const PID_FILE = resolve(homedir(), ".ppm", "ppm.pid");
7
+
8
+ /** Restart only the server process, keeping the tunnel alive */
9
+ export async function restartServer(options: { config?: string }) {
10
+ if (!existsSync(STATUS_FILE)) {
11
+ console.log("No PPM daemon running. Use 'ppm start' instead.");
12
+ process.exit(1);
13
+ }
14
+
15
+ let status: Record<string, unknown>;
16
+ try {
17
+ status = JSON.parse(readFileSync(STATUS_FILE, "utf-8"));
18
+ } catch {
19
+ console.log("Corrupt status file. Use 'ppm stop && ppm start' instead.");
20
+ process.exit(1);
21
+ }
22
+
23
+ const serverPid = status.pid as number | undefined;
24
+ if (!serverPid) {
25
+ console.log("No server PID found. Use 'ppm stop && ppm start' instead.");
26
+ process.exit(1);
27
+ }
28
+
29
+ // Kill old server process
30
+ try {
31
+ process.kill(serverPid);
32
+ console.log(` Stopped server (PID: ${serverPid})`);
33
+ } catch {
34
+ console.log(` Server already stopped (PID: ${serverPid})`);
35
+ }
36
+
37
+ // Brief pause for port release
38
+ await Bun.sleep(500);
39
+
40
+ // Reload config for new server
41
+ const { configService } = await import("../../services/config.service.ts");
42
+ configService.load(options.config);
43
+ const port = status.port as number ?? configService.get("port");
44
+ const host = status.host as string ?? configService.get("host");
45
+
46
+ // Spawn new server child process
47
+ const ppmDir = resolve(homedir(), ".ppm");
48
+ const logFile = resolve(ppmDir, "ppm.log");
49
+ const logFd = openSync(logFile, "a");
50
+ const child = Bun.spawn({
51
+ cmd: [
52
+ process.execPath, "run",
53
+ resolve(import.meta.dir, "../../server/index.ts"), "__serve__",
54
+ String(port), host, options.config ?? "",
55
+ ],
56
+ stdio: ["ignore", logFd, logFd],
57
+ env: process.env,
58
+ });
59
+ child.unref();
60
+
61
+ // Update status with new server PID, keep tunnel info
62
+ status.pid = child.pid;
63
+ writeFileSync(STATUS_FILE, JSON.stringify(status));
64
+ writeFileSync(PID_FILE, String(child.pid));
65
+
66
+ const { VERSION } = await import("../../version.ts");
67
+ console.log(`\n PPM v${VERSION} restarted (PID: ${child.pid})\n`);
68
+ console.log(` ➜ Local: http://localhost:${port}/`);
69
+ if (status.shareUrl) {
70
+ console.log(` ➜ Share: ${status.shareUrl} (tunnel kept alive)`);
71
+ }
72
+ console.log();
73
+
74
+ process.exit(0);
75
+ }
package/src/index.ts CHANGED
@@ -35,6 +35,15 @@ program
35
35
  await stopServer();
36
36
  });
37
37
 
38
+ program
39
+ .command("restart")
40
+ .description("Restart the server (keeps tunnel alive)")
41
+ .option("-c, --config <path>", "Path to config file")
42
+ .action(async (options) => {
43
+ const { restartServer } = await import("./cli/commands/restart.ts");
44
+ await restartServer(options);
45
+ });
46
+
38
47
  program
39
48
  .command("status")
40
49
  .description("Show PPM daemon status")
@@ -228,6 +228,12 @@ export async function startServer(options: {
228
228
  qr.generate(shareUrl, { small: true });
229
229
  }
230
230
 
231
+ console.log(` Commands:`);
232
+ console.log(` ppm restart Reload config (keeps tunnel URL)`);
233
+ console.log(` ppm stop Stop server & tunnel`);
234
+ console.log(` ppm logs -f Follow server logs`);
235
+ console.log();
236
+
231
237
  process.exit(0);
232
238
  }
233
239