gm-skill 2.0.1373 → 2.0.1375
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 +36 -0
- package/gm.json +1 -1
- package/lib/spool-dispatch.js +1 -3
- 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.1375",
|
|
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": {
|
|
@@ -359,6 +359,38 @@ function readCurrentSess() {
|
|
|
359
359
|
|
|
360
360
|
const __lockRejectedEmitAt = new Map();
|
|
361
361
|
|
|
362
|
+
function autoRecordBrowserEditsFromBody(body, cwd, taskBase, verb) {
|
|
363
|
+
if (!body || typeof body !== 'string') return;
|
|
364
|
+
const BROWSER_EXT_RE = /[\w.\-/\\]+\.(?:html?|tsx?|jsx?|mjs|cjs|vue|svelte|css|scss|sass)\b/gi;
|
|
365
|
+
const matches = body.match(BROWSER_EXT_RE);
|
|
366
|
+
if (!matches || matches.length === 0) return;
|
|
367
|
+
const seen = new Set();
|
|
368
|
+
const editsFile = path.join(cwd, '.gm', 'exec-spool', '.turn-browser-edits.json');
|
|
369
|
+
let list = [];
|
|
370
|
+
try { list = JSON.parse(fs.readFileSync(editsFile, 'utf8')); if (!Array.isArray(list)) list = []; } catch (_) {}
|
|
371
|
+
let added = 0;
|
|
372
|
+
for (const raw of matches) {
|
|
373
|
+
let rel = String(raw).replace(/^["'`(]+|["'`)]+$/g, '').replace(/\\/g, '/');
|
|
374
|
+
if (rel.startsWith('http://') || rel.startsWith('https://') || rel.startsWith('//')) continue;
|
|
375
|
+
if (rel.includes('node_modules/') || rel.startsWith('.gm/') || rel.includes('/.gm/')) continue;
|
|
376
|
+
if (seen.has(rel)) continue;
|
|
377
|
+
seen.add(rel);
|
|
378
|
+
const abs = path.isAbsolute(rel) ? rel : path.join(cwd, rel);
|
|
379
|
+
let st;
|
|
380
|
+
try { st = fs.statSync(abs); } catch (_) { continue; }
|
|
381
|
+
if (!st.isFile()) continue;
|
|
382
|
+
let hash = '';
|
|
383
|
+
try { hash = require('crypto').createHash('sha256').update(fs.readFileSync(abs)).digest('hex').slice(0, 12); } catch (_) {}
|
|
384
|
+
const idx = list.findIndex(e => e && e.file === rel);
|
|
385
|
+
const entry = { file: rel, ts: Date.now(), hash, source_verb: verb, source_task: taskBase };
|
|
386
|
+
if (idx === -1) { list.push(entry); added++; } else { list[idx] = entry; }
|
|
387
|
+
}
|
|
388
|
+
if (added > 0) {
|
|
389
|
+
try { fs.mkdirSync(path.dirname(editsFile), { recursive: true }); fs.writeFileSync(editsFile, JSON.stringify(list)); } catch (_) {}
|
|
390
|
+
logEvent('plugkit', 'browser.edits-autorecorded', { verb, task: taskBase, files: list.slice(-added).map(e => e.file), added });
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
362
394
|
function logEvent(sub, event, fields) {
|
|
363
395
|
if (process.env.GM_LOG_DISABLE) return;
|
|
364
396
|
try {
|
|
@@ -2535,6 +2567,10 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
2535
2567
|
console.log(`[dispatch] → verb=${verb} task=${taskBase} body=${bodyBytes.length}b`);
|
|
2536
2568
|
logEvent('plugkit', 'dispatch.start', { verb, task: taskBase, body_bytes: bodyBytes.length, cwd: process.cwd() });
|
|
2537
2569
|
|
|
2570
|
+
if (verb === 'memorize-fire' || verb === 'transition' || verb === 'prd-resolve' || verb === 'mutable-resolve') {
|
|
2571
|
+
try { autoRecordBrowserEditsFromBody(body, process.cwd(), taskBase, verb); } catch (_) {}
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2538
2574
|
let autoRecallPayload = null;
|
|
2539
2575
|
if (verb === 'instruction') {
|
|
2540
2576
|
const sessForRecall = readCurrentSess();
|
package/gm.json
CHANGED
package/lib/spool-dispatch.js
CHANGED
|
@@ -203,15 +203,13 @@ const SPOOL_POLL_PATTERNS = [
|
|
|
203
203
|
/\bwhile\b[^;]*?(?:!|-not)\s*(?:-(?:f|e)\s+|Test-Path\s+)[^;]*?\.gm[\\/](?:exec-spool|spool)/i,
|
|
204
204
|
/\buntil\b[^;]*?(?:-f|-e|Test-Path)\s+[^;]*?\.gm[\\/](?:exec-spool|spool)/i,
|
|
205
205
|
/\bfor\s+i\s+in\b[^;]*?;\s*do\b[^;]*?(?:sleep|Start-Sleep)[^;]*?\.gm[\\/](?:exec-spool|spool)/i,
|
|
206
|
-
/\b(?:cat|head|tail|less|more|type|Get-Content|gc)\s+(?:-[A-Za-z]+\s+)*['"]?[^'"|;&]*\.gm[\\/](?:exec-spool|spool)[\\/]\.status\.json\b/i,
|
|
207
|
-
/\b(?:cat|head|tail|less|more|type|Get-Content|gc)\s+(?:-[A-Za-z]+\s+)*['"]?[^'"|;&]*\.gm[\\/](?:exec-spool|spool)[\\/]\.watcher\.log\b/i,
|
|
208
206
|
/\b(?:ls|dir|Get-ChildItem|gci)\s+(?:-[A-Za-z]+\s+)*['"]?[^'"|;&]*\.gm[\\/](?:exec-spool|spool)(?:[\\/](?:in|out)?)?[\\/]?['"]?\s*(?:$|[|;&])/i,
|
|
209
207
|
/\b(?:test|Test-Path|tp)\s+(?:-[A-Za-z]+\s+)?['"]?[^'"|;&]*\.gm[\\/](?:exec-spool|spool)[\\/](?:out|in)[\\/]/i,
|
|
210
208
|
/\bfind\b[^|]*['"]?[^'"|;&]*\.gm[\\/](?:exec-spool|spool)\b/i,
|
|
211
209
|
/\b(?:xargs|parallel|fzf)\b[^|]*\.gm[\\/](?:exec-spool|spool)/i,
|
|
212
210
|
];
|
|
213
211
|
|
|
214
|
-
const SPOOL_POLL_REASON = 'spool
|
|
212
|
+
const SPOOL_POLL_REASON = 'spool POLLING (sleep+cat, while !test, ls/find on the spool dirs) is forbidden — plugkit is synchronous from your view, so the response file is there the moment the watcher finishes the verb. Specific replacements:\n\n- Instead of `ls .gm/exec-spool/out/` → check the specific response file you wrote, e.g. `Read .gm/exec-spool/out/<verb>-<N>.json`\n- Instead of `sleep N; cat .gm/exec-spool/<...>` → just Read the response file directly; if it doesn\'t exist yet, the watcher is dead (the SKILL.md boot probe `cat .gm/exec-spool/.status.json; date +%s%3N` is the way to check liveness) or the verb is slow (Read .gm/exec-spool/.watcher.log for the dispatch trace)\n- Instead of `while [ ! -f ... ]; do sleep ...; done` → write the request, Read the response in the same message, accept the file-not-found and re-Read in the next message\n\nThe SKILL.md-prescribed boot probe (`cat .gm/exec-spool/.status.json; date +%s%3N`) is NOT a violation — it is the canonical liveness check because it pipes with `date` for ts comparison. The Read tool can\'t do that in one call. What this gate denies is the *polling* pattern around the spool dirs, not the boot-probe cat. You are the state machine. Plugkit serves the response the moment you write the request file.';
|
|
215
213
|
|
|
216
214
|
function stripHeredocsAndStringLiterals(command) {
|
|
217
215
|
let s = String(command);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1375",
|
|
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",
|