gm-skill 2.0.1107 → 2.0.1109
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/README.md +1 -1
- package/bin/plugkit.version +1 -1
- package/bin/plugkit.wasm +0 -0
- package/bin/plugkit.wasm.sha256 +1 -1
- package/gm-plugkit/plugkit-wasm-wrapper.js +62 -15
- package/gm.json +2 -2
- package/lib/skill-bootstrap.js +46 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ npx gm-skill-bootstrap
|
|
|
28
28
|
|
|
29
29
|
## Version
|
|
30
30
|
|
|
31
|
-
`2.0.
|
|
31
|
+
`2.0.1109` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
|
|
32
32
|
|
|
33
33
|
## Source of truth
|
|
34
34
|
|
package/bin/plugkit.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.390
|
package/bin/plugkit.wasm
CHANGED
|
Binary file
|
package/bin/plugkit.wasm.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
228c370afbe435aca3a7aff8b9783000d05551efa3c254765d9ef2d05823fdac plugkit.wasm
|
|
@@ -12,12 +12,6 @@ const VEC_K_DEFAULT = 10;
|
|
|
12
12
|
const EMBED_MODEL_DEFAULT = process.env.EMBED_MODEL || 'mistral/mistral-embed';
|
|
13
13
|
const INFERENCE_MODEL_DEFAULT = process.env.INFERENCE_MODEL || 'groq/llama-3.3-70b-versatile';
|
|
14
14
|
|
|
15
|
-
function failLoud(verb, status, detail) {
|
|
16
|
-
const msg = `[plugkit-wasm] ${verb} FAILED: ${detail}`;
|
|
17
|
-
console.error(msg);
|
|
18
|
-
return { ok: false, verb, error: detail, status: status || 0 };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
function cosineSim(a, b) {
|
|
22
16
|
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return 0;
|
|
23
17
|
let dot = 0, na = 0, nb = 0;
|
|
@@ -383,14 +377,25 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
383
377
|
console.log(`[plugkit-wasm] plugkit v${resolveVersion(instance)} (wasm)`);
|
|
384
378
|
console.log(`[plugkit-wasm] watching ${inDir}`);
|
|
385
379
|
|
|
386
|
-
const
|
|
380
|
+
const PROCESSED_MAX = 10000;
|
|
381
|
+
const processed = new Map();
|
|
382
|
+
function markProcessed(key) {
|
|
383
|
+
processed.set(key, Date.now());
|
|
384
|
+
if (processed.size > PROCESSED_MAX) {
|
|
385
|
+
const oldest = processed.keys().next().value;
|
|
386
|
+
processed.delete(oldest);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function isProcessed(key) { return processed.has(key); }
|
|
390
|
+
function unmarkProcessed(key) { processed.delete(key); }
|
|
391
|
+
|
|
387
392
|
const dispatch = instance.exports.dispatch_verb;
|
|
388
393
|
if (!dispatch) throw new Error('dispatch_verb not exported');
|
|
389
394
|
|
|
390
395
|
const processFile = async (filePath) => {
|
|
391
396
|
const key = path.relative(inDir, filePath);
|
|
392
|
-
if (
|
|
393
|
-
|
|
397
|
+
if (isProcessed(key)) return;
|
|
398
|
+
markProcessed(key);
|
|
394
399
|
|
|
395
400
|
try {
|
|
396
401
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
@@ -423,7 +428,7 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
423
428
|
try { instance.exports.plugkit_free(ptr, len); } catch (_) {}
|
|
424
429
|
|
|
425
430
|
try { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); } catch (_) {}
|
|
426
|
-
|
|
431
|
+
unmarkProcessed(key);
|
|
427
432
|
} catch (e) {
|
|
428
433
|
console.error(`[plugkit-wasm] error processing ${key}: ${e.message}`);
|
|
429
434
|
const taskBase = path.basename(filePath, path.extname(filePath));
|
|
@@ -435,7 +440,7 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
435
440
|
fs.writeFileSync(path.join(outDir, outName), JSON.stringify({ ok: false, error: e.message }));
|
|
436
441
|
} catch (_) {}
|
|
437
442
|
try { fs.unlinkSync(filePath); } catch (_) {}
|
|
438
|
-
|
|
443
|
+
unmarkProcessed(key);
|
|
439
444
|
}
|
|
440
445
|
};
|
|
441
446
|
|
|
@@ -462,12 +467,51 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
462
467
|
try { fs.writeFileSync(heartbeatPath, String(Date.now())); } catch (_) {}
|
|
463
468
|
}, 5000);
|
|
464
469
|
|
|
465
|
-
const
|
|
470
|
+
const pollInterval = setInterval(async () => {
|
|
466
471
|
const existing = walkDir(inDir);
|
|
467
472
|
for (const fullPath of existing) {
|
|
468
473
|
await processFile(fullPath);
|
|
469
474
|
}
|
|
470
|
-
},
|
|
475
|
+
}, 5000);
|
|
476
|
+
|
|
477
|
+
setInterval(() => {
|
|
478
|
+
try {
|
|
479
|
+
const cutoff = Date.now() - 3600_000;
|
|
480
|
+
for (const entry of fs.readdirSync(outDir)) {
|
|
481
|
+
try {
|
|
482
|
+
const fp = path.join(outDir, entry);
|
|
483
|
+
const s = fs.statSync(fp);
|
|
484
|
+
if (s.mtimeMs < cutoff) fs.unlinkSync(fp);
|
|
485
|
+
} catch (_) {}
|
|
486
|
+
}
|
|
487
|
+
} catch (_) {}
|
|
488
|
+
}, 60_000);
|
|
489
|
+
|
|
490
|
+
setInterval(() => {
|
|
491
|
+
try {
|
|
492
|
+
const cutoff = Date.now() - 600_000;
|
|
493
|
+
const walk = (dir) => {
|
|
494
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
495
|
+
const fp = path.join(dir, entry.name);
|
|
496
|
+
if (entry.isDirectory()) walk(fp);
|
|
497
|
+
else if (entry.isFile()) {
|
|
498
|
+
const s = fs.statSync(fp);
|
|
499
|
+
if (s.mtimeMs < cutoff) {
|
|
500
|
+
const rel = path.relative(inDir, fp);
|
|
501
|
+
const verbDir = path.dirname(rel);
|
|
502
|
+
const base = path.basename(fp, path.extname(fp));
|
|
503
|
+
const outName = verbDir === '.' ? `${base}.json` : `${verbDir}-${base}.json`;
|
|
504
|
+
try {
|
|
505
|
+
fs.writeFileSync(path.join(outDir, outName), JSON.stringify({ ok: false, error: 'stale input — never dispatched or watcher crash mid-flight' }));
|
|
506
|
+
} catch (_) {}
|
|
507
|
+
try { fs.unlinkSync(fp); } catch (_) {}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
walk(inDir);
|
|
513
|
+
} catch (_) {}
|
|
514
|
+
}, 300_000);
|
|
471
515
|
|
|
472
516
|
const existing = walkDir(inDir);
|
|
473
517
|
for (const fullPath of existing) {
|
|
@@ -523,7 +567,7 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
523
567
|
await runSpoolWatcher(instance, spoolDir);
|
|
524
568
|
} else if (args[0] === 'dispatch') {
|
|
525
569
|
const verb = args[1] || '';
|
|
526
|
-
const body = args[2]
|
|
570
|
+
const body = args.length >= 3 ? args[2] : '';
|
|
527
571
|
const dispatch = instance.exports.dispatch_verb;
|
|
528
572
|
const verbBytes = new TextEncoder().encode(verb);
|
|
529
573
|
const bodyBytes = new TextEncoder().encode(body);
|
|
@@ -536,7 +580,10 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
536
580
|
const len = Number(result >> 32n);
|
|
537
581
|
const out = new TextDecoder().decode(new Uint8Array(instance.exports.memory.buffer, ptr, len));
|
|
538
582
|
process.stdout.write(out);
|
|
539
|
-
|
|
583
|
+
let parsed;
|
|
584
|
+
try { parsed = JSON.parse(out); } catch (_) { parsed = null; }
|
|
585
|
+
const failed = parsed && parsed.ok === false;
|
|
586
|
+
process.exit(failed ? 2 : 0);
|
|
540
587
|
} else {
|
|
541
588
|
console.log('[plugkit-wasm] args:', args.join(' '));
|
|
542
589
|
process.exit(0);
|
package/gm.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1109",
|
|
4
4
|
"description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,5 +23,5 @@
|
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
|
-
"plugkitVersion": "0.1.
|
|
26
|
+
"plugkitVersion": "0.1.390"
|
|
27
27
|
}
|
package/lib/skill-bootstrap.js
CHANGED
|
@@ -41,18 +41,38 @@ function emitBootstrapEvent(severity, message, details) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function resolveFromCandidates(candidates, requireResolveId) {
|
|
45
|
+
for (const c of candidates) {
|
|
46
|
+
if (c && fs.existsSync(c)) return c;
|
|
47
|
+
}
|
|
48
|
+
if (requireResolveId) {
|
|
49
|
+
try {
|
|
50
|
+
const resolved = require.resolve(requireResolveId);
|
|
51
|
+
if (fs.existsSync(resolved)) return resolved;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
44
58
|
function readManifest() {
|
|
45
59
|
try {
|
|
46
|
-
const gmJsonPath =
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
const gmJsonPath = resolveFromCandidates([
|
|
61
|
+
path.join(__dirname, '..', 'gm.json'),
|
|
62
|
+
path.join(__dirname, '..', '..', 'gm.json'),
|
|
63
|
+
], 'gm-skill/gm.json');
|
|
64
|
+
if (!gmJsonPath) {
|
|
65
|
+
throw new Error('gm.json not found relative to skill-bootstrap.js');
|
|
49
66
|
}
|
|
50
67
|
const gm = JSON.parse(fs.readFileSync(gmJsonPath, 'utf8'));
|
|
51
68
|
const version = gm.plugkitVersion;
|
|
52
69
|
|
|
53
|
-
const sha256Path =
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
const sha256Path = resolveFromCandidates([
|
|
71
|
+
path.join(__dirname, '..', 'bin', 'plugkit.wasm.sha256'),
|
|
72
|
+
path.join(__dirname, '..', '..', 'bin', 'plugkit.wasm.sha256'),
|
|
73
|
+
], 'gm-skill/bin/plugkit.wasm.sha256');
|
|
74
|
+
if (!sha256Path) {
|
|
75
|
+
throw new Error('bin/plugkit.wasm.sha256 not found relative to skill-bootstrap.js');
|
|
56
76
|
}
|
|
57
77
|
const sha256Content = fs.readFileSync(sha256Path, 'utf8').trim();
|
|
58
78
|
const expectedHash = sha256Content.split(/\s+/)[0];
|
|
@@ -366,12 +386,26 @@ async function bootstrapPlugkit(sessionId) {
|
|
|
366
386
|
}
|
|
367
387
|
|
|
368
388
|
async function checkPortReachable(host, port, timeoutMs = 500) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
389
|
+
const net = require('net');
|
|
390
|
+
return new Promise((resolve) => {
|
|
391
|
+
const socket = new net.Socket();
|
|
392
|
+
let done = false;
|
|
393
|
+
const finish = (ok) => {
|
|
394
|
+
if (done) return;
|
|
395
|
+
done = true;
|
|
396
|
+
try { socket.destroy(); } catch (e) {}
|
|
397
|
+
resolve(ok);
|
|
398
|
+
};
|
|
399
|
+
socket.setTimeout(timeoutMs);
|
|
400
|
+
socket.once('connect', () => finish(true));
|
|
401
|
+
socket.once('timeout', () => finish(false));
|
|
402
|
+
socket.once('error', () => finish(false));
|
|
403
|
+
try {
|
|
404
|
+
socket.connect(port, host);
|
|
405
|
+
} catch (e) {
|
|
406
|
+
finish(false);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
375
409
|
}
|
|
376
410
|
|
|
377
411
|
async function bootstrapAcptoapi() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1109",
|
|
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",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"gm.json"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"gm-plugkit": "^2.0.
|
|
42
|
+
"gm-plugkit": "^2.0.1109"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=16.0.0"
|