gm-skill 2.0.1516 → 2.0.1517
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/gm-plugkit/package.json +1 -1
- package/gm-plugkit/supervisor.js +37 -0
- package/gm.json +1 -1
- package/package.json +1 -1
package/gm-plugkit/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1517",
|
|
4
4
|
"description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/gm-plugkit/supervisor.js
CHANGED
|
@@ -23,6 +23,7 @@ fs.mkdirSync(spoolDir, { recursive: true });
|
|
|
23
23
|
const STATUS_PATH = path.join(spoolDir, '.status.json');
|
|
24
24
|
const SHUTDOWN_REASON_PATH = path.join(spoolDir, '.shutdown-reason.json');
|
|
25
25
|
const SUPERVISOR_PATH = path.join(spoolDir, '.supervisor.json');
|
|
26
|
+
const SUPERVISOR_PID_PATH = path.join(spoolDir, '.supervisor.pid');
|
|
26
27
|
const LOG_PATH = path.join(spoolDir, '.watcher.log');
|
|
27
28
|
const GM_LOG_ROOT = process.env.GM_LOG_DIR || path.join(os.homedir(), '.claude', 'gm-log');
|
|
28
29
|
|
|
@@ -66,6 +67,36 @@ function pidAlive(pid) {
|
|
|
66
67
|
try { process.kill(pid, 0); return true; } catch (_) { return false; }
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
// Single-instance guard. findSupervisorPid (skill-bootstrap.js) reads .supervisor.pid to early-return
|
|
71
|
+
// when a supervisor is already running; without it every bootstrap spawns a duplicate supervisor,
|
|
72
|
+
// and duplicates spawn duplicate watchers that lock-fight in an endless spawn-reject churn. Write the
|
|
73
|
+
// pid file on startup and refuse to start if a live peer already holds it.
|
|
74
|
+
function acquireSingleInstance() {
|
|
75
|
+
try {
|
|
76
|
+
if (fs.existsSync(SUPERVISOR_PID_PATH)) {
|
|
77
|
+
const other = parseInt(fs.readFileSync(SUPERVISOR_PID_PATH, 'utf-8').trim(), 10);
|
|
78
|
+
if (Number.isFinite(other) && other !== process.pid && pidAlive(other)) {
|
|
79
|
+
logEvent('supervisor.refused-duplicate', { existing_pid: other, severity: 'warn' });
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
fs.writeFileSync(SUPERVISOR_PID_PATH, String(process.pid));
|
|
84
|
+
return true;
|
|
85
|
+
} catch (e) {
|
|
86
|
+
logEvent('supervisor.pid-write-failed', { error: e.message, severity: 'warn' });
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function releaseSingleInstance() {
|
|
92
|
+
try {
|
|
93
|
+
if (fs.existsSync(SUPERVISOR_PID_PATH)) {
|
|
94
|
+
const raw = fs.readFileSync(SUPERVISOR_PID_PATH, 'utf-8').trim();
|
|
95
|
+
if (parseInt(raw, 10) === process.pid) fs.unlinkSync(SUPERVISOR_PID_PATH);
|
|
96
|
+
}
|
|
97
|
+
} catch (_) {}
|
|
98
|
+
}
|
|
99
|
+
|
|
69
100
|
function readStatus() {
|
|
70
101
|
try { return JSON.parse(fs.readFileSync(STATUS_PATH, 'utf-8')); } catch (_) { return null; }
|
|
71
102
|
}
|
|
@@ -273,9 +304,15 @@ process.on('SIGTERM', () => {
|
|
|
273
304
|
if (currentChildPid && pidAlive(currentChildPid)) {
|
|
274
305
|
try { process.kill(currentChildPid, 'SIGTERM'); } catch (_) {}
|
|
275
306
|
}
|
|
307
|
+
releaseSingleInstance();
|
|
276
308
|
process.exit(0);
|
|
277
309
|
});
|
|
310
|
+
process.on('exit', () => { releaseSingleInstance(); });
|
|
278
311
|
|
|
312
|
+
if (!acquireSingleInstance()) {
|
|
313
|
+
process.stderr.write('[plugkit-supervisor] another supervisor is alive; exiting\n');
|
|
314
|
+
process.exit(0);
|
|
315
|
+
}
|
|
279
316
|
writeSupervisorStatus('starting', {});
|
|
280
317
|
logEvent('supervisor.starting', { spool_dir: spoolDir });
|
|
281
318
|
try { fs.unlinkSync(path.join(spoolDir, '.pre-supervised-watcher.json')); } catch (_) {}
|
package/gm.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1517",
|
|
4
4
|
"description": "Canonical universal harness — AI-native software engineering via skill-driven orchestration; bootstraps plugkit for task execution and session isolation. Install in any AI coding agent host.",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|