gm-plugkit 2.0.1074 → 2.0.1076
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/bootstrap.js +55 -257
- package/package.json +1 -1
package/bootstrap.js
CHANGED
|
@@ -51,18 +51,6 @@ function clearBootstrapError() {
|
|
|
51
51
|
} catch (_) {}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function platformKey() {
|
|
55
|
-
const p = os.platform();
|
|
56
|
-
const a = os.arch();
|
|
57
|
-
if (p === 'win32') return a === 'arm64' ? 'win32-arm64' : 'win32-x64';
|
|
58
|
-
if (p === 'darwin') return a === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
|
|
59
|
-
return (a === 'arm64' || a === 'aarch64') ? 'linux-arm64' : 'linux-x64';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function binaryName() {
|
|
63
|
-
const key = platformKey();
|
|
64
|
-
return key.startsWith('win32') ? `plugkit-${key}.exe` : `plugkit-${key}`;
|
|
65
|
-
}
|
|
66
54
|
|
|
67
55
|
function cacheRoot() {
|
|
68
56
|
const home = os.homedir();
|
|
@@ -223,74 +211,13 @@ async function extractNpmPackageWithRetry(destPath, version) {
|
|
|
223
211
|
throw lastErr;
|
|
224
212
|
}
|
|
225
213
|
|
|
226
|
-
function killHoldersOfPath(targetPath) {
|
|
227
|
-
if (process.platform !== 'win32') return 0;
|
|
228
|
-
try {
|
|
229
|
-
const norm = path.resolve(targetPath).replace(/\//g, '\\');
|
|
230
|
-
const r = spawnSync('wmic', ['process', 'where', `ExecutablePath='${norm.replace(/\\/g, '\\\\')}'`, 'get', 'ProcessId', '/format:value'], { encoding: 'utf8', windowsHide: true, timeout: 5000 });
|
|
231
|
-
if (r.status !== 0 || !r.stdout) return 0;
|
|
232
|
-
const pids = [];
|
|
233
|
-
for (const line of r.stdout.split(/\r?\n/)) {
|
|
234
|
-
const m = line.match(/ProcessId=(\d+)/);
|
|
235
|
-
if (m) {
|
|
236
|
-
const pid = parseInt(m[1], 10);
|
|
237
|
-
if (Number.isFinite(pid) && pid !== process.pid) pids.push(pid);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
for (const pid of pids) {
|
|
241
|
-
try { spawnSync('taskkill', ['/F', '/PID', String(pid)], { windowsHide: true, timeout: 3000 }); } catch (_) {}
|
|
242
|
-
}
|
|
243
|
-
return pids.length;
|
|
244
|
-
} catch (_) { return 0; }
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function renameWithRetry(src, dst, attempts) {
|
|
248
|
-
for (let i = 0; i < attempts; i++) {
|
|
249
|
-
try { fs.renameSync(src, dst); return true; }
|
|
250
|
-
catch (err) {
|
|
251
|
-
if (err.code !== 'EEXIST' && err.code !== 'EPERM' && err.code !== 'EBUSY' && err.code !== 'EACCES') throw err;
|
|
252
|
-
if (i === Math.floor(attempts / 2)) killHoldersOfPath(dst);
|
|
253
|
-
try { spawnSync(process.execPath, ['-e', 'setTimeout(()=>{}, 200)'], { timeout: 400, killSignal: 'SIGKILL', stdio: 'ignore', windowsHide: true }); } catch (_) {}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
214
|
|
|
259
|
-
function
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
if (fs.existsSync(target)) {
|
|
267
|
-
let needsRefresh = true;
|
|
268
|
-
try {
|
|
269
|
-
const cur = sha256OfFileSync(target);
|
|
270
|
-
const src = sha256OfFileSync(finalPath);
|
|
271
|
-
if (cur === src) needsRefresh = false;
|
|
272
|
-
} catch (_) {}
|
|
273
|
-
if (!needsRefresh) {
|
|
274
|
-
try { fs.writeFileSync(path.join(dst, 'plugkit.version'), version); } catch (_) {}
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
try { killHoldersOfPath(target); } catch (_) {}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
fs.copyFileSync(finalPath, targetTmp);
|
|
281
|
-
if (!renameWithRetry(targetTmp, target, 8)) {
|
|
282
|
-
try { killHoldersOfPath(target); } catch (_) {}
|
|
283
|
-
try { fs.unlinkSync(target); } catch (_) {}
|
|
284
|
-
try { fs.renameSync(targetTmp, target); }
|
|
285
|
-
catch (_) {
|
|
286
|
-
try { fs.unlinkSync(targetTmp); } catch (_) {}
|
|
287
|
-
throw new Error(`gm-tools update blocked: cannot replace ${target}`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
if (process.platform !== 'win32') {
|
|
291
|
-
try { fs.chmodSync(target, 0o755); } catch (_) {}
|
|
292
|
-
}
|
|
293
|
-
fs.writeFileSync(path.join(dst, 'plugkit.version'), version);
|
|
215
|
+
function platformKey() {
|
|
216
|
+
const p = os.platform();
|
|
217
|
+
const a = os.arch();
|
|
218
|
+
if (p === 'win32') return a === 'arm64' ? 'win32-arm64' : 'win32-x64';
|
|
219
|
+
if (p === 'darwin') return a === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
|
|
220
|
+
return (a === 'arm64' || a === 'aarch64') ? 'linux-arm64' : 'linux-x64';
|
|
294
221
|
}
|
|
295
222
|
|
|
296
223
|
function rtkBinaryName() {
|
|
@@ -389,71 +316,6 @@ function killSpoolWatcherInCwd(reason) {
|
|
|
389
316
|
return null;
|
|
390
317
|
}
|
|
391
318
|
|
|
392
|
-
function listRunningPlugkitImagePaths() {
|
|
393
|
-
const out = [];
|
|
394
|
-
try {
|
|
395
|
-
if (os.platform() === 'win32') {
|
|
396
|
-
let parsed = null;
|
|
397
|
-
try {
|
|
398
|
-
const p = spawnSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', "Get-Process plugkit* -ErrorAction SilentlyContinue | Select-Object Id,Path | ConvertTo-Json -Compress"], { windowsHide: true, encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
399
|
-
const text = ((p && p.stdout) || '').trim();
|
|
400
|
-
if (text) {
|
|
401
|
-
const j = JSON.parse(text);
|
|
402
|
-
parsed = Array.isArray(j) ? j : [j];
|
|
403
|
-
}
|
|
404
|
-
} catch (_) {}
|
|
405
|
-
if (parsed) {
|
|
406
|
-
for (const item of parsed) {
|
|
407
|
-
if (!item) continue;
|
|
408
|
-
const pid = parseInt(item.Id, 10);
|
|
409
|
-
if (!Number.isFinite(pid)) continue;
|
|
410
|
-
out.push({ pid, path: (item.Path || '').trim() });
|
|
411
|
-
}
|
|
412
|
-
} else {
|
|
413
|
-
const r = spawnSync('tasklist', ['/FI', 'IMAGENAME eq plugkit*', '/FO', 'CSV', '/NH'], { windowsHide: true, encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
414
|
-
const text = (r && r.stdout) || '';
|
|
415
|
-
const seen = new Set();
|
|
416
|
-
for (const line of text.split(/\r?\n/)) {
|
|
417
|
-
const m = line.match(/^"([^"]+)","(\d+)"/);
|
|
418
|
-
if (!m) continue;
|
|
419
|
-
const pid = parseInt(m[2], 10);
|
|
420
|
-
if (!Number.isFinite(pid) || seen.has(pid)) continue;
|
|
421
|
-
seen.add(pid);
|
|
422
|
-
out.push({ pid, path: '' });
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
} else if (os.platform() === 'linux') {
|
|
426
|
-
let entries = [];
|
|
427
|
-
try { entries = fs.readdirSync('/proc'); } catch (_) {}
|
|
428
|
-
for (const e of entries) {
|
|
429
|
-
if (!/^\d+$/.test(e)) continue;
|
|
430
|
-
const pid = parseInt(e, 10);
|
|
431
|
-
let comm = '';
|
|
432
|
-
try { comm = fs.readFileSync(`/proc/${pid}/comm`, 'utf8').trim(); } catch (_) { continue; }
|
|
433
|
-
if (!/^plugkit/i.test(comm)) continue;
|
|
434
|
-
let imagePath = '';
|
|
435
|
-
try { imagePath = fs.readlinkSync(`/proc/${pid}/exe`); } catch (_) {}
|
|
436
|
-
out.push({ pid, path: imagePath });
|
|
437
|
-
}
|
|
438
|
-
} else {
|
|
439
|
-
const r = spawnSync('ps', ['-axo', 'pid=,comm='], { encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
440
|
-
const text = (r && r.stdout) || '';
|
|
441
|
-
for (const line of text.split(/\r?\n/)) {
|
|
442
|
-
const m = line.match(/^\s*(\d+)\s+(.+?)\s*$/);
|
|
443
|
-
if (!m) continue;
|
|
444
|
-
if (!/plugkit/i.test(m[2])) continue;
|
|
445
|
-
const pid = parseInt(m[1], 10);
|
|
446
|
-
let imagePath = '';
|
|
447
|
-
try {
|
|
448
|
-
const p = spawnSync('ps', ['-p', String(pid), '-o', 'command='], { encoding: 'utf8', timeout: 3000, killSignal: 'SIGKILL', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
449
|
-
imagePath = ((p && p.stdout) || '').trim().split(/\s+/)[0] || '';
|
|
450
|
-
} catch (_) {}
|
|
451
|
-
out.push({ pid, path: imagePath });
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
} catch (_) {}
|
|
455
|
-
return out;
|
|
456
|
-
}
|
|
457
319
|
|
|
458
320
|
function isLockStale(lockPath) {
|
|
459
321
|
try {
|
|
@@ -486,25 +348,9 @@ function pruneOldVersions(root, keepVersion, keepRtkVersion) {
|
|
|
486
348
|
} catch (_) {}
|
|
487
349
|
}
|
|
488
350
|
|
|
489
|
-
function proactiveKillForNewInstall(installedVersion
|
|
351
|
+
function proactiveKillForNewInstall(installedVersion) {
|
|
490
352
|
try {
|
|
491
353
|
const reason = `install:v${installedVersion}`;
|
|
492
|
-
const target = finalPath ? path.resolve(finalPath).toLowerCase() : null;
|
|
493
|
-
const cacheRootNorm = (() => {
|
|
494
|
-
try { return path.resolve(cacheRoot()).toLowerCase(); } catch (_) { return null; }
|
|
495
|
-
})();
|
|
496
|
-
const procs = listRunningPlugkitImagePaths();
|
|
497
|
-
for (const { pid, path: imagePath } of procs) {
|
|
498
|
-
if (!Number.isFinite(pid) || pid === process.pid) continue;
|
|
499
|
-
if (!imagePath) continue;
|
|
500
|
-
const norm = path.resolve(imagePath).toLowerCase();
|
|
501
|
-
if (target && norm === target) continue;
|
|
502
|
-
if (!cacheRootNorm || !norm.startsWith(cacheRootNorm + path.sep.toLowerCase())) continue;
|
|
503
|
-
if (killPid(pid)) {
|
|
504
|
-
try { process.stderr.write(`[bootstrap] killed stale daemon pid=${pid} path=${imagePath} (current install: v${installedVersion})\n`); } catch (_) {}
|
|
505
|
-
obsEvent('bootstrap', 'daemon.killed', { pid, oldPath: imagePath, installedVersion, mechanism: 'process-path' });
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
354
|
killRunningDaemons(reason);
|
|
509
355
|
killSpoolWatcherInCwd(reason);
|
|
510
356
|
writeDaemonVersion(installedVersion);
|
|
@@ -525,19 +371,6 @@ function killStaleDaemonIfVersionChanged() {
|
|
|
525
371
|
writeDaemonVersion(currentVersion);
|
|
526
372
|
}
|
|
527
373
|
|
|
528
|
-
function resolveCachedBinary(opts) {
|
|
529
|
-
opts = opts || {};
|
|
530
|
-
const version = opts.version || readVersionFile();
|
|
531
|
-
const root = (() => {
|
|
532
|
-
try { const r = cacheRoot(); ensureDir(r); return r; }
|
|
533
|
-
catch (_) { const r = fallbackCacheRoot(); ensureDir(r); return r; }
|
|
534
|
-
})();
|
|
535
|
-
const verDir = path.join(root, `v${version}`);
|
|
536
|
-
const finalPath = path.join(verDir, binaryName());
|
|
537
|
-
const okSentinel = path.join(verDir, '.ok');
|
|
538
|
-
if (fs.existsSync(finalPath) && fs.existsSync(okSentinel)) return finalPath;
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
374
|
|
|
542
375
|
function resolveCachedRtk() {
|
|
543
376
|
const version = readVersionFile();
|
|
@@ -638,8 +471,8 @@ async function bootstrap(opts) {
|
|
|
638
471
|
opts = opts || {};
|
|
639
472
|
const version = readVersionFile();
|
|
640
473
|
const shaManifest = readShaManifest();
|
|
641
|
-
const
|
|
642
|
-
const expectedSha = shaManifest ? shaManifest[
|
|
474
|
+
const wasmName = 'plugkit.wasm';
|
|
475
|
+
const expectedSha = shaManifest ? shaManifest[wasmName] : null;
|
|
643
476
|
|
|
644
477
|
let root = cacheRoot();
|
|
645
478
|
try { ensureDir(root); }
|
|
@@ -648,7 +481,7 @@ async function bootstrap(opts) {
|
|
|
648
481
|
const verDir = path.join(root, `v${version}`);
|
|
649
482
|
ensureDir(verDir);
|
|
650
483
|
|
|
651
|
-
const finalPath = path.join(verDir,
|
|
484
|
+
const finalPath = path.join(verDir, wasmName);
|
|
652
485
|
const okSentinel = path.join(verDir, '.ok');
|
|
653
486
|
const partialPath = `${finalPath}.partial`;
|
|
654
487
|
|
|
@@ -657,7 +490,7 @@ async function bootstrap(opts) {
|
|
|
657
490
|
const actualSha = sha256OfFileSync(finalPath);
|
|
658
491
|
if (actualSha === expectedSha) {
|
|
659
492
|
obsEvent('bootstrap', 'decision.hit', { reason: 'sha-match', version, path: finalPath });
|
|
660
|
-
|
|
493
|
+
copyWasmToGmTools(finalPath, version);
|
|
661
494
|
clearBootstrapError();
|
|
662
495
|
return finalPath;
|
|
663
496
|
}
|
|
@@ -665,22 +498,22 @@ async function bootstrap(opts) {
|
|
|
665
498
|
writeBootstrapError({
|
|
666
499
|
expected_version: version, cached_version: null,
|
|
667
500
|
error_phase: 'cache-hit-sha-mismatch',
|
|
668
|
-
error_message: `cached
|
|
501
|
+
error_message: `cached wasm at ${finalPath} sha=${actualSha} but manifest expects ${expectedSha}`,
|
|
669
502
|
});
|
|
670
503
|
try { fs.unlinkSync(finalPath); } catch (_) {}
|
|
671
504
|
try { fs.unlinkSync(okSentinel); } catch (_) {}
|
|
672
505
|
} else {
|
|
673
506
|
obsEvent('bootstrap', 'decision.hit', { reason: 'sentinel+no-sha-manifest', path: finalPath });
|
|
674
|
-
|
|
507
|
+
copyWasmToGmTools(finalPath, version);
|
|
675
508
|
clearBootstrapError();
|
|
676
509
|
return finalPath;
|
|
677
510
|
}
|
|
678
511
|
}
|
|
679
512
|
|
|
680
|
-
if (healIfShaMatches(finalPath, expectedSha, okSentinel, partialPath, 'plugkit')) {
|
|
513
|
+
if (healIfShaMatches(finalPath, expectedSha, okSentinel, partialPath, 'plugkit-wasm')) {
|
|
681
514
|
obsEvent('bootstrap', 'decision.heal', { reason: 'sha-match', path: finalPath });
|
|
682
515
|
spawnDetachedRtkFetch();
|
|
683
|
-
|
|
516
|
+
copyWasmToGmTools(finalPath, version);
|
|
684
517
|
clearBootstrapError();
|
|
685
518
|
return finalPath;
|
|
686
519
|
}
|
|
@@ -690,14 +523,14 @@ async function bootstrap(opts) {
|
|
|
690
523
|
try {
|
|
691
524
|
if (fs.existsSync(finalPath) && fs.existsSync(okSentinel)) {
|
|
692
525
|
obsEvent('bootstrap', 'decision.hit', { reason: 'lock-race-resolved', path: finalPath });
|
|
693
|
-
|
|
526
|
+
copyWasmToGmTools(finalPath, version);
|
|
694
527
|
clearBootstrapError();
|
|
695
528
|
return finalPath;
|
|
696
529
|
}
|
|
697
|
-
if (healIfShaMatches(finalPath, expectedSha, okSentinel, partialPath, 'plugkit')) {
|
|
530
|
+
if (healIfShaMatches(finalPath, expectedSha, okSentinel, partialPath, 'plugkit-wasm')) {
|
|
698
531
|
obsEvent('bootstrap', 'decision.heal', { reason: 'sha-match-under-lock', path: finalPath });
|
|
699
532
|
spawnDetachedRtkFetch();
|
|
700
|
-
|
|
533
|
+
copyWasmToGmTools(finalPath, version);
|
|
701
534
|
clearBootstrapError();
|
|
702
535
|
return finalPath;
|
|
703
536
|
}
|
|
@@ -729,9 +562,9 @@ async function bootstrap(opts) {
|
|
|
729
562
|
writeBootstrapError({
|
|
730
563
|
expected_version: version, cached_version: null,
|
|
731
564
|
error_phase: 'sha256-mismatch',
|
|
732
|
-
error_message: `sha256 mismatch for ${
|
|
565
|
+
error_message: `sha256 mismatch for ${wasmName}: expected ${expectedSha}, got ${got}`,
|
|
733
566
|
});
|
|
734
|
-
throw new Error(`sha256 mismatch for ${
|
|
567
|
+
throw new Error(`sha256 mismatch for ${wasmName}: expected ${expectedSha}, got ${got}`);
|
|
735
568
|
}
|
|
736
569
|
log('sha256 verified');
|
|
737
570
|
} else {
|
|
@@ -746,17 +579,13 @@ async function bootstrap(opts) {
|
|
|
746
579
|
} else throw err;
|
|
747
580
|
}
|
|
748
581
|
|
|
749
|
-
if (os.platform() !== 'win32') {
|
|
750
|
-
try { fs.chmodSync(finalPath, 0o755); } catch (_) {}
|
|
751
|
-
}
|
|
752
|
-
|
|
753
582
|
fs.writeFileSync(okSentinel, new Date().toISOString());
|
|
754
583
|
log(`decision: fetch reason: install-complete (${finalPath})`);
|
|
755
|
-
obsEvent('bootstrap', 'install.done', { path: finalPath, version, kind: 'plugkit' });
|
|
756
|
-
proactiveKillForNewInstall(version
|
|
584
|
+
obsEvent('bootstrap', 'install.done', { path: finalPath, version, kind: 'plugkit-wasm' });
|
|
585
|
+
proactiveKillForNewInstall(version);
|
|
757
586
|
pruneOldVersions(root, version, readRtkVersion());
|
|
758
587
|
spawnDetachedRtkFetch();
|
|
759
|
-
|
|
588
|
+
copyWasmToGmTools(finalPath, version);
|
|
760
589
|
clearBootstrapError();
|
|
761
590
|
return finalPath;
|
|
762
591
|
} finally {
|
|
@@ -764,61 +593,51 @@ async function bootstrap(opts) {
|
|
|
764
593
|
}
|
|
765
594
|
}
|
|
766
595
|
|
|
767
|
-
function
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
function isReady() {
|
|
774
|
-
const bin = getBinaryPath();
|
|
775
|
-
if (!fs.existsSync(bin)) return false;
|
|
776
|
-
try {
|
|
777
|
-
const r = spawnSync(bin, ['--version'], { timeout: 3000, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
|
|
778
|
-
return r.status === 0;
|
|
779
|
-
} catch (_) { return false; }
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
function startSpoolDaemon() {
|
|
783
|
-
const bin = getBinaryPath();
|
|
784
|
-
if (!fs.existsSync(bin)) return { ok: false, error: 'binary not found' };
|
|
596
|
+
function copyWasmToGmTools(wasmPath, version) {
|
|
597
|
+
const dst = gmToolsDir();
|
|
598
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
599
|
+
const target = path.join(dst, 'plugkit.wasm');
|
|
785
600
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
601
|
+
if (fs.existsSync(target)) {
|
|
602
|
+
let needsRefresh = true;
|
|
603
|
+
try {
|
|
604
|
+
const cur = sha256OfFileSync(target);
|
|
605
|
+
const src = sha256OfFileSync(wasmPath);
|
|
606
|
+
if (cur === src) needsRefresh = false;
|
|
607
|
+
} catch (_) {}
|
|
608
|
+
if (!needsRefresh) {
|
|
609
|
+
try { fs.writeFileSync(path.join(dst, 'plugkit.version'), version); } catch (_) {}
|
|
610
|
+
return;
|
|
791
611
|
}
|
|
792
|
-
try { fs.unlinkSync(pidFile); } catch (_) {}
|
|
793
612
|
}
|
|
794
613
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
windowsHide: true,
|
|
799
|
-
});
|
|
800
|
-
child.unref();
|
|
614
|
+
fs.copyFileSync(wasmPath, target);
|
|
615
|
+
fs.writeFileSync(path.join(dst, 'plugkit.version'), version);
|
|
616
|
+
}
|
|
801
617
|
|
|
802
|
-
|
|
803
|
-
|
|
618
|
+
function getWasmPath() {
|
|
619
|
+
const home = process.env.USERPROFILE || process.env.HOME || os.homedir();
|
|
620
|
+
return path.join(home, '.claude', 'gm-tools', 'plugkit.wasm');
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
function isReady() {
|
|
624
|
+
const wasm = getWasmPath();
|
|
625
|
+
return fs.existsSync(wasm);
|
|
804
626
|
}
|
|
805
627
|
|
|
806
628
|
async function ensureReady() {
|
|
807
629
|
if (isReady()) {
|
|
808
|
-
return { ok: true,
|
|
630
|
+
return { ok: true, wasmPath: getWasmPath(), status: 'already-ready' };
|
|
809
631
|
}
|
|
810
|
-
const
|
|
811
|
-
return { ok: true,
|
|
632
|
+
const wasmPath = await bootstrap();
|
|
633
|
+
return { ok: true, wasmPath, status: 'bootstrapped' };
|
|
812
634
|
}
|
|
813
635
|
|
|
814
636
|
module.exports = {
|
|
815
637
|
bootstrap,
|
|
816
638
|
ensureReady,
|
|
817
|
-
|
|
818
|
-
getBinaryPath,
|
|
639
|
+
getWasmPath,
|
|
819
640
|
isReady,
|
|
820
|
-
platformKey,
|
|
821
|
-
binaryName,
|
|
822
641
|
rtkBinaryName,
|
|
823
642
|
cacheRoot,
|
|
824
643
|
obsEvent,
|
|
@@ -826,7 +645,6 @@ module.exports = {
|
|
|
826
645
|
killStaleDaemonIfVersionChanged,
|
|
827
646
|
killSpoolWatcherInCwd,
|
|
828
647
|
proactiveKillForNewInstall,
|
|
829
|
-
resolveCachedBinary,
|
|
830
648
|
resolveCachedRtk,
|
|
831
649
|
bootstrapRtk,
|
|
832
650
|
readDaemonVersion,
|
|
@@ -847,38 +665,18 @@ if (require.main === module) {
|
|
|
847
665
|
ensureDir(verDir);
|
|
848
666
|
await bootstrapRtk(verDir, version, true, root);
|
|
849
667
|
process.exit(0);
|
|
850
|
-
} else if (args.includes('--daemon')) {
|
|
851
|
-
const result = await ensureReady();
|
|
852
|
-
if (!result.ok) {
|
|
853
|
-
console.error('Bootstrap failed:', result.error);
|
|
854
|
-
process.exit(1);
|
|
855
|
-
}
|
|
856
|
-
const daemon = startSpoolDaemon();
|
|
857
|
-
console.log(JSON.stringify({ bootstrap: result, daemon }));
|
|
858
|
-
process.exit(0);
|
|
859
|
-
} else if (args.includes('--binary')) {
|
|
860
|
-
const result = await ensureReady();
|
|
861
|
-
if (result.ok) {
|
|
862
|
-
console.log(result.binaryPath);
|
|
863
|
-
process.exit(0);
|
|
864
|
-
} else {
|
|
865
|
-
console.error('Bootstrap failed:', result.error);
|
|
866
|
-
process.exit(1);
|
|
867
|
-
}
|
|
868
668
|
} else if (args.includes('--status')) {
|
|
869
669
|
console.log(JSON.stringify({
|
|
870
670
|
ready: isReady(),
|
|
871
|
-
|
|
872
|
-
platform: platformKey(),
|
|
671
|
+
wasmPath: getWasmPath(),
|
|
873
672
|
daemonVersion: readDaemonVersion(),
|
|
874
673
|
cachedRtk: resolveCachedRtk(),
|
|
875
674
|
}));
|
|
876
675
|
process.exit(0);
|
|
877
676
|
} else {
|
|
878
677
|
const result = await ensureReady();
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
process.exit(result.ok && daemon.ok ? 0 : 1);
|
|
678
|
+
console.log(JSON.stringify({ bootstrap: result }));
|
|
679
|
+
process.exit(result.ok ? 0 : 1);
|
|
882
680
|
}
|
|
883
681
|
} catch (err) {
|
|
884
682
|
obsEvent('bootstrap', 'fatal', { err: String(err.message || err) });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1076",
|
|
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": {
|