gm-skill 2.0.1987 → 2.0.1989
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/bin/plugkit-slim.wasm.sha256 +1 -0
- package/bin/plugkit.version +1 -1
- package/bin/plugkit.wasm.sha256 +1 -1
- package/gm-plugkit/bootstrap.js +119 -17
- package/gm-plugkit/package.json +1 -1
- package/gm-plugkit/plugkit-slim.wasm.sha256 +1 -0
- package/gm-plugkit/plugkit-wasm-wrapper.js +40 -5
- package/gm-plugkit/plugkit.version +1 -1
- package/gm.json +2 -2
- package/package.json +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
44fe1ce8f27bc716b366b881d2ece7529487cec1ac1398bd4f8f097c3c291020 plugkit-slim.wasm
|
package/bin/plugkit.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.914
|
package/bin/plugkit.wasm.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
b805b74d1ef2e73fc4b246987ab01a879d7de20063504083a38163163b5ed879 plugkit.wasm
|
package/gm-plugkit/bootstrap.js
CHANGED
|
@@ -223,6 +223,26 @@ function gmToolsDir() {
|
|
|
223
223
|
return primary;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
// Slim-artifact eligibility: plugkit-core's embed.rs probes host_vec_embed
|
|
227
|
+
// before ever loading its wasm-embedded safetensors fallback (see
|
|
228
|
+
// rs-plugkit/crates/plugkit-core/src/embed.rs::init_ctx) -- a slim build
|
|
229
|
+
// (feature=slim, no embedded weights at all) is only safe to fetch on a host
|
|
230
|
+
// that actually answers host_vec_embed for real. plugkit-wasm-wrapper.js
|
|
231
|
+
// wires that answer through gm-runner's native candle path
|
|
232
|
+
// (hostEmbedViaGmRunner) or agentplug-runner's shared daemon, both gated on
|
|
233
|
+
// one of these two binaries existing under ~/.gm-tools -- mirrors that same
|
|
234
|
+
// on-disk presence check here so bootstrap-time artifact selection and
|
|
235
|
+
// runtime embed-delegation eligibility never disagree. Absence of both means
|
|
236
|
+
// no host_vec_embed answer will ever come, so fetching fat (which carries its
|
|
237
|
+
// own wasm-side embedding fallback) is the only safe choice.
|
|
238
|
+
function hasNativeEmbedRunner() {
|
|
239
|
+
const dir = gmToolsDir();
|
|
240
|
+
const names = process.platform === 'win32'
|
|
241
|
+
? ['gm-runner.exe', 'agentplug-runner.exe']
|
|
242
|
+
: ['gm-runner', 'agentplug-runner'];
|
|
243
|
+
return names.some(n => { try { return fs.existsSync(path.join(dir, n)); } catch (_) { return false; } });
|
|
244
|
+
}
|
|
245
|
+
|
|
226
246
|
// Root a project-dir resolution at the git COMMON dir, not the raw cwd/
|
|
227
247
|
// CLAUDE_PROJECT_DIR -- a worktree (e.g. Workflow's isolation:'worktree'
|
|
228
248
|
// agents, each `git worktree add`-ing a fresh physical directory) shares the
|
|
@@ -265,8 +285,26 @@ function readVersionFile() {
|
|
|
265
285
|
function readShaManifest() {
|
|
266
286
|
const p = path.join(wrapperDir, 'plugkit.sha256');
|
|
267
287
|
if (!fs.existsSync(p)) return null;
|
|
288
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
289
|
+
// Two real formats seen in the wild for this file: the checked-in local
|
|
290
|
+
// gm-plugkit/plugkit.sha256 is a JSON manifest ({"plugkit.wasm":"<sha>"}),
|
|
291
|
+
// written by the version-bump automation; a GitHub-release .sha256 sidecar
|
|
292
|
+
// (fetched directly from plugkit-bin releases) is a standard sha256sum-format
|
|
293
|
+
// line ("<hash> <filename>"). Try JSON first since that's this file's own
|
|
294
|
+
// real on-disk shape -- the sha256sum-line regex never matched it, silently
|
|
295
|
+
// returning {} and skipping verification on every bootstrap call.
|
|
296
|
+
try {
|
|
297
|
+
const parsed = JSON.parse(raw);
|
|
298
|
+
if (parsed && typeof parsed === 'object') {
|
|
299
|
+
const out = {};
|
|
300
|
+
for (const [name, sha] of Object.entries(parsed)) {
|
|
301
|
+
if (typeof sha === 'string') out[name] = sha.toLowerCase();
|
|
302
|
+
}
|
|
303
|
+
return out;
|
|
304
|
+
}
|
|
305
|
+
} catch (_) { /* not JSON, fall through to sha256sum-line parsing */ }
|
|
268
306
|
const out = {};
|
|
269
|
-
for (const line of
|
|
307
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
270
308
|
const m = line.match(/^([0-9a-f]{64})\s+(\S+)\s*$/i);
|
|
271
309
|
if (m) out[m[2]] = m[1].toLowerCase();
|
|
272
310
|
}
|
|
@@ -441,14 +479,39 @@ function httpGetBuffer(url, timeoutMs) {
|
|
|
441
479
|
});
|
|
442
480
|
}
|
|
443
481
|
|
|
444
|
-
|
|
482
|
+
// artifactName selects the REMOTE release asset ('plugkit.wasm' fat or
|
|
483
|
+
// 'plugkit-slim.wasm' slim) -- the local destPath filename is unaffected,
|
|
484
|
+
// same convention gm-runner's own download.rs::bootstrap_plugkit_wasm uses
|
|
485
|
+
// (fixed local name, artifact-selected remote source). A slim fetch that 404s
|
|
486
|
+
// (older release predating the slim publish step, or the asset genuinely
|
|
487
|
+
// missing) falls back to fetching fat rather than failing the whole
|
|
488
|
+
// bootstrap -- a host capable of running the slim build is also always a
|
|
489
|
+
// valid fat-build host (fat is a strict superset of slim's capability), so
|
|
490
|
+
// this fallback never produces incorrect behavior, only a larger download.
|
|
491
|
+
async function downloadFromGithubReleases(destPath, version, artifactName) {
|
|
492
|
+
const name = artifactName || 'plugkit.wasm';
|
|
445
493
|
const base = `https://github.com/AnEntrypoint/plugkit-bin/releases/download/v${version}`;
|
|
446
|
-
log(`gh-releases download: ${base}
|
|
447
|
-
|
|
448
|
-
|
|
494
|
+
log(`gh-releases download: ${base}/${name}`);
|
|
495
|
+
let buf;
|
|
496
|
+
try {
|
|
497
|
+
buf = await httpGetBuffer(`${base}/${name}`, 60000);
|
|
498
|
+
} catch (e) {
|
|
499
|
+
if (name !== 'plugkit.wasm') {
|
|
500
|
+
log(`gh-releases slim fetch failed (${e.message}); falling back to fat plugkit.wasm`);
|
|
501
|
+
return downloadFromGithubReleases(destPath, version, 'plugkit.wasm');
|
|
502
|
+
}
|
|
503
|
+
throw e;
|
|
504
|
+
}
|
|
505
|
+
if (!buf || buf.length < 1024) {
|
|
506
|
+
if (name !== 'plugkit.wasm') {
|
|
507
|
+
log(`gh-releases slim download too small (${buf ? buf.length : 0} bytes); falling back to fat plugkit.wasm`);
|
|
508
|
+
return downloadFromGithubReleases(destPath, version, 'plugkit.wasm');
|
|
509
|
+
}
|
|
510
|
+
throw new Error(`gh-releases download too small: ${buf ? buf.length : 0} bytes`);
|
|
511
|
+
}
|
|
449
512
|
let remoteSha = '';
|
|
450
513
|
try {
|
|
451
|
-
const shaBuf = await httpGetBuffer(`${base}
|
|
514
|
+
const shaBuf = await httpGetBuffer(`${base}/${name}.sha256`, 10000);
|
|
452
515
|
remoteSha = shaBuf.toString('utf-8').trim().split(/\s+/)[0];
|
|
453
516
|
} catch (e) { log(`gh-releases sha fetch failed: ${e.message}`); }
|
|
454
517
|
if (remoteSha) {
|
|
@@ -457,7 +520,7 @@ async function downloadFromGithubReleases(destPath, version) {
|
|
|
457
520
|
log(`gh-releases sha verified ${got.slice(0, 16)}...`);
|
|
458
521
|
}
|
|
459
522
|
fs.writeFileSync(destPath, buf);
|
|
460
|
-
log(`gh-releases wrote ${buf.length} bytes to ${destPath}`);
|
|
523
|
+
log(`gh-releases wrote ${buf.length} bytes to ${destPath} (artifact=${name})`);
|
|
461
524
|
}
|
|
462
525
|
|
|
463
526
|
async function extractNpmPackageWithRetry(destPath, version) {
|
|
@@ -625,14 +688,27 @@ async function bootstrap(opts) {
|
|
|
625
688
|
opts = opts || {};
|
|
626
689
|
const version = readVersionFile();
|
|
627
690
|
const shaManifest = readShaManifest();
|
|
691
|
+
// Artifact selection: slim (no wasm-embedded safetensors, ~130MB smaller)
|
|
692
|
+
// only when this host has a native host_vec_embed answerer on disk
|
|
693
|
+
// (gm-runner or agentplug-runner under ~/.gm-tools -- see
|
|
694
|
+
// hasNativeEmbedRunner) -- everyone else fetches fat, unchanged from
|
|
695
|
+
// before this selection logic existed. remoteArtifact is the release-asset
|
|
696
|
+
// name; the LOCAL cache filename stays 'plugkit.wasm' either way (matching
|
|
697
|
+
// gm-runner's own download.rs convention) so nothing downstream that reads
|
|
698
|
+
// the local wasm path needs to know which variant landed. The cache
|
|
699
|
+
// sub-directory is kept distinct per-kind (v<version> vs v<version>-slim)
|
|
700
|
+
// so a fat and slim download of the same version never collide under the
|
|
701
|
+
// same sha/sentinel check.
|
|
702
|
+
const useSlim = hasNativeEmbedRunner();
|
|
703
|
+
const remoteArtifact = useSlim ? 'plugkit-slim.wasm' : 'plugkit.wasm';
|
|
628
704
|
const wasmName = 'plugkit.wasm';
|
|
629
|
-
const expectedSha = shaManifest ? shaManifest[wasmName] : null;
|
|
705
|
+
const expectedSha = shaManifest ? (shaManifest[remoteArtifact] || (useSlim ? null : shaManifest[wasmName])) : null;
|
|
630
706
|
|
|
631
707
|
let root = cacheRoot();
|
|
632
708
|
try { ensureDir(root); }
|
|
633
709
|
catch (_) { root = fallbackCacheRoot(); ensureDir(root); }
|
|
634
710
|
|
|
635
|
-
const verDir = path.join(root, `v${version}`);
|
|
711
|
+
const verDir = path.join(root, useSlim ? `v${version}-slim` : `v${version}`);
|
|
636
712
|
ensureDir(verDir);
|
|
637
713
|
|
|
638
714
|
const finalPath = path.join(verDir, wasmName);
|
|
@@ -696,20 +772,38 @@ async function bootstrap(opts) {
|
|
|
696
772
|
}
|
|
697
773
|
} catch (_) {}
|
|
698
774
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
775
|
+
if (useSlim) {
|
|
776
|
+
// The plugkit-wasm npm package only ever ships the fat artifact (see
|
|
777
|
+
// release.yml's npm-publish step, which cp's release-assets/plugkit.wasm
|
|
778
|
+
// -- never plugkit-slim.wasm -- into the package). Skip the npm-extract
|
|
779
|
+
// attempt entirely for a slim fetch and go straight to GitHub Releases,
|
|
780
|
+
// which is where slim is actually published.
|
|
703
781
|
try {
|
|
704
|
-
await downloadFromGithubReleases(partialPath, version);
|
|
782
|
+
await downloadFromGithubReleases(partialPath, version, remoteArtifact);
|
|
705
783
|
} catch (ghErr) {
|
|
706
784
|
writeBootstrapError({
|
|
707
785
|
expected_version: version, cached_version: null,
|
|
708
|
-
error_phase: '
|
|
709
|
-
error_message: `
|
|
786
|
+
error_phase: 'gh-releases-slim',
|
|
787
|
+
error_message: `gh: ${ghErr.message}`,
|
|
710
788
|
});
|
|
711
789
|
throw ghErr;
|
|
712
790
|
}
|
|
791
|
+
} else {
|
|
792
|
+
try {
|
|
793
|
+
await extractNpmPackageWithRetry(partialPath, version);
|
|
794
|
+
} catch (extractErr) {
|
|
795
|
+
log(`npm-extract failed (${extractErr.message || extractErr}); falling back to GitHub Releases`);
|
|
796
|
+
try {
|
|
797
|
+
await downloadFromGithubReleases(partialPath, version, remoteArtifact);
|
|
798
|
+
} catch (ghErr) {
|
|
799
|
+
writeBootstrapError({
|
|
800
|
+
expected_version: version, cached_version: null,
|
|
801
|
+
error_phase: 'npm-extract+gh-fallback',
|
|
802
|
+
error_message: `npm: ${extractErr.message}; gh: ${ghErr.message}`,
|
|
803
|
+
});
|
|
804
|
+
throw ghErr;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
713
807
|
}
|
|
714
808
|
|
|
715
809
|
if (expectedSha) {
|
|
@@ -740,7 +834,15 @@ async function bootstrap(opts) {
|
|
|
740
834
|
log(`decision: fetch reason: install-complete (${finalPath})`);
|
|
741
835
|
obsEvent('bootstrap', 'install.done', { path: finalPath, version, kind: 'plugkit-wasm' });
|
|
742
836
|
proactiveKillForNewInstall(version);
|
|
743
|
-
pruneOldVersions
|
|
837
|
+
// pruneOldVersions keeps only the dir literally named v<keepVersion> --
|
|
838
|
+
// verDir uses a '-slim' suffix for the slim cache slot (see useSlim
|
|
839
|
+
// above), so the keep-token passed here must match that same suffix or
|
|
840
|
+
// pruneOldVersions deletes the directory just populated by THIS run
|
|
841
|
+
// before copyWasmToGmTools below can read from it (live-witnessed this
|
|
842
|
+
// session: a real end-to-end bootstrap() run on a native-runner host hit
|
|
843
|
+
// exactly this -- 'pruned .../v0.1.906-slim' followed by an ENOENT on the
|
|
844
|
+
// immediately-following copy, because 'v0.1.906' != 'v0.1.906-slim').
|
|
845
|
+
pruneOldVersions(root, useSlim ? `${version}-slim` : version);
|
|
744
846
|
copyWasmToGmTools(finalPath, version);
|
|
745
847
|
clearBootstrapError();
|
|
746
848
|
return finalPath;
|
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.1989",
|
|
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": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
44fe1ce8f27bc716b366b881d2ece7529487cec1ac1398bd4f8f097c3c291020 plugkit-slim.wasm
|
|
@@ -1936,6 +1936,10 @@ globalThis.__hostEmbedSync = function __hostEmbedSync(textPtr, textLen, outPtr,
|
|
|
1936
1936
|
|
|
1937
1937
|
function makeHostFunctions(instanceRef) {
|
|
1938
1938
|
return {
|
|
1939
|
+
host_cwd: () => {
|
|
1940
|
+
const cwd = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
1941
|
+
return writeWasmStr(instanceRef.value, cwd);
|
|
1942
|
+
},
|
|
1939
1943
|
host_fs_read: (pathPtr, pathLen) => {
|
|
1940
1944
|
try {
|
|
1941
1945
|
const filePath = readWasmStr(instanceRef.value, pathPtr, pathLen);
|
|
@@ -4601,6 +4605,17 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
4601
4605
|
await new Promise(() => {});
|
|
4602
4606
|
}
|
|
4603
4607
|
|
|
4608
|
+
// Slim eligibility mirrors bootstrap.js's own hasNativeEmbedRunner (same
|
|
4609
|
+
// on-disk check, duplicated rather than shared because this file is ESM and
|
|
4610
|
+
// bootstrap.js is CJS with no shared module between them today) -- a slim
|
|
4611
|
+
// fetch here is only correct when a real host_vec_embed answerer
|
|
4612
|
+
// (resolveGmRunnerEmbedBin / resolveAgentplugRunnerBin, both already defined
|
|
4613
|
+
// above for the runtime embed-delegation path) is present on disk, since a
|
|
4614
|
+
// slim wasm has no fallback embedding path of its own.
|
|
4615
|
+
function hasNativeEmbedRunnerForSelfHeal() {
|
|
4616
|
+
return !!(resolveGmRunnerEmbedBin() || resolveAgentplugRunnerBin());
|
|
4617
|
+
}
|
|
4618
|
+
|
|
4604
4619
|
async function selfHealFromGithubReleases() {
|
|
4605
4620
|
return new Promise((resolve, reject) => {
|
|
4606
4621
|
const fetchJson = (url) => new Promise((res, rej) => {
|
|
@@ -4635,10 +4650,30 @@ async function selfHealFromGithubReleases() {
|
|
|
4635
4650
|
const version = meta && meta.version;
|
|
4636
4651
|
if (!version) throw new Error('no version from npm plugkit-wasm');
|
|
4637
4652
|
const base = `https://github.com/AnEntrypoint/plugkit-bin/releases/download/v${version}`;
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4653
|
+
// Slim only when a real host_vec_embed answerer is present -- see
|
|
4654
|
+
// hasNativeEmbedRunnerForSelfHeal. A slim asset that 404s (older
|
|
4655
|
+
// release predating slim publish) falls back to fat rather than
|
|
4656
|
+
// failing self-heal entirely, since fat is a strict capability
|
|
4657
|
+
// superset and always a safe (if larger) substitute.
|
|
4658
|
+
const wantSlim = hasNativeEmbedRunnerForSelfHeal();
|
|
4659
|
+
let artifactName = wantSlim ? 'plugkit-slim.wasm' : 'plugkit.wasm';
|
|
4660
|
+
let wasm, sha;
|
|
4661
|
+
try {
|
|
4662
|
+
[wasm, sha] = await Promise.all([
|
|
4663
|
+
fetchBuf(`${base}/${artifactName}`),
|
|
4664
|
+
fetchBuf(`${base}/${artifactName}.sha256`).then(b => b.toString('utf-8').trim().split(/\s+/)[0]).catch(() => ''),
|
|
4665
|
+
]);
|
|
4666
|
+
} catch (e) {
|
|
4667
|
+
if (artifactName !== 'plugkit.wasm') {
|
|
4668
|
+
artifactName = 'plugkit.wasm';
|
|
4669
|
+
[wasm, sha] = await Promise.all([
|
|
4670
|
+
fetchBuf(`${base}/${artifactName}`),
|
|
4671
|
+
fetchBuf(`${base}/${artifactName}.sha256`).then(b => b.toString('utf-8').trim().split(/\s+/)[0]).catch(() => ''),
|
|
4672
|
+
]);
|
|
4673
|
+
} else {
|
|
4674
|
+
throw e;
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4642
4677
|
if (sha) {
|
|
4643
4678
|
const got = crypto.createHash('sha256').update(wasm).digest('hex');
|
|
4644
4679
|
if (got !== sha) throw new Error(`sha mismatch: got ${got}, expected ${sha}`);
|
|
@@ -4664,7 +4699,7 @@ async function selfHealFromGithubReleases() {
|
|
|
4664
4699
|
if (path.resolve(wrapperSrc) !== path.resolve(wrapperDst) && fs.existsSync(wrapperSrc)) {
|
|
4665
4700
|
try { fs.copyFileSync(wrapperSrc, wrapperDst); } catch (_) {}
|
|
4666
4701
|
}
|
|
4667
|
-
resolve({ ok: true, version, sha });
|
|
4702
|
+
resolve({ ok: true, version, sha, artifact: artifactName });
|
|
4668
4703
|
} catch (e) { reject(e); }
|
|
4669
4704
|
})();
|
|
4670
4705
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.914
|
package/gm.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1989",
|
|
4
4
|
"description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
"publishConfig": {
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
|
-
"plugkitVersion": "0.1.
|
|
20
|
+
"plugkitVersion": "0.1.914"
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1989",
|
|
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",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"bin/plugkit.sha256",
|
|
37
37
|
"bin/plugkit.version",
|
|
38
38
|
"bin/plugkit.wasm.sha256",
|
|
39
|
+
"bin/plugkit-slim.wasm.sha256",
|
|
39
40
|
"gm-plugkit/bootstrap.js",
|
|
40
41
|
"gm-plugkit/browser-idle.js",
|
|
41
42
|
"gm-plugkit/cli.js",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"gm-plugkit/gm-process.js",
|
|
48
49
|
"gm-plugkit/plugkit.version",
|
|
49
50
|
"gm-plugkit/plugkit.sha256",
|
|
51
|
+
"gm-plugkit/plugkit-slim.wasm.sha256",
|
|
50
52
|
"gm-plugkit/instructions/",
|
|
51
53
|
"gm-plugkit/scripts/",
|
|
52
54
|
"AGENTS.md",
|