modelstat 0.0.33 → 0.0.34
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/dist/cli.mjs +3 -3
- package/package.json +1 -1
- package/scripts/postinstall.mjs +63 -5
package/dist/cli.mjs
CHANGED
|
@@ -45129,7 +45129,7 @@ var init_scan = __esm({
|
|
|
45129
45129
|
init_pipeline2();
|
|
45130
45130
|
init_config2();
|
|
45131
45131
|
init_api();
|
|
45132
|
-
AGENT_VERSION = "agent-0.0.
|
|
45132
|
+
AGENT_VERSION = "agent-0.0.34";
|
|
45133
45133
|
BATCH_MAX_EVENTS = 2e3;
|
|
45134
45134
|
}
|
|
45135
45135
|
});
|
|
@@ -47221,7 +47221,7 @@ var init_daemon = __esm({
|
|
|
47221
47221
|
init_config2();
|
|
47222
47222
|
init_lock();
|
|
47223
47223
|
init_scan();
|
|
47224
|
-
AGENT_VERSION2 = "agent-0.0.
|
|
47224
|
+
AGENT_VERSION2 = "agent-0.0.34";
|
|
47225
47225
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
47226
47226
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
47227
47227
|
status = {
|
|
@@ -47646,7 +47646,7 @@ function tryOpenBrowser(url) {
|
|
|
47646
47646
|
return false;
|
|
47647
47647
|
}
|
|
47648
47648
|
}
|
|
47649
|
-
var AGENT_VERSION3 = "agent-0.0.
|
|
47649
|
+
var AGENT_VERSION3 = "agent-0.0.34";
|
|
47650
47650
|
function osFamily() {
|
|
47651
47651
|
const p = platform4();
|
|
47652
47652
|
if (p === "darwin") return "macos";
|
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -317,13 +317,71 @@ async function setupNativeNodeModules(installedBundle) {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
/**
|
|
320
|
-
* Kill any
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* lock
|
|
324
|
-
*
|
|
320
|
+
* Kill any modelstat-related process the service supervisor didn't
|
|
321
|
+
* reap. Two passes:
|
|
322
|
+
* (1) PID from ~/.modelstat/daemon.lock — the most reliable hit
|
|
323
|
+
* when the lock is fresh and our own daemon wrote it.
|
|
324
|
+
* (2) Process scan via `pgrep -f` on macOS/Linux — catches stray
|
|
325
|
+
* daemons launched by an OLDER bundle (different command
|
|
326
|
+
* line, different lock format), zombies that survived a
|
|
327
|
+
* launchd KeepAlive bounce, and the case where the user has
|
|
328
|
+
* BOTH the launchd-managed daemon AND a hand-spawned one
|
|
329
|
+
* running. The pattern is intentionally narrow
|
|
330
|
+
* (`modelstat\\.mjs`) so we don't kill `modelstatd` or any
|
|
331
|
+
* other process that happens to share a substring.
|
|
332
|
+
*
|
|
333
|
+
* SIGTERM first, escalate to SIGKILL after 2 s. All failures
|
|
334
|
+
* tolerated — we just want the new bundle to be the only modelstat
|
|
335
|
+
* process holding the lock when we restart.
|
|
325
336
|
*/
|
|
326
337
|
async function killStaleDaemon(stateDir) {
|
|
338
|
+
await killByLockfile(stateDir);
|
|
339
|
+
await killByProcessScan();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async function killByProcessScan() {
|
|
343
|
+
const { spawnSync } = await import("node:child_process");
|
|
344
|
+
// pgrep is on macOS by default, Linux via procps.
|
|
345
|
+
const r = spawnSync("pgrep", ["-f", "modelstat\\.mjs"], {
|
|
346
|
+
encoding: "utf8",
|
|
347
|
+
});
|
|
348
|
+
if (r.status !== 0 || !r.stdout) return;
|
|
349
|
+
const pids = r.stdout
|
|
350
|
+
.split(/\s+/)
|
|
351
|
+
.map((s) => Number(s))
|
|
352
|
+
.filter((n) => Number.isInteger(n) && n > 0 && n !== process.pid);
|
|
353
|
+
if (pids.length === 0) return;
|
|
354
|
+
for (const pid of pids) {
|
|
355
|
+
try {
|
|
356
|
+
process.kill(pid, "SIGTERM");
|
|
357
|
+
} catch {
|
|
358
|
+
/* gone or not ours */
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// Wait up to 2 s for graceful exits.
|
|
362
|
+
for (let i = 0; i < 20; i++) {
|
|
363
|
+
let alive = 0;
|
|
364
|
+
for (const pid of pids) {
|
|
365
|
+
try {
|
|
366
|
+
process.kill(pid, 0);
|
|
367
|
+
alive += 1;
|
|
368
|
+
} catch {
|
|
369
|
+
/* exited */
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (alive === 0) return;
|
|
373
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
374
|
+
}
|
|
375
|
+
for (const pid of pids) {
|
|
376
|
+
try {
|
|
377
|
+
process.kill(pid, "SIGKILL");
|
|
378
|
+
} catch {
|
|
379
|
+
/* gone or denied */
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async function killByLockfile(stateDir) {
|
|
327
385
|
const { readFileSync } = await import("node:fs");
|
|
328
386
|
const lockPath = join(stateDir, "daemon.lock");
|
|
329
387
|
let payload;
|