gm-skill 2.0.1332 → 2.0.1334
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 +47 -3
- 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.1334",
|
|
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": {
|
|
@@ -2344,7 +2344,29 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2344
2344
|
}
|
|
2345
2345
|
|
|
2346
2346
|
try {
|
|
2347
|
-
const
|
|
2347
|
+
const rawBuf = fs.readFileSync(filePath);
|
|
2348
|
+
let content;
|
|
2349
|
+
let _detectedEncoding = 'utf-8';
|
|
2350
|
+
if (rawBuf.length >= 2 && rawBuf[0] === 0xFF && rawBuf[1] === 0xFE) {
|
|
2351
|
+
content = rawBuf.slice(2).toString('utf16le');
|
|
2352
|
+
_detectedEncoding = 'utf-16le-bom';
|
|
2353
|
+
} else if (rawBuf.length >= 2 && rawBuf[0] === 0xFE && rawBuf[1] === 0xFF) {
|
|
2354
|
+
const swapped = Buffer.alloc(rawBuf.length - 2);
|
|
2355
|
+
for (let i = 2; i + 1 < rawBuf.length; i += 2) {
|
|
2356
|
+
swapped[i - 2] = rawBuf[i + 1];
|
|
2357
|
+
swapped[i - 1] = rawBuf[i];
|
|
2358
|
+
}
|
|
2359
|
+
content = swapped.toString('utf16le');
|
|
2360
|
+
_detectedEncoding = 'utf-16be-bom';
|
|
2361
|
+
} else if (rawBuf.length >= 3 && rawBuf[0] === 0xEF && rawBuf[1] === 0xBB && rawBuf[2] === 0xBF) {
|
|
2362
|
+
content = rawBuf.slice(3).toString('utf8');
|
|
2363
|
+
_detectedEncoding = 'utf-8-bom';
|
|
2364
|
+
} else {
|
|
2365
|
+
content = rawBuf.toString('utf8');
|
|
2366
|
+
}
|
|
2367
|
+
if (_detectedEncoding !== 'utf-8') {
|
|
2368
|
+
try { logEvent('plugkit', 'spool.body-encoding-recoded', { task: path.basename(filePath, path.extname(filePath)), encoding: _detectedEncoding, bytes: rawBuf.length }); } catch (_) {}
|
|
2369
|
+
}
|
|
2348
2370
|
const relPath = path.relative(inDir, filePath);
|
|
2349
2371
|
const dir = path.dirname(relPath);
|
|
2350
2372
|
const verb = dir === '.' ? path.basename(filePath, path.extname(filePath)) : dir;
|
|
@@ -2555,8 +2577,26 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2555
2577
|
}
|
|
2556
2578
|
}, 5000);
|
|
2557
2579
|
|
|
2580
|
+
let _sweepErrLogged = false;
|
|
2558
2581
|
setInterval(() => {
|
|
2559
2582
|
try {
|
|
2583
|
+
if (!fs.existsSync(outDir)) {
|
|
2584
|
+
try {
|
|
2585
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
2586
|
+
fs.mkdirSync(inDir, { recursive: true });
|
|
2587
|
+
console.log(`[retention] recreated missing spool dirs: ${outDir}, ${inDir}`);
|
|
2588
|
+
logEvent('plugkit', 'spool.dirs-recreated', { outDir, inDir, reason: 'sweep-found-missing' });
|
|
2589
|
+
_sweepErrLogged = false;
|
|
2590
|
+
return;
|
|
2591
|
+
} catch (mke) {
|
|
2592
|
+
if (!_sweepErrLogged) {
|
|
2593
|
+
console.error(`[retention] cannot recreate ${outDir}: ${mke.message}`);
|
|
2594
|
+
logEvent('plugkit', 'spool.dirs-recreate-failed', { outDir, error: mke.message });
|
|
2595
|
+
_sweepErrLogged = true;
|
|
2596
|
+
}
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2560
2600
|
const cutoff = Date.now() - 3600_000;
|
|
2561
2601
|
let swept = 0;
|
|
2562
2602
|
for (const entry of fs.readdirSync(outDir)) {
|
|
@@ -2570,9 +2610,13 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2570
2610
|
console.log(`[retention] swept ${swept} out/ files older than 1h`);
|
|
2571
2611
|
logEvent('plugkit', 'sweep.retention', { swept });
|
|
2572
2612
|
}
|
|
2613
|
+
_sweepErrLogged = false;
|
|
2573
2614
|
} catch (e) {
|
|
2574
|
-
|
|
2575
|
-
|
|
2615
|
+
if (!_sweepErrLogged) {
|
|
2616
|
+
console.error(`[retention] sweep error: ${e.message}`);
|
|
2617
|
+
logEvent('plugkit', 'sweep.retention.error', { error: String(e.message || e) });
|
|
2618
|
+
_sweepErrLogged = true;
|
|
2619
|
+
}
|
|
2576
2620
|
}
|
|
2577
2621
|
}, 60_000);
|
|
2578
2622
|
|
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.1334",
|
|
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.
|