pennyrouter 0.3.49 → 0.3.50

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/src/launch.js +22 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pennyrouter",
3
- "version": "0.3.49",
3
+ "version": "0.3.50",
4
4
  "description": "Install and manage PennyRouter local coding-agent integrations.",
5
5
  "homepage": "https://pennyrouter.com",
6
6
  "bugs": {
package/src/launch.js CHANGED
@@ -1542,6 +1542,26 @@ export async function runPennyClaudeStats(args, profile) {
1542
1542
  return result.code ?? 1;
1543
1543
  }
1544
1544
 
1545
+ /** Stop a Penny Compare server already listening on `port`; any other listener is left alone. */
1546
+ async function stopRunningPennyCompare(port) {
1547
+ if (process.platform === "win32") return;
1548
+ const listeners = spawnSync("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"], { encoding: "utf8" });
1549
+ const pids = (listeners.stdout || "").split("\n").map(Number).filter((pid) => pid > 0 && pid !== process.pid);
1550
+ for (const pid of pids) {
1551
+ const command = spawnSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" }).stdout || "";
1552
+ if (!/web-demo[\\/]server\.mjs/.test(command)) {
1553
+ throw new Error(`Port ${port} is in use by another program (pid ${pid}). Stop it or pass --port=<other>.`);
1554
+ }
1555
+ console.log(`Stopping the existing Penny Compare session (pid ${pid}).`);
1556
+ process.kill(pid, "SIGTERM");
1557
+ for (let waited = 0; waited < 3000; waited += 100) {
1558
+ try { process.kill(pid, 0); } catch { break; }
1559
+ await new Promise((done) => setTimeout(done, 100));
1560
+ }
1561
+ try { process.kill(pid, 0); process.kill(pid, "SIGKILL"); } catch {}
1562
+ }
1563
+ }
1564
+
1545
1565
  /** Launch the separately installed Penny Compare app from the `penny` command. */
1546
1566
  async function runPennyCompare(args) {
1547
1567
  const compareDir = pennyCompareDir();
@@ -1551,6 +1571,8 @@ async function runPennyCompare(args) {
1551
1571
  } catch {
1552
1572
  throw new Error("Penny Compare is not installed. Run `npx pennyrouter compare` first.");
1553
1573
  }
1574
+ const portArg = args.find((arg) => /^--port=\d+$/.test(arg));
1575
+ await stopRunningPennyCompare(Number(portArg?.slice("--port=".length) ?? 8789));
1554
1576
  const child = spawn(process.execPath, [executable, "--compare", ...args], {
1555
1577
  cwd: process.cwd(), env: process.env, stdio: "inherit",
1556
1578
  });