gm-skill 2.0.1513 → 2.0.1515
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.
|
@@ -5,6 +5,13 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const os = require('os');
|
|
7
7
|
const { spawn, spawnSync } = require('child_process');
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
|
|
10
|
+
function wrapperSha12OnDisk() {
|
|
11
|
+
try {
|
|
12
|
+
return crypto.createHash('sha256').update(fs.readFileSync(resolveWrapper())).digest('hex').slice(0, 12);
|
|
13
|
+
} catch (_) { return null; }
|
|
14
|
+
}
|
|
8
15
|
|
|
9
16
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
10
17
|
const spoolDir = path.join(projectDir, '.gm', 'exec-spool');
|
|
@@ -248,6 +255,25 @@ function checkWatcherHealth() {
|
|
|
248
255
|
severity: 'critical',
|
|
249
256
|
});
|
|
250
257
|
killChild('supervisor-killed-stale-heartbeat');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
// A published wrapper-only fix (no wasm version bump) is copied to ~/.gm-tools by the next
|
|
261
|
+
// bootstrap's ensureWrapperFresh, but a healthy running watcher keeps the old wrapper until it
|
|
262
|
+
// restarts. Compare the watcher's reported wrapper_sha against the on-disk wrapper; on drift,
|
|
263
|
+
// recycle so the fix goes live without a manual kill. Skip while busy (a long verb is running).
|
|
264
|
+
const status = readStatus();
|
|
265
|
+
if (status && !(status.busy_until && status.busy_until > Date.now())) {
|
|
266
|
+
const reported = status.wrapper_sha || null;
|
|
267
|
+
const onDisk = wrapperSha12OnDisk();
|
|
268
|
+
if (reported && onDisk && reported !== onDisk) {
|
|
269
|
+
logEvent('supervisor.wrapper-sha-drift', {
|
|
270
|
+
watcher_pid: currentChildPid,
|
|
271
|
+
reported_sha: reported,
|
|
272
|
+
on_disk_sha: onDisk,
|
|
273
|
+
severity: 'info',
|
|
274
|
+
});
|
|
275
|
+
killChild('supervisor-killed-wrapper-sha-drift');
|
|
276
|
+
}
|
|
251
277
|
}
|
|
252
278
|
}
|
|
253
279
|
|
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.1515",
|
|
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": {
|
|
@@ -15,6 +15,10 @@ let _writeStatusBusy = () => {};
|
|
|
15
15
|
// Latest busy_until epoch ms stamped by a long synchronous verb (codesearch rebuild, chromium
|
|
16
16
|
// spawn). scanStalledTurns reads it so a busy watcher is not mis-flagged as an idle stall.
|
|
17
17
|
let _lastBusyUntil = 0;
|
|
18
|
+
// First 12 hex of sha256 of this watcher's own gmTools wrapper. Module-scoped so writeStatus
|
|
19
|
+
// (a different function scope) can stamp status.wrapper_sha, which the supervisor compares
|
|
20
|
+
// against the on-disk wrapper to recycle a watcher running a stale wrapper-only fix.
|
|
21
|
+
let _ownWrapperSha12 = '';
|
|
18
22
|
|
|
19
23
|
function spawnSync(cmd, args, opts) {
|
|
20
24
|
return _rawSpawnSync(cmd, args, { windowsHide: true, ...(opts || {}) });
|
|
@@ -2078,12 +2082,14 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2078
2082
|
|
|
2079
2083
|
|
|
2080
2084
|
const LOCK_PATH = path.join(spoolDir, '.watcher.lock');
|
|
2081
|
-
let _ownWrapperSha12 = '';
|
|
2082
2085
|
try {
|
|
2083
2086
|
const _crypto = require('crypto');
|
|
2084
2087
|
const _wp = path.join(GM_TOOLS_ROOT, 'plugkit-wasm-wrapper.js');
|
|
2085
2088
|
_ownWrapperSha12 = _crypto.createHash('sha256').update(fs.readFileSync(_wp)).digest('hex').slice(0, 12);
|
|
2086
|
-
|
|
2089
|
+
try { logEvent('plugkit', 'watcher.own-wrapper-sha', { sha: _ownWrapperSha12, wrapper_path: _wp }); } catch (_) {}
|
|
2090
|
+
} catch (e) {
|
|
2091
|
+
try { logEvent('plugkit', 'watcher.own-wrapper-sha-failed', { error: String(e && e.message || e), gm_tools_root: GM_TOOLS_ROOT }); } catch (_) {}
|
|
2092
|
+
}
|
|
2087
2093
|
function lockBody() { return `${process.pid}|${Date.now()}|${_ownWrapperSha12}`; }
|
|
2088
2094
|
function acquireLock() {
|
|
2089
2095
|
try {
|
package/gm-plugkit/supervisor.js
CHANGED
|
@@ -4,8 +4,18 @@
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const os = require('os');
|
|
7
|
+
const crypto = require('crypto');
|
|
7
8
|
const { spawn, spawnSync } = require('child_process');
|
|
8
9
|
|
|
10
|
+
function wrapperSha12OnDisk() {
|
|
11
|
+
try {
|
|
12
|
+
const primary = path.join(os.homedir(), '.gm-tools', 'plugkit-wasm-wrapper.js');
|
|
13
|
+
const fallback = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
|
|
14
|
+
const wp = fs.existsSync(primary) ? primary : fallback;
|
|
15
|
+
return crypto.createHash('sha256').update(fs.readFileSync(wp)).digest('hex').slice(0, 12);
|
|
16
|
+
} catch (_) { return null; }
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
10
20
|
const spoolDir = path.join(projectDir, '.gm', 'exec-spool');
|
|
11
21
|
fs.mkdirSync(spoolDir, { recursive: true });
|
|
@@ -227,6 +237,25 @@ function checkWatcherHealth() {
|
|
|
227
237
|
if (process.platform === 'win32') {
|
|
228
238
|
try { spawnSync('taskkill', ['/F', '/T', '/PID', String(currentChildPid)], { stdio: 'ignore', windowsHide: true, timeout: 3000 }); } catch (_) {}
|
|
229
239
|
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// A published wrapper-only fix (no wasm version bump) lands in ~/.gm-tools via the next
|
|
243
|
+
// bootstrap's ensureWrapperFresh, but a healthy running watcher keeps the old wrapper until it
|
|
244
|
+
// restarts. On wrapper_sha drift (watcher's reported sha != on-disk), recycle so the fix goes
|
|
245
|
+
// live without a manual kill. busy_until already returned above, so the watcher is not mid-verb.
|
|
246
|
+
const reported = status.wrapper_sha || null;
|
|
247
|
+
const onDisk = wrapperSha12OnDisk();
|
|
248
|
+
if (reported && onDisk && reported !== onDisk) {
|
|
249
|
+
logEvent('supervisor.wrapper-sha-drift', {
|
|
250
|
+
watcher_pid: currentChildPid,
|
|
251
|
+
reported_sha: reported,
|
|
252
|
+
on_disk_sha: onDisk,
|
|
253
|
+
severity: 'info',
|
|
254
|
+
});
|
|
255
|
+
try { process.kill(currentChildPid, 'SIGTERM'); } catch (_) {}
|
|
256
|
+
if (process.platform === 'win32') {
|
|
257
|
+
try { spawnSync('taskkill', ['/F', '/T', '/PID', String(currentChildPid)], { stdio: 'ignore', windowsHide: true, timeout: 3000 }); } catch (_) {}
|
|
258
|
+
}
|
|
230
259
|
}
|
|
231
260
|
}
|
|
232
261
|
|
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.1515",
|
|
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",
|