gm-codex 2.0.963 → 2.0.964
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/.codex-plugin/plugin.json +1 -1
- package/bin/bootstrap.js +74 -11
- package/gm.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
package/bin/bootstrap.js
CHANGED
|
@@ -24,6 +24,27 @@ function log(msg) {
|
|
|
24
24
|
try { process.stderr.write(`[plugkit-bootstrap] ${msg}\n`); } catch (_) {}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function probeBinaryVersion(binPath) {
|
|
28
|
+
try {
|
|
29
|
+
const { spawnSync } = require('child_process');
|
|
30
|
+
const r = spawnSync(binPath, ['--version'], { timeout: 3000, encoding: 'utf8' });
|
|
31
|
+
if (r.error) return null;
|
|
32
|
+
const text = `${r.stdout || ''} ${r.stderr || ''}`.trim();
|
|
33
|
+
const m = text.match(/(\d+\.\d+\.\d+)/);
|
|
34
|
+
return m ? m[1] : null;
|
|
35
|
+
} catch (_) { return null; }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function writeBootstrapError(spec) {
|
|
39
|
+
try {
|
|
40
|
+
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
41
|
+
const spoolDir = path.join(projectDir, '.gm', 'exec-spool');
|
|
42
|
+
fs.mkdirSync(spoolDir, { recursive: true });
|
|
43
|
+
const out = path.join(spoolDir, '.bootstrap-error.json');
|
|
44
|
+
fs.writeFileSync(out, JSON.stringify({ ts: new Date().toISOString(), ...spec }, null, 2));
|
|
45
|
+
} catch (_) {}
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
function obsEvent(subsystem, event, fields) {
|
|
28
49
|
if (process.env.GM_LOG_DISABLE) return;
|
|
29
50
|
try {
|
|
@@ -326,19 +347,45 @@ async function bootstrap(opts) {
|
|
|
326
347
|
const partialPath = `${finalPath}.partial`;
|
|
327
348
|
|
|
328
349
|
if (fs.existsSync(finalPath) && fs.existsSync(okSentinel)) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
350
|
+
const actualVersion = probeBinaryVersion(finalPath);
|
|
351
|
+
if (actualVersion && actualVersion !== version) {
|
|
352
|
+
log(`cache version mismatch: dir=v${version} contains binary ${actualVersion} → re-fetching v${version}`);
|
|
353
|
+
writeBootstrapError({
|
|
354
|
+
expected_version: version,
|
|
355
|
+
cached_version: actualVersion,
|
|
356
|
+
error_phase: 'cache-hit-pin-mismatch',
|
|
357
|
+
error_message: `cached binary at ${finalPath} reports --version=${actualVersion} but cache dir pins v${version}`,
|
|
358
|
+
});
|
|
359
|
+
try { fs.unlinkSync(finalPath); } catch (_) {}
|
|
360
|
+
try { fs.unlinkSync(okSentinel); } catch (_) {}
|
|
361
|
+
} else {
|
|
362
|
+
if (!opts.silent) log(`cache hit: ${finalPath}${actualVersion ? ` (matches pin v${version})` : ''}`);
|
|
363
|
+
proactiveKillForNewInstall(version, finalPath);
|
|
364
|
+
pruneOldVersions(root, version, readRtkVersion(wrapperDir));
|
|
365
|
+
return finalPath;
|
|
366
|
+
}
|
|
333
367
|
}
|
|
334
368
|
|
|
335
369
|
if (healIfShaMatches(finalPath, expectedSha, okSentinel, partialPath, 'plugkit')) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
370
|
+
const actualVersion = probeBinaryVersion(finalPath);
|
|
371
|
+
if (actualVersion && actualVersion !== version) {
|
|
372
|
+
log(`cache heal version mismatch: dir=v${version} contains binary ${actualVersion} → re-fetching`);
|
|
373
|
+
writeBootstrapError({
|
|
374
|
+
expected_version: version,
|
|
375
|
+
cached_version: actualVersion,
|
|
376
|
+
error_phase: 'cache-heal-pin-mismatch',
|
|
377
|
+
error_message: `healed binary at ${finalPath} reports --version=${actualVersion} but cache dir pins v${version}`,
|
|
378
|
+
});
|
|
379
|
+
try { fs.unlinkSync(finalPath); } catch (_) {}
|
|
380
|
+
try { fs.unlinkSync(okSentinel); } catch (_) {}
|
|
381
|
+
} else {
|
|
382
|
+
if (!opts.silent) log(`cache heal (sha match): ${finalPath}${actualVersion ? ` (matches pin v${version})` : ''}`);
|
|
383
|
+
proactiveKillForNewInstall(version, finalPath);
|
|
384
|
+
pruneOldVersions(root, version, readRtkVersion(wrapperDir));
|
|
385
|
+
try { await bootstrapRtk(verDir, version, wrapperDir, opts.silent, root); }
|
|
386
|
+
catch (err) { log(`rtk fetch skipped: ${err.message}`); }
|
|
387
|
+
return finalPath;
|
|
388
|
+
}
|
|
342
389
|
}
|
|
343
390
|
|
|
344
391
|
const lockPath = path.join(verDir, '.lock');
|
|
@@ -368,12 +415,28 @@ async function bootstrap(opts) {
|
|
|
368
415
|
} catch (_) {}
|
|
369
416
|
}
|
|
370
417
|
const url = `https://github.com/${RELEASE_REPO}/releases/download/v${version}/${binName}`;
|
|
371
|
-
|
|
418
|
+
try {
|
|
419
|
+
await downloadWithRetry(url, partialPath);
|
|
420
|
+
} catch (fetchErr) {
|
|
421
|
+
writeBootstrapError({
|
|
422
|
+
expected_version: version,
|
|
423
|
+
cached_version: null,
|
|
424
|
+
error_phase: 'download',
|
|
425
|
+
error_message: fetchErr && fetchErr.message ? fetchErr.message : String(fetchErr),
|
|
426
|
+
});
|
|
427
|
+
throw fetchErr;
|
|
428
|
+
}
|
|
372
429
|
|
|
373
430
|
if (expectedSha) {
|
|
374
431
|
const got = await sha256OfFile(partialPath);
|
|
375
432
|
if (got !== expectedSha) {
|
|
376
433
|
try { fs.unlinkSync(partialPath); } catch (_) {}
|
|
434
|
+
writeBootstrapError({
|
|
435
|
+
expected_version: version,
|
|
436
|
+
cached_version: null,
|
|
437
|
+
error_phase: 'sha256-mismatch',
|
|
438
|
+
error_message: `sha256 mismatch for ${binName}: expected ${expectedSha}, got ${got}`,
|
|
439
|
+
});
|
|
377
440
|
throw new Error(`sha256 mismatch for ${binName}: expected ${expectedSha}, got ${got}`);
|
|
378
441
|
}
|
|
379
442
|
log('sha256 verified');
|
package/gm.json
CHANGED
package/package.json
CHANGED