xtrm-tools 0.7.2 → 0.7.3

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.
@@ -43977,6 +43977,8 @@ function resolvePkgRoot() {
43977
43977
  return candidates[0];
43978
43978
  }
43979
43979
  var PI_AGENT_DIR = process.env.PI_AGENT_DIR || import_path3.default.join((0, import_node_os.homedir)(), ".pi", "agent");
43980
+ var PI_MCP_ADAPTER_OVERRIDE_DIR = import_path3.default.join(PI_AGENT_DIR, "extensions", "pi-mcp-adapter");
43981
+ var PI_MCP_ADAPTER_REQUIRED_ENTRY = "commands.js";
43980
43982
  var PROJECT_EXTENSIONS_ENTRY = "../.xtrm/extensions";
43981
43983
  var PROJECT_SKILLS_ENTRY = "../.xtrm/skills/active/pi";
43982
43984
  var MANAGED_EXTENSIONS = [
@@ -44138,21 +44140,111 @@ function renderPiRuntimePlan(plan) {
44138
44140
  console.log(kleur_default.yellow(" \u26A0 Missing required items.\n"));
44139
44141
  }
44140
44142
  }
44143
+ function mergePiSyncResults(base, incoming) {
44144
+ return {
44145
+ extensionsAdded: [...base.extensionsAdded, ...incoming.extensionsAdded],
44146
+ extensionsUpdated: [...base.extensionsUpdated, ...incoming.extensionsUpdated],
44147
+ extensionsRemoved: [...base.extensionsRemoved, ...incoming.extensionsRemoved],
44148
+ packagesInstalled: [...base.packagesInstalled, ...incoming.packagesInstalled],
44149
+ failed: [...base.failed, ...incoming.failed]
44150
+ };
44151
+ }
44141
44152
  async function ensureCorePackageSymlink(coreSrcDir, projectRoot, dryRun, log) {
44142
- if (!await import_fs_extra7.default.pathExists(coreSrcDir)) return;
44153
+ if (!await import_fs_extra7.default.pathExists(coreSrcDir)) return "missing-source";
44143
44154
  const extensionsDir = import_path3.default.join(projectRoot, ".xtrm", "extensions");
44144
44155
  const nodeModulesDir = import_path3.default.join(extensionsDir, "node_modules", "@xtrm");
44145
44156
  const symlinkPath = import_path3.default.join(nodeModulesDir, "pi-core");
44157
+ const expectedTarget = import_path3.default.resolve(coreSrcDir);
44146
44158
  const existing = await import_fs_extra7.default.lstat(symlinkPath).catch(() => null);
44147
- if (existing) return;
44159
+ if (existing) {
44160
+ if (existing.isSymbolicLink()) {
44161
+ const currentLinkTarget = await import_fs_extra7.default.readlink(symlinkPath);
44162
+ const resolvedTarget = import_path3.default.resolve(import_path3.default.dirname(symlinkPath), currentLinkTarget);
44163
+ if (resolvedTarget === expectedTarget) {
44164
+ return "ok";
44165
+ }
44166
+ }
44167
+ if (dryRun) {
44168
+ log?.(kleur_default.dim("[DRY RUN] would repair @xtrm/pi-core symlink target"));
44169
+ return "would-repair";
44170
+ }
44171
+ await import_fs_extra7.default.remove(symlinkPath);
44172
+ await import_fs_extra7.default.ensureDir(nodeModulesDir);
44173
+ const relTarget2 = import_path3.default.relative(nodeModulesDir, coreSrcDir);
44174
+ await import_fs_extra7.default.symlink(relTarget2, symlinkPath);
44175
+ log?.(kleur_default.dim("Repaired @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core"));
44176
+ return "repaired";
44177
+ }
44148
44178
  if (dryRun) {
44149
- log?.(kleur_default.dim(`[DRY RUN] would create @xtrm/pi-core symlink`));
44150
- return;
44179
+ log?.(kleur_default.dim("[DRY RUN] would create @xtrm/pi-core symlink"));
44180
+ return "would-create";
44151
44181
  }
44152
44182
  await import_fs_extra7.default.ensureDir(nodeModulesDir);
44153
44183
  const relTarget = import_path3.default.relative(nodeModulesDir, coreSrcDir);
44154
44184
  await import_fs_extra7.default.symlink(relTarget, symlinkPath);
44155
- log?.(kleur_default.dim(`Created @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core`));
44185
+ log?.(kleur_default.dim("Created @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core"));
44186
+ return "created";
44187
+ }
44188
+ async function remediateStalePiMcpAdapterOverride(dryRun, log) {
44189
+ const stat = await import_fs_extra7.default.lstat(PI_MCP_ADAPTER_OVERRIDE_DIR).catch(() => null);
44190
+ if (!stat) {
44191
+ return {
44192
+ path: PI_MCP_ADAPTER_OVERRIDE_DIR,
44193
+ found: false,
44194
+ stale: false,
44195
+ remediated: false
44196
+ };
44197
+ }
44198
+ if (stat.isSymbolicLink()) {
44199
+ return {
44200
+ path: PI_MCP_ADAPTER_OVERRIDE_DIR,
44201
+ found: true,
44202
+ stale: false,
44203
+ remediated: false
44204
+ };
44205
+ }
44206
+ const hasRequiredEntry = await import_fs_extra7.default.pathExists(import_path3.default.join(PI_MCP_ADAPTER_OVERRIDE_DIR, PI_MCP_ADAPTER_REQUIRED_ENTRY));
44207
+ if (stat.isDirectory() && hasRequiredEntry) {
44208
+ return {
44209
+ path: PI_MCP_ADAPTER_OVERRIDE_DIR,
44210
+ found: true,
44211
+ stale: false,
44212
+ remediated: false
44213
+ };
44214
+ }
44215
+ const reason = stat.isDirectory() ? `missing ${PI_MCP_ADAPTER_REQUIRED_ENTRY}` : "not a directory/symlink";
44216
+ if (dryRun) {
44217
+ log?.(kleur_default.dim(`[DRY RUN] would remove stale pi-mcp-adapter override (${reason})`));
44218
+ return {
44219
+ path: PI_MCP_ADAPTER_OVERRIDE_DIR,
44220
+ found: true,
44221
+ stale: true,
44222
+ remediated: false,
44223
+ reason
44224
+ };
44225
+ }
44226
+ await import_fs_extra7.default.remove(PI_MCP_ADAPTER_OVERRIDE_DIR);
44227
+ log?.(kleur_default.dim(`Removed stale pi-mcp-adapter override (${reason})`));
44228
+ return {
44229
+ path: PI_MCP_ADAPTER_OVERRIDE_DIR,
44230
+ found: true,
44231
+ stale: true,
44232
+ remediated: true,
44233
+ reason
44234
+ };
44235
+ }
44236
+ async function runPiLaunchPreflight(projectRoot, dryRun, log) {
44237
+ const staleOverride = await remediateStalePiMcpAdapterOverride(dryRun, log);
44238
+ const coreSymlinkStatus = await ensureCorePackageSymlink(
44239
+ import_path3.default.join(projectRoot, ".xtrm", "extensions", "core"),
44240
+ projectRoot,
44241
+ dryRun,
44242
+ log
44243
+ );
44244
+ return {
44245
+ coreSymlinkStatus,
44246
+ staleOverride
44247
+ };
44156
44248
  }
44157
44249
  function isXtrmExtensionsSetting(entry) {
44158
44250
  const normalizedEntry = entry.replaceAll("\\", "/").replace(/\/$/, "");
@@ -44312,20 +44404,26 @@ async function runPiRuntimeSync(opts = {}) {
44312
44404
  packagesInstalled: [],
44313
44405
  failed: []
44314
44406
  };
44407
+ const result = { ...emptyResult };
44315
44408
  if (!await import_fs_extra7.default.pathExists(sourceDir)) {
44316
44409
  console.log(kleur_default.dim("\n Managed extensions: skipped (not bundled in npm package)\n"));
44317
- return emptyResult;
44410
+ return result;
44411
+ }
44412
+ const preflight = await runPiLaunchPreflight(resolvedProjectRoot, dryRun, log);
44413
+ if (preflight.staleOverride.remediated) {
44414
+ result.extensionsRemoved.push("pi-mcp-adapter");
44318
44415
  }
44319
44416
  if (isGlobal) {
44320
44417
  const targetDir = import_path3.default.join(PI_AGENT_DIR, "extensions");
44321
44418
  const plan = await inventoryPiRuntime(sourceDir, targetDir);
44322
44419
  renderPiRuntimePlan(plan);
44323
- if (plan.allPresent) return emptyResult;
44324
- return await executePiSync(plan, sourceDir, targetDir, {
44420
+ if (plan.allPresent) return result;
44421
+ const synced = await executePiSync(plan, sourceDir, targetDir, {
44325
44422
  dryRun,
44326
44423
  isGlobal: true,
44327
44424
  removeOrphaned: true
44328
44425
  });
44426
+ return mergePiSyncResults(result, synced);
44329
44427
  }
44330
44428
  const installedPkgIds = getInstalledPiPackages();
44331
44429
  const packageStatuses = [];
@@ -44346,7 +44444,6 @@ async function runPiRuntimeSync(opts = {}) {
44346
44444
  console.log(kleur_default.yellow(` Missing: ${names}`));
44347
44445
  }
44348
44446
  console.log(kleur_default.dim(" " + "-".repeat(50)));
44349
- const result = { ...emptyResult };
44350
44447
  const legacyCleanup = await cleanupLegacyProjectExtensionCopies(resolvedProjectRoot, dryRun, log);
44351
44448
  result.extensionsRemoved.push(...legacyCleanup.removed);
44352
44449
  result.failed.push(...legacyCleanup.failed);
@@ -44382,7 +44479,6 @@ async function runPiRuntimeSync(opts = {}) {
44382
44479
  }
44383
44480
  }
44384
44481
  await updatePiSettings(resolvedProjectRoot, dryRun, log);
44385
- await ensureCorePackageSymlink(import_path3.default.join(sourceDir, "core"), resolvedProjectRoot, dryRun, log);
44386
44482
  const requiredFailed = missingPackages.filter(
44387
44483
  (s) => s.pkg.required && result.failed.includes(s.pkg.id)
44388
44484
  );
@@ -44584,12 +44680,11 @@ async function launchWorktreeSession(opts) {
44584
44680
  } catch {
44585
44681
  }
44586
44682
  }
44587
- const coreExtDir = import_node_path5.default.join(worktreePath, ".xtrm", "extensions", "core");
44588
44683
  try {
44589
- await ensureCorePackageSymlink(coreExtDir, worktreePath, false);
44684
+ await runPiLaunchPreflight(worktreePath, false);
44590
44685
  } catch (error48) {
44591
44686
  const message = error48 instanceof Error ? error48.message : String(error48);
44592
- console.log(kleur_default.dim(` warning: could not ensure @xtrm/pi-core symlink (${message})`));
44687
+ console.log(kleur_default.dim(` warning: pi launch preflight failed (${message})`));
44593
44688
  }
44594
44689
  }
44595
44690
  if (runtime === "claude") {
@@ -45478,6 +45573,33 @@ function createPiCommand() {
45478
45573
  const bundleRoot = await findRepoRoot();
45479
45574
  const sourceDir = import_path7.default.join(bundleRoot, ".xtrm", "extensions");
45480
45575
  const globalTargetDir = import_path7.default.join(PI_AGENT_DIR4, "extensions");
45576
+ try {
45577
+ const staleOverride = await remediateStalePiMcpAdapterOverride(false);
45578
+ if (staleOverride.stale && staleOverride.remediated) {
45579
+ console.log(t.success(" \u2713 removed stale ~/.pi/agent/extensions/pi-mcp-adapter override"));
45580
+ } else if (staleOverride.stale) {
45581
+ console.log(kleur_default.yellow(" \u26A0 stale ~/.pi/agent/extensions/pi-mcp-adapter override detected"));
45582
+ allOk = false;
45583
+ } else {
45584
+ console.log(t.success(" \u2713 pi-mcp-adapter override check passed"));
45585
+ }
45586
+ } catch (error48) {
45587
+ console.log(kleur_default.yellow(` \u26A0 failed to remediate pi-mcp-adapter override: ${error48}`));
45588
+ allOk = false;
45589
+ }
45590
+ try {
45591
+ const coreStatus = await ensureCorePackageSymlink(import_path7.default.join(sourceDir, "core"), projectRoot, false);
45592
+ if (coreStatus === "repaired" || coreStatus === "created") {
45593
+ console.log(t.success(" \u2713 repaired .xtrm/extensions/node_modules/@xtrm/pi-core symlink"));
45594
+ } else if (coreStatus === "ok") {
45595
+ console.log(t.success(" \u2713 @xtrm/pi-core symlink is healthy"));
45596
+ } else if (coreStatus === "missing-source") {
45597
+ console.log(kleur_default.dim(" \u25CB @xtrm/pi-core source not bundled in this install"));
45598
+ }
45599
+ } catch (error48) {
45600
+ console.log(kleur_default.yellow(` \u26A0 failed to ensure @xtrm/pi-core symlink: ${error48}`));
45601
+ allOk = false;
45602
+ }
45481
45603
  if (!await import_fs_extra11.default.pathExists(sourceDir)) {
45482
45604
  console.log(kleur_default.dim(" \u25CB managed extensions not bundled in this install"));
45483
45605
  } else {
@@ -50554,6 +50676,14 @@ function createAttachCommand() {
50554
50676
  console.log(kleur_default.dim(` runtime: ${runtime} (resuming session)`));
50555
50677
  console.log(kleur_default.dim(` path: ${target.path}
50556
50678
  `));
50679
+ if (runtime === "pi") {
50680
+ try {
50681
+ await runPiLaunchPreflight(target.path, false);
50682
+ } catch (error48) {
50683
+ const message = error48 instanceof Error ? error48.message : String(error48);
50684
+ console.log(kleur_default.dim(` warning: pi launch preflight failed (${message})`));
50685
+ }
50686
+ }
50557
50687
  const result = (0, import_node_child_process8.spawnSync)(runtime, resumeArgs, {
50558
50688
  cwd: target.path,
50559
50689
  stdio: "inherit"