gm-skill 2.0.1392 → 2.0.1394
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/plugkit-wasm-wrapper.js +14 -1
- package/gm.json +1 -1
- package/package.json +1 -1
- package/skills/gm-skill/SKILL.md +5 -3
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.1394",
|
|
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": {
|
|
@@ -1868,7 +1868,9 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
1868
1868
|
const holderSha = parts[2] || '';
|
|
1869
1869
|
const lockTs = parseInt(tsStr, 10);
|
|
1870
1870
|
const age = Date.now() - lockTs;
|
|
1871
|
-
|
|
1871
|
+
const holderPidNum = parseInt(pidStr, 10);
|
|
1872
|
+
const holderAlive = Number.isFinite(holderPidNum) && isProcessAliveSync(holderPidNum);
|
|
1873
|
+
if (age < 15000 && holderAlive) {
|
|
1872
1874
|
if (_ownWrapperSha12 && holderSha && holderSha !== _ownWrapperSha12) {
|
|
1873
1875
|
try { logEvent('plugkit', 'peer.stale-wrapper-takeover', { holder_pid: pidStr, holder_sha: holderSha, own_sha: _ownWrapperSha12, lock_age_ms: age }); } catch (_) {}
|
|
1874
1876
|
console.error(`[plugkit-wasm] peer wrapper-sha mismatch (holder=${holderSha} own=${_ownWrapperSha12}); killing pid=${pidStr} and taking over`);
|
|
@@ -1896,6 +1898,9 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
1896
1898
|
} catch (_) {}
|
|
1897
1899
|
process.exit(75);
|
|
1898
1900
|
}
|
|
1901
|
+
} else if (!holderAlive) {
|
|
1902
|
+
console.error(`[plugkit-wasm] stale lock (holder pid=${pidStr} dead, age=${age}ms); taking over`);
|
|
1903
|
+
try { logEvent('plugkit', 'watcher.lock-pid-dead-takeover', { stale_pid: pidStr, lock_age_ms: age }); } catch (_) {}
|
|
1899
1904
|
} else {
|
|
1900
1905
|
console.error(`[plugkit-wasm] stale lock (age=${age}ms); taking over`);
|
|
1901
1906
|
}
|
|
@@ -2776,6 +2781,13 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2776
2781
|
} catch (_) {}
|
|
2777
2782
|
const fileV = readFileVersionOnly() || null;
|
|
2778
2783
|
const instV = _instanceVersionAtBoot || null;
|
|
2784
|
+
let updateAvailable = null;
|
|
2785
|
+
try {
|
|
2786
|
+
const upd = JSON.parse(fs.readFileSync(path.join(spoolDir, '.update-available.json'), 'utf-8'));
|
|
2787
|
+
if (upd && upd.installed && upd.latest && upd.installed !== upd.latest) {
|
|
2788
|
+
updateAvailable = { installed: upd.installed, latest: upd.latest };
|
|
2789
|
+
}
|
|
2790
|
+
} catch (_) {}
|
|
2779
2791
|
fs.writeFileSync(TURN_SUMMARY_PATH, JSON.stringify({
|
|
2780
2792
|
ts: Date.now(),
|
|
2781
2793
|
watcher_pid: process.pid,
|
|
@@ -2787,6 +2799,7 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2787
2799
|
last_instruction_age_ms: lastInstructionAgeMs,
|
|
2788
2800
|
long_gap_threshold_ms: 300000,
|
|
2789
2801
|
browser_sessions_alive: browserSessions,
|
|
2802
|
+
update_available: updateAvailable,
|
|
2790
2803
|
}));
|
|
2791
2804
|
} catch (_) {}
|
|
2792
2805
|
}
|
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.1394",
|
|
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",
|
package/skills/gm-skill/SKILL.md
CHANGED
|
@@ -22,13 +22,15 @@ Every turn: dispatch `instruction` (you are the one dispatching it), read the re
|
|
|
22
22
|
|
|
23
23
|
**Boot before dispatching. Always check first.** Writing to `.gm/exec-spool/in/instruction/N.txt` while the watcher is dead is the canonical cold-start failure — the request sits forever, you read no response, you fabricate the chain from memory of the prose. The spool directory's existence does NOT mean the watcher is alive; `.status.json` mtime within the last 15s does. The leftover `.status.json` from yesterday's dead watcher is the most common trap.
|
|
24
24
|
|
|
25
|
-
Your first tool call of every session is the boot probe, in one Bash invocation:
|
|
25
|
+
Your first tool call of every session is the boot probe, in one Bash invocation. Read `.status.json` (liveness) and `.turn-summary.json` (orientation) together — the watcher precomputes both every 5s, so the two files give you everything you'd otherwise extract via gmsniff queries, git, yaml-parse, and ports-file scans:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
cat .gm/exec-spool/.status.json 2>/dev/null; date +%s%3N
|
|
28
|
+
cat .gm/exec-spool/.status.json 2>/dev/null; echo ---; cat .gm/exec-spool/.turn-summary.json 2>/dev/null; echo ---; date +%s%3N
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
`.turn-summary.json` carries `phase`, `last_skill`, `prd_pending`, `last_instruction_ts`, `last_instruction_age_ms`, `long_gap_threshold_ms`, `browser_sessions_alive`, `update_available`. When age exceeds the threshold, your next non-orienting verb will be gated — dispatch `instruction` first. When `update_available` is non-null, the watcher has detected drift: kill the watcher and re-bootstrap before continuing so the next instruction lands on the fresh wasm.
|
|
32
|
+
|
|
33
|
+
Compare `.status.json` `ts` field to the printed epoch ms. If the gap is >15000, the watcher is dead — boot it:
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
36
|
bun x gm-plugkit@latest spool > /dev/null 2>&1 &
|