gm-skill 2.0.1363 → 2.0.1365

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.1363",
3
+ "version": "2.0.1365",
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": {
@@ -2059,6 +2059,7 @@ async function runSpoolWatcher(instance, spoolDir) {
2059
2059
  }, 5000);
2060
2060
 
2061
2061
  let _selfStaleLoggedOnce = false;
2062
+ let _selfStaleProbeErrorLogged = false;
2062
2063
  function probeGmPlugkitSelfStale() {
2063
2064
  try {
2064
2065
  const ownPkgVersionFile = path.join(GM_TOOLS_ROOT, 'gm-plugkit.version');
@@ -2072,11 +2073,19 @@ async function runSpoolWatcher(instance, spoolDir) {
2072
2073
  }
2073
2074
  if (!own) return;
2074
2075
  const https = require('https');
2075
- const req = https.get('https://registry.npmjs.org/gm-plugkit/latest', { timeout: 3000 }, (res) => {
2076
+ let _probeErrored = false;
2077
+ const req = https.get('https://registry.npmjs.org/gm-plugkit/latest', { timeout: 10000, headers: { 'user-agent': 'plugkit-watcher' } }, (res) => {
2076
2078
  let body = '';
2077
2079
  res.on('data', (c) => body += c);
2078
2080
  res.on('end', () => {
2079
2081
  try {
2082
+ if (res.statusCode !== 200) {
2083
+ if (!_selfStaleProbeErrorLogged) {
2084
+ _selfStaleProbeErrorLogged = true;
2085
+ try { logEvent('plugkit', 'gm-plugkit.self-stale-probe-error', { reason: `http-${res.statusCode}` }); } catch (_) {}
2086
+ }
2087
+ return;
2088
+ }
2080
2089
  const latest = JSON.parse(body).version;
2081
2090
  const stalePath = path.join(spoolDir, '.gm-plugkit-stale.json');
2082
2091
  if (!latest || latest === own) {
@@ -2088,7 +2097,7 @@ async function runSpoolWatcher(instance, spoolDir) {
2088
2097
  reason: 'gm-plugkit-self-stale',
2089
2098
  running_version: own,
2090
2099
  latest_version: latest,
2091
- instruction: `gm-plugkit running ${own} but npm has ${latest}. The npx/bun cache served a stale copy. Clear the cache so the next invocation picks up the latest wrapper fixes: bun pm cache rm; or npx clear-npx-cache; or rm -rf ~/.npm/_npx ~/AppData/Local/npm-cache/_npx`,
2100
+ instruction: `gm-plugkit running ${own} but npm has ${latest}. The npx/bun cache served a stale copy. Run 'bun x gm-plugkit@latest --kill-stale-watchers' then re-bootstrap. Or clear the cache directly: bun pm cache rm; or rm -rf ~/.npm/_npx ~/AppData/Local/npm-cache/_npx`,
2092
2101
  detected_by: 'watcher-periodic-probe',
2093
2102
  };
2094
2103
  try { fs.writeFileSync(stalePath, JSON.stringify(marker, null, 2)); } catch (_) {}
@@ -2097,11 +2106,31 @@ async function runSpoolWatcher(instance, spoolDir) {
2097
2106
  try { logEvent('plugkit', 'gm-plugkit.self-stale', { running_version: own, latest_version: latest, detected_by: 'watcher-periodic-probe' }); } catch (_) {}
2098
2107
  console.error(`[plugkit-wasm] gm-plugkit self-stale: running ${own}, latest npm ${latest} (marker at .gm/exec-spool/.gm-plugkit-stale.json)`);
2099
2108
  }
2100
- } catch (_) {}
2109
+ } catch (e) {
2110
+ if (!_selfStaleProbeErrorLogged) {
2111
+ _selfStaleProbeErrorLogged = true;
2112
+ try { logEvent('plugkit', 'gm-plugkit.self-stale-probe-error', { reason: 'parse', error: String(e && e.message || e).slice(0, 200) }); } catch (_) {}
2113
+ }
2114
+ }
2101
2115
  });
2102
2116
  });
2103
- req.on('error', () => {});
2104
- req.on('timeout', () => { try { req.destroy(); } catch (_) {} });
2117
+ req.on('error', (e) => {
2118
+ if (_probeErrored) return;
2119
+ _probeErrored = true;
2120
+ if (!_selfStaleProbeErrorLogged) {
2121
+ _selfStaleProbeErrorLogged = true;
2122
+ try { logEvent('plugkit', 'gm-plugkit.self-stale-probe-error', { reason: 'network', error: String(e && e.message || e).slice(0, 200) }); } catch (_) {}
2123
+ }
2124
+ });
2125
+ req.on('timeout', () => {
2126
+ if (_probeErrored) { try { req.destroy(); } catch (_) {} return; }
2127
+ _probeErrored = true;
2128
+ try { req.destroy(); } catch (_) {}
2129
+ if (!_selfStaleProbeErrorLogged) {
2130
+ _selfStaleProbeErrorLogged = true;
2131
+ try { logEvent('plugkit', 'gm-plugkit.self-stale-probe-error', { reason: 'timeout' }); } catch (_) {}
2132
+ }
2133
+ });
2105
2134
  } catch (_) {}
2106
2135
  }
2107
2136
  setTimeout(probeGmPlugkitSelfStale, 5000);
@@ -2672,8 +2701,17 @@ async function runSpoolWatcher(instance, spoolDir) {
2672
2701
  function clearSharedUpdateErrorKey() {
2673
2702
  try { fs.unlinkSync(UPDATE_CHECK_ERROR_MARKER); } catch (_) {}
2674
2703
  }
2704
+ function normalizeUpdateErrorCategory(fields) {
2705
+ if (fields.status && fields.status !== 200) return `http-${fields.status}`;
2706
+ const err = String(fields.error || '').toLowerCase();
2707
+ if (!err) return 'unknown';
2708
+ if (/timeout|timed out|etimedout/.test(err)) return 'network';
2709
+ if (/socket hang up|econnreset|econnrefused|enotfound|eai_again|enetunreach|ehostunreach|getaddrinfo/.test(err)) return 'network';
2710
+ if (/json|parse|unexpected/.test(err)) return 'parse';
2711
+ return 'other';
2712
+ }
2675
2713
  function logUpdateCheckError(fields) {
2676
- const key = `${fields.status || ''}:${fields.error || ''}`;
2714
+ const key = normalizeUpdateErrorCategory(fields);
2677
2715
  if (_lastKnownUpdateError === key) return;
2678
2716
  const shared = readSharedUpdateErrorKey();
2679
2717
  if (shared === key) {
@@ -2682,7 +2720,7 @@ async function runSpoolWatcher(instance, spoolDir) {
2682
2720
  }
2683
2721
  _lastKnownUpdateError = key;
2684
2722
  writeSharedUpdateErrorKey(key);
2685
- logEvent('plugkit', 'update.check.error', fields);
2723
+ logEvent('plugkit', 'update.check.error', { ...fields, category: key });
2686
2724
  }
2687
2725
  function clearUpdateCheckError(installed) {
2688
2726
  const shared = readSharedUpdateErrorKey();
@@ -2774,12 +2812,17 @@ async function runSpoolWatcher(instance, spoolDir) {
2774
2812
  }
2775
2813
  });
2776
2814
  });
2815
+ let _checkErrored = false;
2777
2816
  req.on('timeout', () => {
2778
- req.destroy();
2817
+ if (_checkErrored) { try { req.destroy(); } catch (_) {} return; }
2818
+ _checkErrored = true;
2819
+ try { req.destroy(); } catch (_) {}
2779
2820
  writeSharedUpdateCache(null, -1);
2780
2821
  logUpdateCheckError({ error: 'timeout' });
2781
2822
  });
2782
2823
  req.on('error', (e) => {
2824
+ if (_checkErrored) return;
2825
+ _checkErrored = true;
2783
2826
  writeSharedUpdateCache(null, -2);
2784
2827
  logUpdateCheckError({ error: String(e && e.message || e) });
2785
2828
  });
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1363",
3
+ "version": "2.0.1365",
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.1363",
3
+ "version": "2.0.1365",
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",