gm-plugkit 2.0.1295 → 2.0.1296

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 CHANGED
@@ -45,7 +45,7 @@ function log(msg) {
45
45
  function obsEvent(subsystem, event, fields) {
46
46
  if (process.env.GM_LOG_DISABLE) return;
47
47
  try {
48
- const root = process.env.GM_LOG_DIR || path.join(os.homedir(), '.claude', 'gm-log');
48
+ const root = process.env.GM_LOG_DIR || path.join(os.homedir(), '.gm-log');
49
49
  const day = new Date().toISOString().slice(0, 10);
50
50
  const dir = path.join(root, day);
51
51
  fs.mkdirSync(dir, { recursive: true });
@@ -93,7 +93,11 @@ function fallbackCacheRoot() {
93
93
 
94
94
  function gmToolsDir() {
95
95
  const home = process.env.USERPROFILE || process.env.HOME || os.homedir();
96
- return path.join(home, '.claude', 'gm-tools');
96
+ const primary = path.join(home, '.gm-tools');
97
+ const fallback = path.join(home, '.claude', 'gm-tools');
98
+ if (fs.existsSync(primary)) return primary;
99
+ if (fs.existsSync(fallback)) return fallback;
100
+ return primary;
97
101
  }
98
102
 
99
103
  function readVersionFile() {
@@ -623,7 +627,11 @@ function copyWasmToGmTools(wasmPath, version) {
623
627
 
624
628
  function getWasmPath() {
625
629
  const home = process.env.USERPROFILE || process.env.HOME || os.homedir();
626
- return path.join(home, '.claude', 'gm-tools', 'plugkit.wasm');
630
+ const primary = path.join(home, '.gm-tools', 'plugkit.wasm');
631
+ const fallback = path.join(home, '.claude', 'gm-tools', 'plugkit.wasm');
632
+ if (fs.existsSync(primary)) return primary;
633
+ if (fs.existsSync(fallback)) return fallback;
634
+ return primary;
627
635
  }
628
636
 
629
637
  function isReady() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1295",
3
+ "version": "2.0.1296",
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": {
@@ -18,10 +18,18 @@ function spawn(cmd, args, opts) {
18
18
  const __filename = fileURLToPath(import.meta.url);
19
19
  const __dirname = path.dirname(__filename);
20
20
 
21
- const KV_DIR = path.join(os.homedir(), '.claude', 'gm-tools', 'kv');
21
+ function resolveGmToolsRoot() {
22
+ const primary = path.join(os.homedir(), '.gm-tools');
23
+ const fallback = path.join(os.homedir(), '.claude', 'gm-tools');
24
+ if (fs.existsSync(primary)) return primary;
25
+ if (fs.existsSync(fallback)) return fallback;
26
+ return primary;
27
+ }
28
+ const GM_TOOLS_ROOT = resolveGmToolsRoot();
29
+ const KV_DIR = path.join(GM_TOOLS_ROOT, 'kv');
22
30
  fs.mkdirSync(KV_DIR, { recursive: true });
23
31
 
24
- const GM_LOG_ROOT = process.env.GM_LOG_DIR || path.join(os.homedir(), '.claude', 'gm-log');
32
+ const GM_LOG_ROOT = process.env.GM_LOG_DIR || path.join(os.homedir(), '.gm-log');
25
33
  const ORCHESTRATOR_VERBS = new Set(['instruction', 'transition', 'phase-status', 'prd-add', 'prd-resolve', 'prd-list', 'mutable-add', 'mutable-resolve', 'mutable-list', 'memorize-fire', 'residual-scan', 'auto-recall']);
26
34
 
27
35
  const TURN_IDLE_MS = 30_000;
@@ -437,19 +445,25 @@ function browserStateDir(cwd) {
437
445
  function browserPortsFile(cwd) { return path.join(browserStateDir(cwd), 'browser-ports.json'); }
438
446
  function browserSessionsFile(cwd) { return path.join(browserStateDir(cwd), 'browser-sessions.json'); }
439
447
 
448
+ function atomicWriteJson(filePath, obj) {
449
+ const tmp = filePath + '.tmp.' + process.pid + '.' + Date.now() + '.' + Math.random().toString(36).slice(2, 8);
450
+ fs.writeFileSync(tmp, JSON.stringify(obj, null, 2));
451
+ fs.renameSync(tmp, filePath);
452
+ }
453
+
440
454
  function migrateLegacyBrowserState(cwd) {
441
455
  const dst1 = browserPortsFile(cwd);
442
456
  const dst2 = browserSessionsFile(cwd);
443
457
  try {
444
458
  if (!fs.existsSync(dst1) && fs.existsSync(LEGACY_BROWSER_PORTS_FILE)) {
445
459
  const legacy = JSON.parse(fs.readFileSync(LEGACY_BROWSER_PORTS_FILE, 'utf-8'));
446
- if (legacy && typeof legacy === 'object') fs.writeFileSync(dst1, JSON.stringify(legacy, null, 2));
460
+ if (legacy && typeof legacy === 'object') atomicWriteJson(dst1, legacy);
447
461
  }
448
462
  } catch (_) {}
449
463
  try {
450
464
  if (!fs.existsSync(dst2) && fs.existsSync(LEGACY_BROWSER_SESSIONS_FILE)) {
451
465
  const legacy = JSON.parse(fs.readFileSync(LEGACY_BROWSER_SESSIONS_FILE, 'utf-8'));
452
- if (legacy && typeof legacy === 'object') fs.writeFileSync(dst2, JSON.stringify(legacy, null, 2));
466
+ if (legacy && typeof legacy === 'object') atomicWriteJson(dst2, legacy);
453
467
  }
454
468
  } catch (_) {}
455
469
  }
@@ -458,7 +472,7 @@ function readJsonFile(fp, fallback) {
458
472
  try { return JSON.parse(fs.readFileSync(fp, 'utf-8')); } catch (_) { return fallback; }
459
473
  }
460
474
  function writeJsonFile(fp, value) {
461
- try { fs.writeFileSync(fp, JSON.stringify(value, null, 2)); } catch (_) {}
475
+ try { atomicWriteJson(fp, value); } catch (_) {}
462
476
  }
463
477
 
464
478
  const BROWSER_RUNNER_BIN = process.env.GM_BROWSER_RUNNER_BIN || 'playwriter';
@@ -1538,7 +1552,7 @@ function makeHostFunctions(instanceRef) {
1538
1552
 
1539
1553
  function resolveVersion(instance) {
1540
1554
  try {
1541
- return fs.readFileSync(path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit.version'), 'utf8').trim();
1555
+ return fs.readFileSync(path.join(GM_TOOLS_ROOT, 'plugkit.version'), 'utf8').trim();
1542
1556
  } catch (_) {}
1543
1557
  try {
1544
1558
  const fn = instance && instance.exports && instance.exports.plugkit_version;
@@ -1554,7 +1568,7 @@ function resolveVersion(instance) {
1554
1568
  }
1555
1569
 
1556
1570
  function readFileVersionOnly() {
1557
- try { return fs.readFileSync(path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit.version'), 'utf8').trim(); } catch (_) { return null; }
1571
+ try { return fs.readFileSync(path.join(GM_TOOLS_ROOT, 'plugkit.version'), 'utf8').trim(); } catch (_) { return null; }
1558
1572
  }
1559
1573
 
1560
1574
  function readInstanceVersion(instance) {
@@ -1580,7 +1594,7 @@ async function runSpoolWatcher(instance, spoolDir) {
1580
1594
  let _ownWrapperSha12 = '';
1581
1595
  try {
1582
1596
  const _crypto = require('crypto');
1583
- const _wp = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
1597
+ const _wp = path.join(GM_TOOLS_ROOT, 'plugkit-wasm-wrapper.js');
1584
1598
  _ownWrapperSha12 = _crypto.createHash('sha256').update(fs.readFileSync(_wp)).digest('hex').slice(0, 12);
1585
1599
  } catch (_) {}
1586
1600
  function lockBody() { return `${process.pid}|${Date.now()}|${_ownWrapperSha12}`; }
@@ -1724,7 +1738,7 @@ async function runSpoolWatcher(instance, spoolDir) {
1724
1738
  }
1725
1739
  writeBootActive();
1726
1740
 
1727
- const PEER_REGISTRY_PATH = path.join(os.homedir(), '.claude', 'gm-tools', 'peer-registry.json');
1741
+ const PEER_REGISTRY_PATH = path.join(GM_TOOLS_ROOT, 'peer-registry.json');
1728
1742
  function registerSelfAsPeer() {
1729
1743
  try {
1730
1744
  let reg = {};
@@ -1860,7 +1874,7 @@ async function runSpoolWatcher(instance, spoolDir) {
1860
1874
  }
1861
1875
  }, 60_000);
1862
1876
 
1863
- const _wrapperPathInstalled = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
1877
+ const _wrapperPathInstalled = path.join(GM_TOOLS_ROOT, 'plugkit-wasm-wrapper.js');
1864
1878
  let _wrapperShaAtBoot = '';
1865
1879
  try {
1866
1880
  const _crypto = require('crypto');
@@ -1938,7 +1952,7 @@ async function runSpoolWatcher(instance, spoolDir) {
1938
1952
  process.on('exit', () => { try { clearBootActive(); } catch (_) {} releaseLock(); });
1939
1953
 
1940
1954
  try {
1941
- const wrapperDst = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit-wasm-wrapper.js');
1955
+ const wrapperDst = path.join(GM_TOOLS_ROOT, 'plugkit-wasm-wrapper.js');
1942
1956
  if (path.resolve(__filename) !== path.resolve(wrapperDst)) {
1943
1957
  let same = false;
1944
1958
  if (fs.existsSync(wrapperDst)) {
@@ -2236,7 +2250,7 @@ async function runSpoolWatcher(instance, spoolDir) {
2236
2250
  installed,
2237
2251
  latest,
2238
2252
  checked_at_ms: Date.now(),
2239
- instruction: 'plugkit is out of date. To update, close the running watcher and re-bootstrap with the @latest flag, e.g. node ~/.claude/gm-tools/plugkit-wasm-wrapper.js spool & after running bootstrap with {latest: true}.',
2253
+ instruction: 'plugkit is out of date. To update, close the running watcher and re-bootstrap with the @latest flag, e.g. node ~/.gm-tools/plugkit-wasm-wrapper.js spool & after running bootstrap with {latest: true}.',
2240
2254
  update_url,
2241
2255
  }, null, 2));
2242
2256
  console.log(`[update] available: installed=${installed} latest=${latest} → wrote ${UPDATE_AVAILABLE_PATH}`);
@@ -2391,7 +2405,7 @@ async function selfHealFromGithubReleases() {
2391
2405
  const got = crypto.createHash('sha256').update(wasm).digest('hex');
2392
2406
  if (got !== sha) throw new Error(`sha mismatch: got ${got}, expected ${sha}`);
2393
2407
  }
2394
- const toolsDir = path.join(os.homedir(), '.claude', 'gm-tools');
2408
+ const toolsDir = GM_TOOLS_ROOT;
2395
2409
  fs.mkdirSync(toolsDir, { recursive: true });
2396
2410
  fs.writeFileSync(path.join(toolsDir, 'plugkit.wasm'), wasm);
2397
2411
  fs.writeFileSync(path.join(toolsDir, 'plugkit.version'), version);
@@ -2435,7 +2449,7 @@ async function tryInstantiate(wasmPath) {
2435
2449
 
2436
2450
  (async () => {
2437
2451
  try {
2438
- const wasmPath = path.join(os.homedir(), '.claude', 'gm-tools', 'plugkit.wasm');
2452
+ const wasmPath = path.join(GM_TOOLS_ROOT, 'plugkit.wasm');
2439
2453
 
2440
2454
  let instance, instanceRef;
2441
2455
  if (!fs.existsSync(wasmPath)) {