gm-skill 2.0.1931 → 2.0.1933

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1931",
3
+ "version": "2.0.1933",
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": {
@@ -4788,6 +4788,7 @@ async function runSpoolWatcher(instance, spoolDir) {
4788
4788
  phase,
4789
4789
  last_skill: lastSkill,
4790
4790
  prd_pending: prdPending,
4791
+ prd_pending_count: prdPending,
4791
4792
  last_instruction_ts: lastInstructionTs,
4792
4793
  last_instruction_age_ms: lastInstructionAgeMs,
4793
4794
  long_gap_threshold_ms: 300000,
@@ -6,12 +6,11 @@ const path = require('path');
6
6
  const os = require('os');
7
7
  const crypto = require('crypto');
8
8
  const { spawn, spawnSync } = require('child_process');
9
+ const { gmToolsDir } = require('./bootstrap');
9
10
 
10
11
  function wrapperSha12OnDisk() {
11
12
  try {
12
- const primary = path.join(os.homedir(), '.gm-tools', 'plugkit-wasm-wrapper.js');
13
- const fallback = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
14
- const wp = fs.existsSync(primary) ? primary : fallback;
13
+ const wp = path.join(gmToolsDir(), 'plugkit-wasm-wrapper.js');
15
14
  return crypto.createHash('sha256').update(fs.readFileSync(wp)).digest('hex').slice(0, 12);
16
15
  } catch (_) { return null; }
17
16
  }
@@ -200,9 +199,7 @@ function spawnWatcher(bootReason) {
200
199
  return;
201
200
  }
202
201
 
203
- const primaryWrapper = path.join(os.homedir(), '.gm-tools', 'plugkit-wasm-wrapper.js');
204
- const fallbackWrapper = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
205
- const wrapper = fs.existsSync(primaryWrapper) ? primaryWrapper : fallbackWrapper;
202
+ const wrapper = path.join(gmToolsDir(), 'plugkit-wasm-wrapper.js');
206
203
  if (!fs.existsSync(wrapper)) {
207
204
  logEvent('supervisor.wrapper-missing', { wrapper, severity: 'critical' });
208
205
  writeSupervisorStatus('error', { error: 'wrapper-missing' });
@@ -379,10 +376,7 @@ function checkWatcherHealth() {
379
376
  severity: 'critical',
380
377
  });
381
378
  try {
382
- const home = process.env.USERPROFILE || process.env.HOME || require('os').homedir();
383
- const gmTools = fs.existsSync(path.join(home, '.gm-tools'))
384
- ? path.join(home, '.gm-tools')
385
- : path.join(home, '.claude', 'gm-tools');
379
+ const gmTools = gmToolsDir();
386
380
  for (const f of ['plugkit.wasm', 'plugkit.version', 'plugkit.wasm.sha256']) {
387
381
  try { fs.unlinkSync(path.join(gmTools, f)); } catch (_) {}
388
382
  }
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1931",
3
+ "version": "2.0.1933",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1931",
3
+ "version": "2.0.1933",
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",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gm
3
3
  description: The primary driver for any non-trivial coding, refactoring, debugging, or multi-step engineering task in a project using this harness -- use it first, for the whole task, not just a piece of it. Plugkit-served instruction stream. Three-layer admission (witness, single-writer, direction) over every possible mutation; effort unbounded, never gated on cost. Closure on first emit; partial = non-monotonic. Not for the post-completion remaining-work check (that is `gm-continue`) or for drift-recovery mid-task (that is `wfgy-method`) -- this skill is the work itself.
4
- allowed-tools: Skill, Read, Write, Bash(bun *), Bash(npx *), Bash(cat *), Bash(date *)
4
+ allowed-tools: Skill, Read, Write, AskUserQuestion, Bash(bun *), Bash(npx *), Bash(cat *), Bash(date *)
5
5
  ---
6
6
 
7
7
  # gm
@@ -72,7 +72,7 @@ The `Resolving dependencies` / `Saved lockfile` chatter before the JSON payload
72
72
 
73
73
  **Waiting out a real `busy_until` window (a long `browser`/`exec_js` dispatch genuinely still running) is not the same thing as the banned bare-`sleep`-then-`ls` poll above -- the ban is on blind, unconditional sleeping when nothing indicates work is actually in flight; a live `busy_until` in the future is exactly the condition that licenses a bounded wait for it.** On a host with a background-monitor primitive (a tool that runs a shell condition and notifies on completion rather than blocking the turn), the correct shape is a condition loop over the OUT file's existence, not a fixed-duration sleep: `until [ -f .gm/exec-spool/out/<verb>-<N>.json ]; do sleep 2; done` handed to that primitive, so the wait happens off-turn and a completion notification (not a guessed delay) resumes work. On a host with no such primitive, a single bounded `sleep` no longer than the dispatch's own declared `busy_until` remaining-window (never an arbitrary guess, never chained/repeated past that one wait) is the fallback -- re-check `.status.json`'s `ts`/`busy_until` once after it elapses, do not loop blind sleeps. Either way: never poll faster than realistic verb latency (sub-second loops are themselves a form of the banned pattern), and never fall back to declaring the watcher dead just because a wait felt long -- dead is defined structurally (stale `ts` AND no future `busy_until`), not by elapsed wall-clock alone.
74
74
 
75
- **Reboot-loop escape (watcher dies ~30-90s after every boot).** If a fresh `bun x gm-plugkit@latest spool` boots but the watcher dies again shortly after (heartbeat `ts` goes stale >30s with no future `busy_until`, then a new pid appears, repeatedly), a plain re-boot cannot fix it -- the on-disk index has not finished embedding and each boot re-triggers the same synchronous code-index embed that blocks the heartbeat past the supervisor's 30s stale limit (`STATUS_STALE_MS`), so the supervisor kills the watcher mid-rebuild every time. Confirm by reading `.gm/exec-spool/.watcher.log` for repeated `codeinsight_rebuild` + `partial pass (wall budget) ... deferred_files=N` lines whose `deferred_files` never reaches 0. Two fixes, in order: (1) update the installed wrapper -- an installed `~/.gm-tools/plugkit-wasm-wrapper.js` older than the shipped one refreshes `busy_until` only once at boot instead of once per warmup pass, so the embed's later passes lapse the window; reinstall the current gm-plugkit build so the wrapper's warmup loop holds `busy_until` until `deferred_files==0`. (2) If reinstall is unavailable, let the index converge WITHOUT rebooting: after a boot, do NOT immediately re-boot on the first stale reading -- read `.watcher.log`, and as long as `deferred_files` is strictly decreasing across `codeinsight_index_partial` events the index is converging (each accepted verb advances it one wall-budget); give it repeated single verbs until a `code_index: done` / `deferred_files=0` line appears, then normal dispatch resumes. Rebooting mid-convergence resets this progress -- the loop is the reboot, not the embed. The proper durable fix is a host-project one (make `spool` overwrite a stale installed wrapper from the just-resolved bundled build); until that ships, drive real work via native tools and treat the spool as optional bookkeeping.
75
+ **Reboot-loop escape (watcher dies ~30-90s after every boot).** If a fresh `bun x gm-plugkit@latest spool` boots but the watcher dies again shortly after (heartbeat `ts` goes stale >30s with no future `busy_until`, then a new pid appears, repeatedly), the on-disk index has not finished embedding and each boot re-triggers the same synchronous code-index embed that can block the heartbeat past the supervisor's 30s stale limit (`STATUS_STALE_MS`). Confirm by reading `.gm/exec-spool/.watcher.log` for repeated `codeinsight_rebuild` + `partial pass (wall budget) ... deferred_files=N` lines whose `deferred_files` never reaches 0. The durable fix has shipped: every `bun x gm-plugkit@latest spool` boot calls `ensureWrapperFresh()` (`gm-plugkit/bootstrap.js`), which sha256-compares the installed `~/.gm-tools/plugkit-wasm-wrapper.js` against the bundled one and atomically force-replaces it on any mismatch (lock-guarded, tmp-write-then-rename, safe under concurrent per-project watchers) -- a stale installed wrapper self-heals on the very next boot, no manual reinstall needed. If the loop persists even on a freshly-synced wrapper, the embed itself is still genuinely converging: do NOT immediately re-boot on the first stale reading -- read `.watcher.log`, and as long as `deferred_files` is strictly decreasing across `codeinsight_index_partial` events the index is converging (each accepted verb advances it one wall-budget); give it repeated single verbs until a `code_index: done` / `deferred_files=0` line appears, then normal dispatch resumes. Rebooting mid-convergence resets this progress -- the loop is the reboot, not the embed.
76
76
 
77
77
  **Apparent tooling failure is never grounds to ask the user, never a blind restart.** "Spooler not working" / missing response / stale watcher / `gm_plugkit_stale` flagged in a response = your own mechanical self-recovery: honor a future `busy_until` (wait), else boot + re-dispatch. You have boot authority; asking the user to do what a verb can do is a deviation. Staleness of any kind (stale watcher version, stale served prose vs published source) is itself a deviation to resolve immediately, the same turn it's noticed -- `bun x gm-plugkit@latest spool` first, before any other work.
78
78