gm-codex 2.0.967 → 2.0.968

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-codex",
3
- "version": "2.0.967",
3
+ "version": "2.0.968",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": {
6
6
  "name": "AnEntrypoint",
package/bin/bootstrap.js CHANGED
@@ -183,9 +183,7 @@ function acquireLock(lockPath) {
183
183
  continue;
184
184
  }
185
185
  if (Date.now() - start > ATTEMPT_TIMEOUT_MS) throw new Error(`lock wait timeout: ${lockPath}`);
186
- const waitMs = 2000;
187
- const deadline = Date.now() + waitMs;
188
- while (Date.now() < deadline) {}
186
+ try { const { spawnSync } = require('child_process'); spawnSync(process.execPath, ['-e', 'setTimeout(()=>{}, 2000)'], { timeout: 2500, killSignal: 'SIGKILL' }); } catch (_) {}
189
187
  }
190
188
  }
191
189
  }
@@ -382,8 +380,7 @@ async function bootstrap(opts) {
382
380
  if (!opts.silent) log(`cache heal (sha match): ${finalPath}${actualVersion ? ` (matches pin v${version})` : ''}`);
383
381
  proactiveKillForNewInstall(version, finalPath);
384
382
  pruneOldVersions(root, version, readRtkVersion(wrapperDir));
385
- try { await bootstrapRtk(verDir, version, wrapperDir, opts.silent, root); }
386
- catch (err) { log(`rtk fetch skipped: ${err.message}`); }
383
+ bootstrapRtk(verDir, version, wrapperDir, opts.silent, root).catch(err => log(`rtk fetch skipped: ${err.message}`));
387
384
  return finalPath;
388
385
  }
389
386
  }
@@ -400,8 +397,7 @@ async function bootstrap(opts) {
400
397
  log(`cache heal (sha match) under lock: ${finalPath}`);
401
398
  proactiveKillForNewInstall(version, finalPath);
402
399
  pruneOldVersions(root, version, readRtkVersion(wrapperDir));
403
- try { await bootstrapRtk(verDir, version, wrapperDir, opts.silent, root); }
404
- catch (err) { log(`rtk fetch skipped: ${err.message}`); }
400
+ bootstrapRtk(verDir, version, wrapperDir, opts.silent, root).catch(err => log(`rtk fetch skipped: ${err.message}`));
405
401
  return finalPath;
406
402
  }
407
403
 
@@ -654,7 +650,7 @@ function listRunningPlugkitImagePaths() {
654
650
  out.push({ pid, path: imagePath });
655
651
  }
656
652
  } else {
657
- const r = spawnSync('ps', ['-axo', 'pid=,comm='], { encoding: 'utf8' });
653
+ const r = spawnSync('ps', ['-axo', 'pid=,comm='], { encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL' });
658
654
  const text = (r && r.stdout) || '';
659
655
  for (const line of text.split(/\r?\n/)) {
660
656
  const m = line.match(/^\s*(\d+)\s+(.+?)\s*$/);
@@ -663,7 +659,7 @@ function listRunningPlugkitImagePaths() {
663
659
  const pid = parseInt(m[1], 10);
664
660
  let imagePath = '';
665
661
  try {
666
- const p = spawnSync('ps', ['-p', String(pid), '-o', 'command='], { encoding: 'utf8' });
662
+ const p = spawnSync('ps', ['-p', String(pid), '-o', 'command='], { encoding: 'utf8', timeout: 3000, killSignal: 'SIGKILL' });
667
663
  imagePath = ((p && p.stdout) || '').trim().split(/\s+/)[0] || '';
668
664
  } catch (_) {}
669
665
  out.push({ pid, path: imagePath });
package/bin/plugkit.js CHANGED
@@ -7,6 +7,30 @@ const { bootstrap, resolveCachedBinary, resolveCachedRtk, obsEvent, killStaleDae
7
7
 
8
8
  const dir = __dirname;
9
9
 
10
+ function readPinnedVersion() {
11
+ try { return fs.readFileSync(path.join(dir, 'plugkit.version'), 'utf8').trim(); } catch (_) { return null; }
12
+ }
13
+
14
+ function probeCachedVersion(binPath) {
15
+ try {
16
+ const r = spawnSync(binPath, ['--version'], { timeout: 3000, encoding: 'utf8', windowsHide: true });
17
+ if (r.error) return null;
18
+ const text = `${r.stdout || ''} ${r.stderr || ''}`.trim();
19
+ const m = text.match(/(\d+\.\d+\.\d+)/);
20
+ return m ? m[1] : null;
21
+ } catch (_) { return null; }
22
+ }
23
+
24
+ async function resolveBinaryWithPinCheck() {
25
+ const cached = resolveCachedBinary({ wrapperDir: dir });
26
+ if (!cached) return null;
27
+ const pin = readPinnedVersion();
28
+ if (!pin) return cached;
29
+ const got = probeCachedVersion(cached);
30
+ if (got && got === pin) return cached;
31
+ try { return await bootstrap({ wrapperDir: dir, silent: true }); } catch (_) { return cached; }
32
+ }
33
+
10
34
  function envWithRtkOnPath() {
11
35
  const rtkPath = resolveCachedRtk({ wrapperDir: dir });
12
36
  if (!rtkPath) return process.env;
@@ -49,7 +73,7 @@ async function main() {
49
73
  // below — fall through to the spawn path so the actual handler runs.
50
74
  if (!bin) process.exit(0);
51
75
  } else if (isHook) {
52
- bin = resolveCachedBinary({ wrapperDir: dir }) || legacyFallback();
76
+ bin = (await resolveBinaryWithPinCheck()) || legacyFallback();
53
77
  if (!bin) {
54
78
  process.stderr.write(`[plugkit] hook ${hookSubcmd} skipped: binary not yet installed. Bootstrap will run on session-start.\n`);
55
79
  obsEvent('plugkit_wrapper', 'hook_skip_uncached', { argv: args.slice(0, 4), dur_ms: Date.now() - startedAt });
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.967",
3
+ "version": "2.0.968",
4
4
  "description": "State machine agent with hooks, 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-codex",
3
- "version": "2.0.967",
3
+ "version": "2.0.968",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.967",
3
+ "version": "2.0.968",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": {
6
6
  "name": "AnEntrypoint",