gm-skill 2.0.1260 → 2.0.1261

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 CHANGED
@@ -35,7 +35,7 @@ An earlier generation fanned out fifteen per-platform downstream repos (gm-cc, g
35
35
 
36
36
  ## Version
37
37
 
38
- `2.0.1260` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` (or any cascading sibling crate) republishes this package.
38
+ `2.0.1261` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` (or any cascading sibling crate) republishes this package.
39
39
 
40
40
  ## Source of truth
41
41
 
package/bin/bootstrap.js CHANGED
@@ -34,7 +34,8 @@ function resolveWindowsExe(cmd) {
34
34
  if (r.status !== 0) return cmd;
35
35
  const lines = (r.stdout || '').split(/\r?\n/).map(l => l.trim()).filter(Boolean);
36
36
  const exe = lines.find(l => /\.exe$/i.test(l));
37
- return exe || lines[0] || cmd;
37
+ const shim = lines.find(l => /\.(cmd|bat)$/i.test(l));
38
+ return exe || shim || cmd;
38
39
  } catch {
39
40
  return cmd;
40
41
  }
@@ -299,6 +300,10 @@ async function extractNpmPackageWithRetry(destPath, version) {
299
300
  lastErr = err;
300
301
  log(`attempt ${attempt} failed: ${err.message}`);
301
302
  obsEvent('bootstrap', 'npm.extract.attempt_failed', { package: NPM_PACKAGE, attempt, max: MAX_ATTEMPTS, err: String(err.message || err) });
303
+ if (err && (err.code === 'ENOENT' || /ENOENT/.test(String(err.message || '')))) {
304
+ log(`npx binary unresolvable (ENOENT); skipping retries, falling back`);
305
+ throw err;
306
+ }
302
307
  if (attempt < MAX_ATTEMPTS) {
303
308
  const wait = BACKOFF_MS[attempt - 1] || 120000;
304
309
  log(`backing off ${wait}ms`);
@@ -23,7 +23,8 @@ function resolveWindowsExe(cmd) {
23
23
  if (r.status !== 0) return cmd;
24
24
  const lines = (r.stdout || '').split(/\r?\n/).map(l => l.trim()).filter(Boolean);
25
25
  const exe = lines.find(l => /\.exe$/i.test(l));
26
- return exe || lines[0] || cmd;
26
+ const shim = lines.find(l => /\.(cmd|bat)$/i.test(l));
27
+ return exe || shim || cmd;
27
28
  } catch {
28
29
  return cmd;
29
30
  }
@@ -300,6 +301,10 @@ async function extractNpmPackageWithRetry(destPath, version) {
300
301
  lastErr = err;
301
302
  log(`attempt ${attempt} failed: ${err.message}`);
302
303
  obsEvent('bootstrap', 'npm.extract.attempt_failed', { package: NPM_PACKAGE, attempt, max: MAX_ATTEMPTS, err: String(err.message || err) });
304
+ if (err && (err.code === 'ENOENT' || /ENOENT/.test(String(err.message || '')))) {
305
+ log(`npm binary unresolvable (ENOENT); skipping retries, falling back`);
306
+ throw err;
307
+ }
303
308
  if (attempt < MAX_ATTEMPTS) {
304
309
  const wait = BACKOFF_MS[attempt - 1] || 120000;
305
310
  log(`backing off ${wait}ms`);
@@ -541,7 +541,8 @@ function resolveWindowsExeLocal(cmd) {
541
541
  if (out.status !== 0) return cmd;
542
542
  const lines = (out.stdout || '').split(/\r?\n/).map(l => l.trim()).filter(Boolean);
543
543
  const exe = lines.find(l => /\.exe$/i.test(l));
544
- return exe || lines[0] || cmd;
544
+ const shim = lines.find(l => /\.(cmd|bat)$/i.test(l));
545
+ return exe || shim || cmd;
545
546
  } catch {
546
547
  return cmd;
547
548
  }
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1260",
3
+ "version": "2.0.1261",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -21,7 +21,8 @@ function resolveWindowsExe(cmd) {
21
21
  });
22
22
  const lines = out.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
23
23
  const exe = lines.find(l => /\.exe$/i.test(l));
24
- return exe || lines[0] || cmd;
24
+ const shim = lines.find(l => /\.(cmd|bat)$/i.test(l));
25
+ return exe || shim || cmd;
25
26
  } catch {
26
27
  return cmd;
27
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1260",
3
+ "version": "2.0.1261",
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.1260"
42
+ "gm-plugkit": "^2.0.1261"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=16.0.0"
@@ -20,6 +20,8 @@ bun x gm-plugkit@latest spool > /dev/null 2>&1 &
20
20
 
21
21
  (`npx -y gm-plugkit@latest spool > /dev/null 2>&1 &` if `bun` missing.) Heartbeat fresh → YOU dispatch `instruction` — first turn body `{"prompt":"<user request>"}` so orient_nouns and recall_hits derive from the request; subsequent turns may use empty body. Read the response file directly with the Read tool. 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 (check `.status.json` mtime) or the verb is slow (check `.watcher.log`), not "still processing."
22
22
 
23
+ **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.
24
+
23
25
  Response body is not a mutation surface. Memory writes route through `memorize-fire` only — another verb YOU dispatch.
24
26
 
25
27
  On turn entry (first `instruction` dispatch after a >30s idle gap or session-start), plugkit attaches an `auto_recall` pack to your `instruction` response: `{query, hits, fired_at, turn_entry: true}`. The query is derived from `.gm/last-prompt.txt` / `.gm/turn-state.json`; hits are the top recall results plugkit pulled before serving your instruction. Read `auto_recall.hits` alongside the existing `recall_hits` (which is the phase+PRD-subject pack) — both surface prior memory, but `auto_recall` is the per-turn user-prompt pack and only fires on turn entry. Subsequent `instruction` dispatches in the same turn carry no `auto_recall` field (or carry the same pack from the turn-start fire); do not re-trigger it manually.