gm-skill 2.0.1333 → 2.0.1335
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 +42 -17
- package/gm.json +1 -1
- package/package.json +1 -1
- package/skills/gm-skill/SKILL.md +2 -0
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.1335",
|
|
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": {
|
|
@@ -1752,17 +1752,8 @@ function resolveVersion(instance) {
|
|
|
1752
1752
|
try {
|
|
1753
1753
|
return fs.readFileSync(path.join(GM_TOOLS_ROOT, 'plugkit.version'), 'utf8').trim();
|
|
1754
1754
|
} catch (_) {}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
if (typeof fn === 'function') {
|
|
1758
|
-
const result = fn();
|
|
1759
|
-
const ptr = Number(result & 0xffffffffn);
|
|
1760
|
-
const len = Number(result >> 32n);
|
|
1761
|
-
const bytes = new Uint8Array(instance.exports.memory.buffer, ptr, len);
|
|
1762
|
-
return new TextDecoder().decode(bytes).trim();
|
|
1763
|
-
}
|
|
1764
|
-
} catch (_) {}
|
|
1765
|
-
return 'unknown';
|
|
1755
|
+
const fromInstance = readInstanceVersion(instance);
|
|
1756
|
+
return fromInstance || 'unknown';
|
|
1766
1757
|
}
|
|
1767
1758
|
|
|
1768
1759
|
function readFileVersionOnly() {
|
|
@@ -1774,10 +1765,22 @@ function readInstanceVersion(instance) {
|
|
|
1774
1765
|
const fn = instance && instance.exports && instance.exports.plugkit_version;
|
|
1775
1766
|
if (typeof fn !== 'function') return null;
|
|
1776
1767
|
const result = fn();
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1768
|
+
let ptr, len;
|
|
1769
|
+
if (typeof result === 'bigint') {
|
|
1770
|
+
ptr = Number(result & 0xffffffffn);
|
|
1771
|
+
len = Number(result >> 32n);
|
|
1772
|
+
} else {
|
|
1773
|
+
ptr = Number(result) & 0xffffffff;
|
|
1774
|
+
len = 0;
|
|
1775
|
+
}
|
|
1776
|
+
const buf = new Uint8Array(instance.exports.memory.buffer, ptr, 64);
|
|
1777
|
+
if (len === 0) {
|
|
1778
|
+
let end = 0;
|
|
1779
|
+
while (end < buf.length && buf[end] !== 0) end++;
|
|
1780
|
+
len = end;
|
|
1781
|
+
}
|
|
1782
|
+
if (len === 0) return null;
|
|
1783
|
+
return new TextDecoder().decode(buf.subarray(0, len)).trim() || null;
|
|
1781
1784
|
} catch (_) { return null; }
|
|
1782
1785
|
}
|
|
1783
1786
|
|
|
@@ -2577,8 +2580,26 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2577
2580
|
}
|
|
2578
2581
|
}, 5000);
|
|
2579
2582
|
|
|
2583
|
+
let _sweepErrLogged = false;
|
|
2580
2584
|
setInterval(() => {
|
|
2581
2585
|
try {
|
|
2586
|
+
if (!fs.existsSync(outDir)) {
|
|
2587
|
+
try {
|
|
2588
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
2589
|
+
fs.mkdirSync(inDir, { recursive: true });
|
|
2590
|
+
console.log(`[retention] recreated missing spool dirs: ${outDir}, ${inDir}`);
|
|
2591
|
+
logEvent('plugkit', 'spool.dirs-recreated', { outDir, inDir, reason: 'sweep-found-missing' });
|
|
2592
|
+
_sweepErrLogged = false;
|
|
2593
|
+
return;
|
|
2594
|
+
} catch (mke) {
|
|
2595
|
+
if (!_sweepErrLogged) {
|
|
2596
|
+
console.error(`[retention] cannot recreate ${outDir}: ${mke.message}`);
|
|
2597
|
+
logEvent('plugkit', 'spool.dirs-recreate-failed', { outDir, error: mke.message });
|
|
2598
|
+
_sweepErrLogged = true;
|
|
2599
|
+
}
|
|
2600
|
+
return;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2582
2603
|
const cutoff = Date.now() - 3600_000;
|
|
2583
2604
|
let swept = 0;
|
|
2584
2605
|
for (const entry of fs.readdirSync(outDir)) {
|
|
@@ -2592,9 +2613,13 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2592
2613
|
console.log(`[retention] swept ${swept} out/ files older than 1h`);
|
|
2593
2614
|
logEvent('plugkit', 'sweep.retention', { swept });
|
|
2594
2615
|
}
|
|
2616
|
+
_sweepErrLogged = false;
|
|
2595
2617
|
} catch (e) {
|
|
2596
|
-
|
|
2597
|
-
|
|
2618
|
+
if (!_sweepErrLogged) {
|
|
2619
|
+
console.error(`[retention] sweep error: ${e.message}`);
|
|
2620
|
+
logEvent('plugkit', 'sweep.retention.error', { error: String(e.message || e) });
|
|
2621
|
+
_sweepErrLogged = true;
|
|
2622
|
+
}
|
|
2598
2623
|
}
|
|
2599
2624
|
}, 60_000);
|
|
2600
2625
|
|
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.1335",
|
|
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
|
@@ -38,6 +38,8 @@ bun x gm-plugkit@latest spool > /dev/null 2>&1 &
|
|
|
38
38
|
|
|
39
39
|
Never poll the spool dir with `sleep && ls` or `Start-Sleep && Test-Path` — plugkit is synchronous from your view; if the response is not there, the watcher is dead (re-check `.status.json` mtime) or the verb is slow (check `.gm/exec-spool/.watcher.log`), not "still processing."
|
|
40
40
|
|
|
41
|
+
When writing the spool input from PowerShell, pass `-Encoding utf8` (or use `[System.IO.File]::WriteAllText($path, $body)` which defaults to UTF-8 no-BOM). PowerShell 5.1's default `Out-File` / `Set-Content` write UTF-16 LE with BOM, which the watcher detects and re-decodes (`spool.body-encoding-recoded` event in gmsniff), but the deviation is a fingerprint of an instruction you missed. Use `bash -c "echo -n '...' > ..."` or `Write` tool instead when the body is structured JSON.
|
|
42
|
+
|
|
41
43
|
First turn body must be `{"prompt":"<user request>"}` so orient_nouns and recall_hits derive from the request; subsequent turns in the same conversation may use empty body `{}`.
|
|
42
44
|
|
|
43
45
|
**Batch writes, waits, and reads together.** Each agent turn costs cycles; the dispatch shape `Write request → wait → Read response` is one logical step, not three. Issue all three in a single message — the Write tool call and the Read tool call go in the same `<function_calls>` block. The Read may return "file does not exist" if plugkit is mid-verb; that's fine, retry with one more Read in the next message rather than spreading the cycle across three turns. Fan-out is the same shape — dispatching three independent verbs (`prd-add g1`, `prd-add g2`, `prd-add g3`) means three Write tool calls in one block, then three Read tool calls in one block. Serial dispatch when you could be parallel is wasted cycles. The only sequencing constraint is real data dependency: if verb B needs the response of verb A, those go in separate turns; otherwise batch.
|