@baton-dx/cli 0.1.1 → 0.1.2

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/dist/index.mjs CHANGED
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import { t as findSourceRoot } from "./context-detection-0m8_Fp0j.mjs";
2
+ import { r as __toESM } from "./chunk-BbwQpWto.mjs";
3
+ import { a as Ne, c as Ve, d as bt, f as je, g as runMain, h as defineCommand, i as Le, l as We, m as require_dist, o as R, p as Ct, r as Je, s as Re, t as findSourceRoot, u as Ze } from "./context-detection-mMNLg_4F.mjs";
4
+ import { A as readLock, B as getAdaptersForKeys, C as resolveProfileSupport, D as discoverProfilesInSourceRepo, E as placeFile, F as updateGitignore, G as loadProjectManifest, H as parseSource, I as getIdePlatformTargetDir, J as SourceParseError, K as KEBAB_CASE_REGEX, L as getRegisteredIdePlatforms, M as resolveVersion, N as cloneGitSource, O as findSourceManifest, P as collectProfileSupportPatterns, R as idePlatformRegistry, S as mergeContentParts, T as detectLegacyPaths, U as loadLockfile, V as parseFrontmatter, W as loadProfileManifest, X as getAgentPath, Y as getAgentConfig, Z as getAllAgentKeys, _ as mergeSkills, a as getDefaultGlobalSource, b as isLockedProfile, c as getGlobalSources, d as setGlobalIdePlatforms, f as require_lib, g as mergeRulesWithWarnings, h as mergeRules, i as addGlobalSource, j as writeLock, k as generateLock, l as removeGlobalSource, m as mergeMemoryWithWarnings, n as clearIdeCache, o as getGlobalAiTools, p as mergeMemory, q as FileNotFoundError, r as detectInstalledIdes, s as getGlobalIdePlatforms, t as computeIntersection, u as setGlobalAiTools, v as mergeSkillsWithWarnings, w as resolveProfileChain, x as sortProfilesByWeight, y as getProfileWeight, z as isKnownIdePlatform } from "./src-Dh0ZvHbV.mjs";
5
+ import { n as detectInstalledAgents, t as clearAgentCache } from "./agent-detection-C5gaTtah.mjs";
6
+ import { d as esm_default } from "./esm-BagM-kVd.mjs";
3
7
  import { access, mkdir, readFile, readdir, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
4
8
  import { dirname, join, resolve } from "node:path";
5
9
  import { fileURLToPath } from "node:url";
6
- import { defineCommand, runMain } from "citty";
7
- import { getAgentConfig, getAgentPath, getAllAgentKeys } from "@baton-dx/agent-paths";
8
- import { FileNotFoundError, KEBAB_CASE_REGEX, SourceParseError, addGlobalSource, clearAgentCache, clearIdeCache, cloneGitSource, collectProfileSupportPatterns, computeIntersection, detectInstalledAgents, detectInstalledIdes, detectLegacyPaths, discoverProfilesInSourceRepo, findSourceManifest, generateLock, getAdaptersForKeys, getDefaultGlobalSource, getGlobalAiTools, getGlobalIdePlatforms, getGlobalSources, getIdePlatformTargetDir, getProfileWeight, getRegisteredIdePlatforms, idePlatformRegistry, isKnownIdePlatform, isLockedProfile, loadLockfile, loadProfileManifest, loadProjectManifest, mergeContentParts, mergeMemory, mergeMemoryWithWarnings, mergeRules, mergeRulesWithWarnings, mergeSkills, mergeSkillsWithWarnings, parseFrontmatter, parseSource, placeFile, readLock, removeGlobalSource, resolveProfileChain, resolveProfileSupport, resolveVersion, setGlobalAiTools, setGlobalIdePlatforms, sortProfilesByWeight, updateGitignore, writeLock } from "@baton-dx/core";
9
- import * as p from "@clack/prompts";
10
10
  import { homedir } from "node:os";
11
- import { parse, stringify } from "yaml";
12
- import Handlebars from "handlebars";
13
- import simpleGit from "simple-git";
14
11
 
15
12
  //#region src/commands/ai-tools/list.ts
16
13
  const aiToolsListCommand = defineCommand({
@@ -31,7 +28,7 @@ const aiToolsListCommand = defineCommand({
31
28
  }
32
29
  },
33
30
  async run({ args }) {
34
- if (!args.json) p.intro("Baton - AI Tools");
31
+ if (!args.json) We("Baton - AI Tools");
35
32
  const savedTools = await getGlobalAiTools();
36
33
  const allAgentKeys = getAllAgentKeys();
37
34
  const keysToShow = args.all ? allAgentKeys : savedTools.length > 0 ? savedTools : allAgentKeys;
@@ -75,15 +72,15 @@ const aiToolsListCommand = defineCommand({
75
72
  return;
76
73
  }
77
74
  if (savedTools.length === 0) {
78
- p.log.warn("No AI tools saved in global config.");
79
- p.log.info("Run 'baton ai-tools scan' to detect and save your AI tools.");
75
+ R.warn("No AI tools saved in global config.");
76
+ R.info("Run 'baton ai-tools scan' to detect and save your AI tools.");
80
77
  console.log("");
81
- p.log.info(`All ${allAgentKeys.length} supported tools:`);
78
+ R.info(`All ${allAgentKeys.length} supported tools:`);
82
79
  for (const key of allAgentKeys) {
83
80
  const config = getAgentConfig(key);
84
81
  console.log(` \x1b[90m- ${config.name}\x1b[0m`);
85
82
  }
86
- p.outro("Run 'baton ai-tools scan' to get started.");
83
+ Le("Run 'baton ai-tools scan' to get started.");
87
84
  return;
88
85
  }
89
86
  console.log(`\nSaved AI tools (${savedTools.length}):\n`);
@@ -104,7 +101,7 @@ const aiToolsListCommand = defineCommand({
104
101
  }
105
102
  console.log("");
106
103
  }
107
- p.outro("Manage tools: 'baton ai-tools scan' (detect) | 'baton config set default-tools <tools>'");
104
+ Le("Manage tools: 'baton ai-tools scan' (detect) | 'baton config set default-tools <tools>'");
108
105
  }
109
106
  });
110
107
  /**
@@ -133,8 +130,8 @@ const aiToolsScanCommand = defineCommand({
133
130
  description: "Automatically save detected tools without confirmation"
134
131
  } },
135
132
  async run({ args }) {
136
- p.intro("Baton - AI Tool Scanner");
137
- const spinner = p.spinner();
133
+ We("Baton - AI Tool Scanner");
134
+ const spinner = bt();
138
135
  spinner.start("Scanning for AI tools...");
139
136
  clearAgentCache();
140
137
  const detectedAgents = await detectInstalledAgents();
@@ -152,19 +149,19 @@ const aiToolsScanCommand = defineCommand({
152
149
  else notInstalled.push(entry);
153
150
  }
154
151
  if (installed.length > 0) {
155
- p.log.success(`Found ${installed.length} AI tool${installed.length !== 1 ? "s" : ""}:`);
152
+ R.success(`Found ${installed.length} AI tool${installed.length !== 1 ? "s" : ""}:`);
156
153
  for (const agent of installed) {
157
154
  const badge = currentTools.includes(agent.key) ? " (saved)" : " (new)";
158
155
  console.log(` \x1b[32m✓\x1b[0m ${agent.name}${badge}`);
159
156
  }
160
157
  } else {
161
- p.log.warn("No AI tools detected on your system.");
162
- p.outro("Scan finished.");
158
+ R.warn("No AI tools detected on your system.");
159
+ Le("Scan finished.");
163
160
  return;
164
161
  }
165
162
  if (notInstalled.length > 0) {
166
163
  console.log("");
167
- p.log.info(`Not detected (${notInstalled.length}):`);
164
+ R.info(`Not detected (${notInstalled.length}):`);
168
165
  for (const agent of notInstalled) console.log(` \x1b[90m✗ ${agent.name}\x1b[0m`);
169
166
  }
170
167
  const detectedKeys = installed.map((a) => a.key);
@@ -172,22 +169,22 @@ const aiToolsScanCommand = defineCommand({
172
169
  console.log("");
173
170
  let shouldSave = args.yes;
174
171
  if (!shouldSave) {
175
- const confirm = await p.confirm({ message: "Save detected tools to global config (~/.baton/config.yaml)?" });
176
- if (p.isCancel(confirm)) {
177
- p.outro("Scan finished (not saved).");
172
+ const confirm = await Re({ message: "Save detected tools to global config (~/.baton/config.yaml)?" });
173
+ if (Ct(confirm)) {
174
+ Le("Scan finished (not saved).");
178
175
  return;
179
176
  }
180
177
  shouldSave = confirm;
181
178
  }
182
179
  if (shouldSave) {
183
180
  await setGlobalAiTools(detectedKeys);
184
- p.log.success("Tools saved to global config.");
181
+ R.success("Tools saved to global config.");
185
182
  }
186
183
  } else {
187
184
  console.log("");
188
- p.log.info("Global config is already up to date.");
185
+ R.info("Global config is already up to date.");
189
186
  }
190
- p.outro("Scan finished.");
187
+ Le("Scan finished.");
191
188
  }
192
189
  });
193
190
 
@@ -206,6 +203,7 @@ const aiToolsCommand = defineCommand({
206
203
 
207
204
  //#endregion
208
205
  //#region src/utils/build-intersection.ts
206
+ var import_dist = require_dist();
209
207
  /**
210
208
  * Compute the intersection for a single profile source string.
211
209
  * Shared utility used by sync, config, and manage commands.
@@ -254,7 +252,7 @@ function displayIntersection(intersection) {
254
252
  const hasAiData = intersection.aiTools.synced.length > 0 || intersection.aiTools.unsupported.length > 0 || intersection.aiTools.unavailable.length > 0;
255
253
  const hasIdeData = intersection.idePlatforms.synced.length > 0 || intersection.idePlatforms.unsupported.length > 0 || intersection.idePlatforms.unavailable.length > 0;
256
254
  if (!hasAiData && !hasIdeData) {
257
- p.log.info("No tool or IDE intersection data available.");
255
+ R.info("No tool or IDE intersection data available.");
258
256
  return;
259
257
  }
260
258
  if (hasAiData) displayDimension("AI Tools", intersection.aiTools);
@@ -268,7 +266,7 @@ function displayDimension(label, dimension) {
268
266
  if (dimension.synced.length > 0) for (const item of dimension.synced) lines.push(` \u2713 ${item}`);
269
267
  if (dimension.unavailable.length > 0) for (const item of dimension.unavailable) lines.push(` - ${item} (not installed)`);
270
268
  if (dimension.unsupported.length > 0) for (const item of dimension.unsupported) lines.push(` ~ ${item} (not supported by profile)`);
271
- if (lines.length > 0) p.note(lines.join("\n"), label);
269
+ if (lines.length > 0) Ve(lines.join("\n"), label);
272
270
  }
273
271
  /**
274
272
  * Format a compact intersection summary for inline display.
@@ -297,14 +295,14 @@ async function loadConfig() {
297
295
  } catch {
298
296
  return {};
299
297
  }
300
- return parse(await readFile(CONFIG_FILE, "utf-8"));
298
+ return (0, import_dist.parse)(await readFile(CONFIG_FILE, "utf-8"));
301
299
  }
302
300
  async function saveConfig(config) {
303
301
  await mkdir(dirname(CONFIG_FILE), { recursive: true });
304
- await writeFile(CONFIG_FILE, stringify(config), "utf-8");
302
+ await writeFile(CONFIG_FILE, (0, import_dist.stringify)(config), "utf-8");
305
303
  }
306
304
  async function showDashboard() {
307
- p.intro("Baton Dashboard");
305
+ We("Baton Dashboard");
308
306
  const [sources, aiTools, idePlatforms, projectManifest] = await Promise.all([
309
307
  getGlobalSources(),
310
308
  getGlobalAiTools(),
@@ -312,16 +310,16 @@ async function showDashboard() {
312
310
  loadProjectManifestSafe$1()
313
311
  ]);
314
312
  console.log("");
315
- p.log.step("Global Sources");
316
- if (sources.length === 0) p.log.info(" No sources configured. Run: baton source connect <url>");
313
+ R.step("Global Sources");
314
+ if (sources.length === 0) R.info(" No sources configured. Run: baton source connect <url>");
317
315
  else for (const source of sources) {
318
316
  const defaultBadge = source.default ? " (default)" : "";
319
317
  const desc = source.description ? ` — ${source.description}` : "";
320
- p.log.info(` ${source.name}${defaultBadge}: ${source.url}${desc}`);
318
+ R.info(` ${source.name}${defaultBadge}: ${source.url}${desc}`);
321
319
  }
322
320
  console.log("");
323
- p.log.step("Developer Tools");
324
- if (aiTools.length === 0 && idePlatforms.length === 0) p.log.info(" No tools configured. Run: baton ai-tools scan && baton ides scan");
321
+ R.step("Developer Tools");
322
+ if (aiTools.length === 0 && idePlatforms.length === 0) R.info(" No tools configured. Run: baton ai-tools scan && baton ides scan");
325
323
  else {
326
324
  if (aiTools.length > 0) {
327
325
  const toolNames = aiTools.map((key) => {
@@ -331,17 +329,17 @@ async function showDashboard() {
331
329
  return key;
332
330
  }
333
331
  });
334
- p.log.info(` AI Tools: ${toolNames.join(", ")}`);
332
+ R.info(` AI Tools: ${toolNames.join(", ")}`);
335
333
  }
336
- if (idePlatforms.length > 0) p.log.info(` IDE Platforms: ${idePlatforms.join(", ")}`);
334
+ if (idePlatforms.length > 0) R.info(` IDE Platforms: ${idePlatforms.join(", ")}`);
337
335
  }
338
336
  console.log("");
339
- p.log.step("Current Project");
340
- if (!projectManifest) p.log.info(" Not inside a Baton project. Run: baton init");
341
- else if (projectManifest.profiles.length === 0) p.log.info(" No profiles installed. Run: baton manage");
337
+ R.step("Current Project");
338
+ if (!projectManifest) R.info(" Not inside a Baton project. Run: baton init");
339
+ else if (projectManifest.profiles.length === 0) R.info(" No profiles installed. Run: baton manage");
342
340
  else for (const profile of projectManifest.profiles) {
343
341
  const version = profile.version ? ` (${profile.version})` : "";
344
- p.log.info(` ${profile.source}${version}`);
342
+ R.info(` ${profile.source}${version}`);
345
343
  }
346
344
  if (projectManifest && projectManifest.profiles.length > 0) {
347
345
  if (aiTools.length > 0 || idePlatforms.length > 0) {
@@ -350,18 +348,18 @@ async function showDashboard() {
350
348
  idePlatforms
351
349
  };
352
350
  console.log("");
353
- p.log.step("Active Intersections");
351
+ R.step("Active Intersections");
354
352
  for (const profile of projectManifest.profiles) try {
355
353
  const intersection = await buildIntersection(profile.source, developerTools, process.cwd());
356
354
  if (intersection) {
357
355
  const summary = formatIntersectionSummary(intersection);
358
- p.log.info(` ${profile.source}: ${summary}`);
356
+ R.info(` ${profile.source}: ${summary}`);
359
357
  }
360
358
  } catch {}
361
359
  }
362
360
  }
363
361
  console.log("");
364
- p.outro("Use 'baton config list' to view configuration settings");
362
+ Le("Use 'baton config list' to view configuration settings");
365
363
  }
366
364
  async function loadProjectManifestSafe$1() {
367
365
  try {
@@ -402,33 +400,33 @@ const configCommand = defineCommand({
402
400
  }
403
401
  const selectedAction = action;
404
402
  if (selectedAction === "list") {
405
- p.intro("⚙️ Baton Configuration");
403
+ We("⚙️ Baton Configuration");
406
404
  const config = await loadConfig();
407
405
  if (Object.keys(config).length === 0) {
408
- p.outro("No configuration set. Using defaults.");
406
+ Le("No configuration set. Using defaults.");
409
407
  return;
410
408
  }
411
409
  console.log("");
412
410
  for (const [configKey, configValue] of Object.entries(config)) console.log(`${configKey}: ${Array.isArray(configValue) ? configValue.join(", ") : configValue}`);
413
411
  console.log("");
414
- p.outro("Configuration loaded");
412
+ Le("Configuration loaded");
415
413
  return;
416
414
  }
417
415
  if (selectedAction === "get") {
418
416
  if (!key) {
419
- p.intro("⚙️ Baton Configuration");
420
- p.outro("Error: Missing key argument. Usage: baton config get <key>");
417
+ We("⚙️ Baton Configuration");
418
+ Le("Error: Missing key argument. Usage: baton config get <key>");
421
419
  process.exit(1);
422
420
  }
423
421
  if (!VALID_KEYS.includes(key)) {
424
- p.intro("⚙️ Baton Configuration");
425
- p.outro(`Error: Invalid key "${key}". Valid keys: ${VALID_KEYS.join(", ")}`);
422
+ We("⚙️ Baton Configuration");
423
+ Le(`Error: Invalid key "${key}". Valid keys: ${VALID_KEYS.join(", ")}`);
426
424
  process.exit(1);
427
425
  }
428
426
  const configValue = (await loadConfig())[key];
429
427
  if (configValue === void 0) {
430
- p.intro("⚙️ Baton Configuration");
431
- p.outro(`"${key}" is not set (using default)`);
428
+ We("⚙️ Baton Configuration");
429
+ Le(`"${key}" is not set (using default)`);
432
430
  return;
433
431
  }
434
432
  console.log(Array.isArray(configValue) ? configValue.join(", ") : configValue);
@@ -436,37 +434,37 @@ const configCommand = defineCommand({
436
434
  }
437
435
  if (selectedAction === "set") {
438
436
  if (!key || !value) {
439
- p.intro("⚙️ Baton Configuration");
440
- p.outro("Error: Missing arguments. Usage: baton config set <key> <value>");
437
+ We("⚙️ Baton Configuration");
438
+ Le("Error: Missing arguments. Usage: baton config set <key> <value>");
441
439
  process.exit(1);
442
440
  }
443
441
  if (!VALID_KEYS.includes(key)) {
444
- p.intro("⚙️ Baton Configuration");
445
- p.outro(`Error: Invalid key "${key}". Valid keys: ${VALID_KEYS.join(", ")}`);
442
+ We("⚙️ Baton Configuration");
443
+ Le(`Error: Invalid key "${key}". Valid keys: ${VALID_KEYS.join(", ")}`);
446
444
  process.exit(1);
447
445
  }
448
- p.intro("⚙️ Baton Configuration");
446
+ We("⚙️ Baton Configuration");
449
447
  const config = await loadConfig();
450
448
  if (key === "default-scope") {
451
449
  if (value !== "project" && value !== "global") {
452
- p.outro("Error: default-scope must be either \"project\" or \"global\"");
450
+ Le("Error: default-scope must be either \"project\" or \"global\"");
453
451
  process.exit(1);
454
452
  }
455
453
  config["default-scope"] = value;
456
454
  } else if (key === "symlink-mode") {
457
455
  if (value !== "true" && value !== "false") {
458
- p.outro("Error: symlink-mode must be either \"true\" or \"false\"");
456
+ Le("Error: symlink-mode must be either \"true\" or \"false\"");
459
457
  process.exit(1);
460
458
  }
461
459
  config["symlink-mode"] = value === "true";
462
460
  } else if (key === "default-tools") config["default-tools"] = value.split(",").map((s) => s.trim());
463
461
  else if (key === "cache-dir") config["cache-dir"] = value;
464
462
  await saveConfig(config);
465
- p.outro(`✓ Set ${key} = ${Array.isArray(config[key]) ? config[key].join(", ") : config[key]}`);
463
+ Le(`✓ Set ${key} = ${Array.isArray(config[key]) ? config[key].join(", ") : config[key]}`);
466
464
  return;
467
465
  }
468
- p.intro("⚙️ Baton Configuration");
469
- p.outro(`Error: Unknown action "${selectedAction}". Use: set, get, or list`);
466
+ We("⚙️ Baton Configuration");
467
+ Le(`Error: Unknown action "${selectedAction}". Use: set, get, or list`);
470
468
  process.exit(1);
471
469
  }
472
470
  });
@@ -484,15 +482,15 @@ const diffCommand = defineCommand({
484
482
  alias: "n"
485
483
  } },
486
484
  async run({ args }) {
487
- p.intro("🔍 Baton Diff");
485
+ We("🔍 Baton Diff");
488
486
  try {
489
487
  const projectRoot = process.cwd();
490
488
  const manifest = await loadProjectManifest(resolve(projectRoot, "baton.yaml"));
491
489
  if (!manifest.profiles || manifest.profiles.length === 0) {
492
- p.outro("⚠️ No profiles configured in baton.yaml");
490
+ Le("⚠️ No profiles configured in baton.yaml");
493
491
  process.exit(0);
494
492
  }
495
- const spinner = p.spinner();
493
+ const spinner = bt();
496
494
  spinner.start("Resolving profile chain...");
497
495
  const allProfiles = [];
498
496
  const profileLocalPaths = /* @__PURE__ */ new Map();
@@ -528,7 +526,7 @@ const diffCommand = defineCommand({
528
526
  }
529
527
  if (allProfiles.length === 0) {
530
528
  spinner.stop("No profiles resolved");
531
- p.outro("Nothing to diff. Run `baton manage` to add a profile.");
529
+ Le("Nothing to diff. Run `baton manage` to add a profile.");
532
530
  process.exit(0);
533
531
  }
534
532
  spinner.stop(`Resolved ${allProfiles.length} profile(s)`);
@@ -584,7 +582,7 @@ const diffCommand = defineCommand({
584
582
  } else syncedAiTools = detectedAgents;
585
583
  if (syncedAiTools.length === 0) {
586
584
  spinner.stop("No AI tools in intersection");
587
- p.cancel("No AI tools match. Run `baton ai-tools scan`.");
585
+ Ne("No AI tools match. Run `baton ai-tools scan`.");
588
586
  process.exit(1);
589
587
  }
590
588
  const adapters = getAdaptersForKeys(syncedAiTools);
@@ -719,11 +717,11 @@ const diffCommand = defineCommand({
719
717
  }
720
718
  spinner.stop();
721
719
  if (diffs.length === 0) {
722
- p.log.success("No differences found");
723
- p.outro("✅ Diff complete - all placed files match remote sources");
720
+ R.success("No differences found");
721
+ Le("✅ Diff complete - all placed files match remote sources");
724
722
  process.exit(0);
725
723
  }
726
- p.log.warning(`${diffs.length} file(s) with differences`);
724
+ R.warning(`${diffs.length} file(s) with differences`);
727
725
  for (const diff of diffs) if (args.nameOnly) {
728
726
  const statusSymbol = diff.status === "added" ? "+" : diff.status === "removed" ? "-" : "~";
729
727
  console.log(` ${statusSymbol} ${diff.file}`);
@@ -747,10 +745,10 @@ const diffCommand = defineCommand({
747
745
  } else if (diff.status === "added") console.log(" \x1B[32m+ New file in remote (not yet placed locally)\x1B[0m");
748
746
  else console.log(" \x1B[31m- File exists locally but not in remote\x1B[0m");
749
747
  }
750
- p.outro("✅ Diff complete - differences found. Run `baton sync` to update.");
748
+ Le("✅ Diff complete - differences found. Run `baton sync` to update.");
751
749
  process.exit(1);
752
750
  } catch (error) {
753
- p.log.error(`Failed to run diff: ${error instanceof Error ? error.message : "Unknown error"}`);
751
+ R.error(`Failed to run diff: ${error instanceof Error ? error.message : "Unknown error"}`);
754
752
  process.exit(1);
755
753
  }
756
754
  }
@@ -863,7 +861,7 @@ const idesListCommand = defineCommand({
863
861
  }
864
862
  },
865
863
  async run({ args }) {
866
- if (!args.json) p.intro("Baton - IDE Platforms");
864
+ if (!args.json) We("Baton - IDE Platforms");
867
865
  const savedPlatforms = await getGlobalIdePlatforms();
868
866
  const allIdeKeys = getRegisteredIdePlatforms();
869
867
  const platformStatuses = (args.all ? allIdeKeys : savedPlatforms.length > 0 ? savedPlatforms : allIdeKeys).map((ideKey) => {
@@ -881,15 +879,15 @@ const idesListCommand = defineCommand({
881
879
  return;
882
880
  }
883
881
  if (savedPlatforms.length === 0) {
884
- p.log.warn("No IDE platforms saved in global config.");
885
- p.log.info("Run 'baton ides scan' to detect and save your IDE platforms.");
882
+ R.warn("No IDE platforms saved in global config.");
883
+ R.info("Run 'baton ides scan' to detect and save your IDE platforms.");
886
884
  console.log("");
887
- p.log.info(`All ${allIdeKeys.length} supported platforms:`);
885
+ R.info(`All ${allIdeKeys.length} supported platforms:`);
888
886
  for (const key of allIdeKeys) {
889
887
  const entry = idePlatformRegistry[key];
890
888
  console.log(` \x1b[90m- ${formatIdeName(key)} (${entry?.targetDir ?? key})\x1b[0m`);
891
889
  }
892
- p.outro("Run 'baton ides scan' to get started.");
890
+ Le("Run 'baton ides scan' to get started.");
893
891
  return;
894
892
  }
895
893
  console.log(`\nSaved IDE platforms (${savedPlatforms.length}):\n`);
@@ -899,7 +897,7 @@ const idesListCommand = defineCommand({
899
897
  console.log(`${statusColor}${status} ${platform.name.padEnd(20)} → ${platform.targetDir}`);
900
898
  }
901
899
  console.log("");
902
- p.outro("Manage platforms: 'baton ides scan' (detect)");
900
+ Le("Manage platforms: 'baton ides scan' (detect)");
903
901
  }
904
902
  });
905
903
 
@@ -916,8 +914,8 @@ const idesScanCommand = defineCommand({
916
914
  description: "Automatically save detected platforms without confirmation"
917
915
  } },
918
916
  async run({ args }) {
919
- p.intro("Baton - IDE Platform Scanner");
920
- const spinner = p.spinner();
917
+ We("Baton - IDE Platform Scanner");
918
+ const spinner = bt();
921
919
  spinner.start("Scanning for IDE platforms...");
922
920
  clearIdeCache();
923
921
  const detectedIdes = await detectInstalledIdes();
@@ -935,19 +933,19 @@ const idesScanCommand = defineCommand({
935
933
  else notInstalled.push(entry);
936
934
  }
937
935
  if (installed.length > 0) {
938
- p.log.success(`Found ${installed.length} IDE platform${installed.length !== 1 ? "s" : ""}:`);
936
+ R.success(`Found ${installed.length} IDE platform${installed.length !== 1 ? "s" : ""}:`);
939
937
  for (const ide of installed) {
940
938
  const badge = currentPlatforms.includes(ide.key) ? " (saved)" : " (new)";
941
939
  console.log(` \x1b[32m✓\x1b[0m ${ide.name}${badge}`);
942
940
  }
943
941
  } else {
944
- p.log.warn("No IDE platforms detected on your system.");
945
- p.outro("Scan finished.");
942
+ R.warn("No IDE platforms detected on your system.");
943
+ Le("Scan finished.");
946
944
  return;
947
945
  }
948
946
  if (notInstalled.length > 0) {
949
947
  console.log("");
950
- p.log.info(`Not detected (${notInstalled.length}):`);
948
+ R.info(`Not detected (${notInstalled.length}):`);
951
949
  for (const ide of notInstalled) console.log(` \x1b[90m✗ ${ide.name}\x1b[0m`);
952
950
  }
953
951
  const detectedKeys = installed.map((i) => i.key);
@@ -955,22 +953,22 @@ const idesScanCommand = defineCommand({
955
953
  console.log("");
956
954
  let shouldSave = args.yes;
957
955
  if (!shouldSave) {
958
- const confirm = await p.confirm({ message: "Save detected platforms to global config (~/.baton/config.yaml)?" });
959
- if (p.isCancel(confirm)) {
960
- p.outro("Scan finished (not saved).");
956
+ const confirm = await Re({ message: "Save detected platforms to global config (~/.baton/config.yaml)?" });
957
+ if (Ct(confirm)) {
958
+ Le("Scan finished (not saved).");
961
959
  return;
962
960
  }
963
961
  shouldSave = confirm;
964
962
  }
965
963
  if (shouldSave) {
966
964
  await setGlobalIdePlatforms(detectedKeys);
967
- p.log.success("Platforms saved to global config.");
965
+ R.success("Platforms saved to global config.");
968
966
  }
969
967
  } else {
970
968
  console.log("");
971
- p.log.info("Global config is already up to date.");
969
+ R.info("Global config is already up to date.");
972
970
  }
973
- p.outro("Scan finished.");
971
+ Le("Scan finished.");
974
972
  }
975
973
  });
976
974
 
@@ -999,7 +997,7 @@ const idesCommand = defineCommand({
999
997
  async function selectProfileFromSource(sourceString) {
1000
998
  const parsedSource = parseSource(sourceString);
1001
999
  if ((parsedSource.provider === "github" || parsedSource.provider === "gitlab") && !parsedSource.subpath) {
1002
- const spinner = p.spinner();
1000
+ const spinner = bt();
1003
1001
  spinner.start("Cloning repository to discover profiles...");
1004
1002
  try {
1005
1003
  const cloned = await cloneGitSource({
@@ -1010,10 +1008,10 @@ async function selectProfileFromSource(sourceString) {
1010
1008
  spinner.stop("✅ Repository cloned");
1011
1009
  const profiles = await discoverProfilesInSourceRepo(cloned.localPath);
1012
1010
  if (profiles.length === 0) {
1013
- p.cancel("❌ No profiles found in the source repository");
1011
+ Ne("❌ No profiles found in the source repository");
1014
1012
  process.exit(1);
1015
1013
  }
1016
- const selectedProfilePath = await p.select({
1014
+ const selectedProfilePath = await Je({
1017
1015
  message: "Select a profile from this source:",
1018
1016
  options: profiles.map((profile) => ({
1019
1017
  value: profile.path,
@@ -1021,15 +1019,15 @@ async function selectProfileFromSource(sourceString) {
1021
1019
  hint: profile.description ? `${profile.description} (v${profile.version})` : `v${profile.version}`
1022
1020
  }))
1023
1021
  });
1024
- if (p.isCancel(selectedProfilePath)) {
1025
- p.cancel("❌ Profile selection cancelled");
1022
+ if (Ct(selectedProfilePath)) {
1023
+ Ne("❌ Profile selection cancelled");
1026
1024
  process.exit(0);
1027
1025
  }
1028
1026
  if (selectedProfilePath === ".") return sourceString;
1029
1027
  return `${parsedSource.ref ? `${parsedSource.provider}:${parsedSource.org}/${parsedSource.repo}@${parsedSource.ref}` : `${parsedSource.provider}:${parsedSource.org}/${parsedSource.repo}`}/${selectedProfilePath}`;
1030
1028
  } catch (error) {
1031
1029
  spinner.stop("❌ Failed to clone repository");
1032
- p.cancel(`❌ Failed to discover profiles: ${error instanceof Error ? error.message : String(error)}`);
1030
+ Ne(`❌ Failed to discover profiles: ${error instanceof Error ? error.message : String(error)}`);
1033
1031
  process.exit(1);
1034
1032
  }
1035
1033
  }
@@ -1037,7 +1035,7 @@ async function selectProfileFromSource(sourceString) {
1037
1035
  const profiles = await discoverProfilesInSourceRepo(parsedSource.path.startsWith("/") ? parsedSource.path : resolve(process.cwd(), parsedSource.path));
1038
1036
  if (profiles.length === 0) return sourceString;
1039
1037
  if (profiles.length === 1) return profiles[0].path === "." ? sourceString : `${sourceString}/${profiles[0].path}`;
1040
- const selectedProfilePath = await p.select({
1038
+ const selectedProfilePath = await Je({
1041
1039
  message: "Select a profile from this source:",
1042
1040
  options: profiles.map((profile) => ({
1043
1041
  value: profile.path,
@@ -1045,8 +1043,8 @@ async function selectProfileFromSource(sourceString) {
1045
1043
  hint: profile.description ? `${profile.description} (v${profile.version})` : `v${profile.version}`
1046
1044
  }))
1047
1045
  });
1048
- if (p.isCancel(selectedProfilePath)) {
1049
- p.cancel("❌ Profile selection cancelled");
1046
+ if (Ct(selectedProfilePath)) {
1047
+ Ne("❌ Profile selection cancelled");
1050
1048
  process.exit(0);
1051
1049
  }
1052
1050
  if (selectedProfilePath === ".") return sourceString;
@@ -1066,7 +1064,7 @@ async function selectProfileFromSource(sourceString) {
1066
1064
  async function selectMultipleProfilesFromSource(sourceString, options) {
1067
1065
  const parsedSource = parseSource(sourceString);
1068
1066
  if ((parsedSource.provider === "github" || parsedSource.provider === "gitlab") && !parsedSource.subpath) {
1069
- const spinner = p.spinner();
1067
+ const spinner = bt();
1070
1068
  spinner.start("Cloning repository to discover profiles...");
1071
1069
  try {
1072
1070
  const cloned = await cloneGitSource({
@@ -1077,18 +1075,18 @@ async function selectMultipleProfilesFromSource(sourceString, options) {
1077
1075
  spinner.stop("✅ Repository cloned");
1078
1076
  const profiles = await discoverProfilesInSourceRepo(cloned.localPath);
1079
1077
  if (profiles.length === 0) {
1080
- p.cancel("❌ No profiles found in the source repository");
1078
+ Ne("❌ No profiles found in the source repository");
1081
1079
  process.exit(1);
1082
1080
  }
1083
1081
  if (profiles.length === 1) {
1084
- p.note(`Using profile: ${profiles[0].name}`, "Profile");
1082
+ Ve(`Using profile: ${profiles[0].name}`, "Profile");
1085
1083
  return [constructProfilePath(parsedSource, profiles[0].path)];
1086
1084
  }
1087
1085
  if (options?.nonInteractive) {
1088
- p.note(`Auto-selecting all ${profiles.length} profile(s)`, "Non-interactive mode");
1086
+ Ve(`Auto-selecting all ${profiles.length} profile(s)`, "Non-interactive mode");
1089
1087
  return profiles.map((prof) => constructProfilePath(parsedSource, prof.path));
1090
1088
  }
1091
- const selected = await p.multiselect({
1089
+ const selected = await je({
1092
1090
  message: "Select profile(s) to install: (Space to select, Enter to continue)",
1093
1091
  options: profiles.map((prof) => ({
1094
1092
  value: prof.path,
@@ -1097,14 +1095,14 @@ async function selectMultipleProfilesFromSource(sourceString, options) {
1097
1095
  })),
1098
1096
  required: true
1099
1097
  });
1100
- if (p.isCancel(selected)) {
1101
- p.cancel("❌ Profile selection cancelled");
1098
+ if (Ct(selected)) {
1099
+ Ne("❌ Profile selection cancelled");
1102
1100
  process.exit(0);
1103
1101
  }
1104
1102
  return selected.map((path) => constructProfilePath(parsedSource, path));
1105
1103
  } catch (error) {
1106
1104
  spinner.stop("❌ Failed to clone repository");
1107
- p.cancel(`❌ Failed to discover profiles: ${error instanceof Error ? error.message : String(error)}`);
1105
+ Ne(`❌ Failed to discover profiles: ${error instanceof Error ? error.message : String(error)}`);
1108
1106
  process.exit(1);
1109
1107
  }
1110
1108
  }
@@ -1112,14 +1110,14 @@ async function selectMultipleProfilesFromSource(sourceString, options) {
1112
1110
  const profiles = await discoverProfilesInSourceRepo(parsedSource.path.startsWith("/") ? parsedSource.path : resolve(process.cwd(), parsedSource.path));
1113
1111
  if (profiles.length === 0) return [sourceString];
1114
1112
  if (profiles.length === 1) {
1115
- p.note(`Using profile: ${profiles[0].name}`, "Profile");
1113
+ Ve(`Using profile: ${profiles[0].name}`, "Profile");
1116
1114
  return [profiles[0].path === "." ? sourceString : `${sourceString}/${profiles[0].path}`];
1117
1115
  }
1118
1116
  if (options?.nonInteractive) {
1119
- p.note(`Auto-selecting all ${profiles.length} profile(s)`, "Non-interactive mode");
1117
+ Ve(`Auto-selecting all ${profiles.length} profile(s)`, "Non-interactive mode");
1120
1118
  return profiles.map((prof) => prof.path === "." ? sourceString : `${sourceString}/${prof.path}`);
1121
1119
  }
1122
- const selected = await p.multiselect({
1120
+ const selected = await je({
1123
1121
  message: "Select profile(s) to install: (Space to select, Enter to continue)",
1124
1122
  options: profiles.map((prof) => ({
1125
1123
  value: prof.path,
@@ -1128,8 +1126,8 @@ async function selectMultipleProfilesFromSource(sourceString, options) {
1128
1126
  })),
1129
1127
  required: true
1130
1128
  });
1131
- if (p.isCancel(selected)) {
1132
- p.cancel("❌ Profile selection cancelled");
1129
+ if (Ct(selected)) {
1130
+ Ne("❌ Profile selection cancelled");
1133
1131
  process.exit(0);
1134
1132
  }
1135
1133
  return selected.map((path) => path === "." ? sourceString : `${sourceString}/${path}`);
@@ -1161,12 +1159,12 @@ async function runBatonSync(cwd) {
1161
1159
  stdio: "inherit"
1162
1160
  });
1163
1161
  syncProcess.on("close", (code) => {
1164
- if (code === 0) p.log.success("Profiles synced successfully!");
1165
- else p.log.warn(`Sync finished with exit code ${code}`);
1162
+ if (code === 0) R.success("Profiles synced successfully!");
1163
+ else R.warn(`Sync finished with exit code ${code}`);
1166
1164
  done();
1167
1165
  });
1168
1166
  syncProcess.on("error", (error) => {
1169
- p.log.warn(`Failed to run sync: ${error.message}`);
1167
+ R.warn(`Failed to run sync: ${error.message}`);
1170
1168
  done();
1171
1169
  });
1172
1170
  });
@@ -1197,17 +1195,17 @@ const initCommand = defineCommand({
1197
1195
  async run({ args }) {
1198
1196
  const isInteractive = !args.yes;
1199
1197
  const cwd = process.cwd();
1200
- p.intro("🎯 Welcome to Baton");
1198
+ We("🎯 Welcome to Baton");
1201
1199
  try {
1202
1200
  await readFile(join(cwd, "baton.yaml"));
1203
1201
  if (!args.force) {
1204
- p.cancel("baton.yaml already exists in this directory.");
1205
- p.note("Use `baton manage` to modify your project configuration\nor `baton sync` to sync your profiles.\n\nTo reinitialize, use `baton init --force`.", "Already initialized");
1202
+ Ne("baton.yaml already exists in this directory.");
1203
+ Ve("Use `baton manage` to modify your project configuration\nor `baton sync` to sync your profiles.\n\nTo reinitialize, use `baton init --force`.", "Already initialized");
1206
1204
  process.exit(1);
1207
1205
  }
1208
- p.log.warn("Overwriting existing baton.yaml (--force)");
1206
+ R.warn("Overwriting existing baton.yaml (--force)");
1209
1207
  } catch (_error) {}
1210
- const spinner = p.spinner();
1208
+ const spinner = bt();
1211
1209
  await autoScanAiTools(spinner, isInteractive);
1212
1210
  await autoScanIdePlatforms(spinner, isInteractive);
1213
1211
  let profileSources;
@@ -1215,17 +1213,17 @@ const initCommand = defineCommand({
1215
1213
  else {
1216
1214
  const globalSources = await getGlobalSources();
1217
1215
  if (globalSources.length === 0) {
1218
- p.cancel("No sources configured.");
1219
- p.note("Connect a source repository first:\n\n baton source connect <url>\n\nExample:\n baton source connect github:my-org/dx-config", "No sources found");
1216
+ Ne("No sources configured.");
1217
+ Ve("Connect a source repository first:\n\n baton source connect <url>\n\nExample:\n baton source connect github:my-org/dx-config", "No sources found");
1220
1218
  process.exit(1);
1221
1219
  } else if (globalSources.length === 1 && globalSources[0].default) {
1222
1220
  const defaultSource = globalSources[0];
1223
- p.note(`Using default source: ${defaultSource.name}\n${defaultSource.url}`, "Source");
1221
+ Ve(`Using default source: ${defaultSource.name}\n${defaultSource.url}`, "Source");
1224
1222
  profileSources = await selectMultipleProfilesFromSource(defaultSource.url, { nonInteractive: !isInteractive });
1225
1223
  } else if (!isInteractive) profileSources = await selectMultipleProfilesFromSource((await getDefaultGlobalSource())?.url || globalSources[0].url, { nonInteractive: true });
1226
1224
  else {
1227
1225
  const defaultSource = await getDefaultGlobalSource();
1228
- const selectedUrl = await p.select({
1226
+ const selectedUrl = await Je({
1229
1227
  message: "Select a source repository:",
1230
1228
  options: globalSources.map((s) => ({
1231
1229
  value: s.url,
@@ -1234,15 +1232,15 @@ const initCommand = defineCommand({
1234
1232
  })),
1235
1233
  initialValue: defaultSource?.url
1236
1234
  });
1237
- if (p.isCancel(selectedUrl)) {
1238
- p.cancel("Setup cancelled.");
1235
+ if (Ct(selectedUrl)) {
1236
+ Ne("Setup cancelled.");
1239
1237
  process.exit(0);
1240
1238
  }
1241
1239
  profileSources = await selectMultipleProfilesFromSource(selectedUrl);
1242
1240
  }
1243
1241
  }
1244
1242
  await showProfileIntersections(profileSources);
1245
- const yamlContent = stringify({ profiles: profileSources.map((source) => ({ source })) });
1243
+ const yamlContent = (0, import_dist.stringify)({ profiles: profileSources.map((source) => ({ source })) });
1246
1244
  spinner.start("Creating baton.yaml...");
1247
1245
  await writeFile(join(cwd, "baton.yaml"), yamlContent, "utf-8");
1248
1246
  spinner.stop("✅ Created baton.yaml");
@@ -1264,14 +1262,14 @@ const initCommand = defineCommand({
1264
1262
  spinner.stop("✅ .baton directory already exists");
1265
1263
  }
1266
1264
  if (profileSources.length > 0) {
1267
- const shouldSync = isInteractive ? await p.confirm({
1265
+ const shouldSync = isInteractive ? await Re({
1268
1266
  message: "Sync profiles now?",
1269
1267
  initialValue: true
1270
1268
  }) : true;
1271
- if (!p.isCancel(shouldSync) && shouldSync) await runBatonSync(cwd);
1272
- else p.log.info("Run 'baton sync' later to apply your profiles.");
1269
+ if (!Ct(shouldSync) && shouldSync) await runBatonSync(cwd);
1270
+ else R.info("Run 'baton sync' later to apply your profiles.");
1273
1271
  }
1274
- p.outro("Baton initialized successfully!");
1272
+ Le("Baton initialized successfully!");
1275
1273
  }
1276
1274
  });
1277
1275
  /**
@@ -1282,7 +1280,7 @@ const initCommand = defineCommand({
1282
1280
  async function autoScanAiTools(spinner, isInteractive) {
1283
1281
  const existingTools = await getGlobalAiTools();
1284
1282
  if (existingTools.length > 0) {
1285
- p.log.info(`AI tools already configured: ${existingTools.join(", ")}`);
1283
+ R.info(`AI tools already configured: ${existingTools.join(", ")}`);
1286
1284
  return;
1287
1285
  }
1288
1286
  spinner.start("Scanning for installed AI tools...");
@@ -1290,21 +1288,21 @@ async function autoScanAiTools(spinner, isInteractive) {
1290
1288
  const detectedTools = await detectInstalledAgents();
1291
1289
  spinner.stop(detectedTools.length > 0 ? `Found ${detectedTools.length} AI tool${detectedTools.length !== 1 ? "s" : ""}: ${detectedTools.join(", ")}` : "No AI tools detected.");
1292
1290
  if (detectedTools.length === 0) {
1293
- p.log.warn("No AI tools detected. You can run 'baton ai-tools scan' later.");
1291
+ R.warn("No AI tools detected. You can run 'baton ai-tools scan' later.");
1294
1292
  return;
1295
1293
  }
1296
1294
  if (isInteractive) {
1297
- const shouldSave = await p.confirm({
1295
+ const shouldSave = await Re({
1298
1296
  message: "Save detected AI tools to global config?",
1299
1297
  initialValue: true
1300
1298
  });
1301
- if (p.isCancel(shouldSave) || !shouldSave) {
1302
- p.log.info("Skipped saving AI tools. Run 'baton ai-tools scan' later.");
1299
+ if (Ct(shouldSave) || !shouldSave) {
1300
+ R.info("Skipped saving AI tools. Run 'baton ai-tools scan' later.");
1303
1301
  return;
1304
1302
  }
1305
1303
  }
1306
1304
  await setGlobalAiTools(detectedTools);
1307
- p.log.success("AI tools saved to global config.");
1305
+ R.success("AI tools saved to global config.");
1308
1306
  }
1309
1307
  /**
1310
1308
  * Auto-scan IDE platforms if none are configured in global config.
@@ -1314,7 +1312,7 @@ async function autoScanAiTools(spinner, isInteractive) {
1314
1312
  async function autoScanIdePlatforms(spinner, isInteractive) {
1315
1313
  const existingPlatforms = await getGlobalIdePlatforms();
1316
1314
  if (existingPlatforms.length > 0) {
1317
- p.log.info(`IDE platforms already configured: ${existingPlatforms.join(", ")}`);
1315
+ R.info(`IDE platforms already configured: ${existingPlatforms.join(", ")}`);
1318
1316
  return;
1319
1317
  }
1320
1318
  spinner.start("Scanning for installed IDE platforms...");
@@ -1322,21 +1320,21 @@ async function autoScanIdePlatforms(spinner, isInteractive) {
1322
1320
  const detectedIdes = await detectInstalledIdes();
1323
1321
  spinner.stop(detectedIdes.length > 0 ? `Found ${detectedIdes.length} IDE platform${detectedIdes.length !== 1 ? "s" : ""}: ${detectedIdes.join(", ")}` : "No IDE platforms detected.");
1324
1322
  if (detectedIdes.length === 0) {
1325
- p.log.warn("No IDE platforms detected. You can run 'baton ides scan' later.");
1323
+ R.warn("No IDE platforms detected. You can run 'baton ides scan' later.");
1326
1324
  return;
1327
1325
  }
1328
1326
  if (isInteractive) {
1329
- const shouldSave = await p.confirm({
1327
+ const shouldSave = await Re({
1330
1328
  message: "Save detected IDE platforms to global config?",
1331
1329
  initialValue: true
1332
1330
  });
1333
- if (p.isCancel(shouldSave) || !shouldSave) {
1334
- p.log.info("Skipped saving IDE platforms. Run 'baton ides scan' later.");
1331
+ if (Ct(shouldSave) || !shouldSave) {
1332
+ R.info("Skipped saving IDE platforms. Run 'baton ides scan' later.");
1335
1333
  return;
1336
1334
  }
1337
1335
  }
1338
1336
  await setGlobalIdePlatforms(detectedIdes);
1339
- p.log.success("IDE platforms saved to global config.");
1337
+ R.success("IDE platforms saved to global config.");
1340
1338
  }
1341
1339
  /**
1342
1340
  * Load source/profile manifests for each selected profile and display
@@ -1382,7 +1380,7 @@ async function showProfileIntersections(profileSources) {
1382
1380
  if (!profileManifest) continue;
1383
1381
  const intersection = computeIntersection(developerTools, resolveProfileSupport(profileManifest, sourceManifest));
1384
1382
  if (intersection.aiTools.synced.length > 0 || intersection.aiTools.unavailable.length > 0 || intersection.idePlatforms.synced.length > 0 || intersection.idePlatforms.unavailable.length > 0) {
1385
- p.log.step(`Intersection for ${profileManifest.name}`);
1383
+ R.step(`Intersection for ${profileManifest.name}`);
1386
1384
  displayIntersection(intersection);
1387
1385
  }
1388
1386
  } catch {}
@@ -1412,16 +1410,16 @@ async function showOverview(cwd) {
1412
1410
  hasLockfile(cwd)
1413
1411
  ]);
1414
1412
  if (!manifest) {
1415
- p.log.warn("Could not load baton.yaml");
1413
+ R.warn("Could not load baton.yaml");
1416
1414
  return;
1417
1415
  }
1418
- p.log.step("Installed Profiles");
1419
- if (manifest.profiles.length === 0) p.log.info(" No profiles installed.");
1416
+ R.step("Installed Profiles");
1417
+ if (manifest.profiles.length === 0) R.info(" No profiles installed.");
1420
1418
  else for (const profile of manifest.profiles) {
1421
1419
  const version = profile.version ? ` (${profile.version})` : "";
1422
1420
  const matchingSource = sources.find((s) => profile.source.includes(s.url) || profile.source.includes(s.name));
1423
1421
  const sourceName = matchingSource ? ` [${matchingSource.name}]` : "";
1424
- p.log.info(` ${profile.source}${version}${sourceName}`);
1422
+ R.info(` ${profile.source}${version}${sourceName}`);
1425
1423
  }
1426
1424
  if (manifest.profiles.length > 0) {
1427
1425
  const aiTools = await getGlobalAiTools();
@@ -1432,48 +1430,48 @@ async function showOverview(cwd) {
1432
1430
  idePlatforms
1433
1431
  };
1434
1432
  console.log("");
1435
- p.log.step("Tool Intersection");
1433
+ R.step("Tool Intersection");
1436
1434
  for (const profile of manifest.profiles) try {
1437
1435
  const intersection = await buildIntersection(profile.source, developerTools, cwd);
1438
1436
  if (intersection) {
1439
1437
  const summary = formatIntersectionSummary(intersection);
1440
- p.log.info(` ${profile.source}: ${summary}`);
1438
+ R.info(` ${profile.source}: ${summary}`);
1441
1439
  displayIntersection(intersection);
1442
1440
  }
1443
1441
  } catch {}
1444
1442
  }
1445
1443
  }
1446
1444
  console.log("");
1447
- p.log.step("Sync Status");
1448
- if (synced) p.log.info(" Synced (baton.lock exists)");
1449
- else p.log.info(" Not synced — run 'baton sync' to sync profiles");
1445
+ R.step("Sync Status");
1446
+ if (synced) R.info(" Synced (baton.lock exists)");
1447
+ else R.info(" Not synced — run 'baton sync' to sync profiles");
1450
1448
  console.log("");
1451
- p.log.step("Global Sources");
1452
- if (sources.length === 0) p.log.info(" No sources configured. Run: baton source connect <url>");
1449
+ R.step("Global Sources");
1450
+ if (sources.length === 0) R.info(" No sources configured. Run: baton source connect <url>");
1453
1451
  else for (const source of sources) {
1454
1452
  const defaultBadge = source.default ? " (default)" : "";
1455
- p.log.info(` ${source.name}${defaultBadge}: ${source.url}`);
1453
+ R.info(` ${source.name}${defaultBadge}: ${source.url}`);
1456
1454
  }
1457
1455
  }
1458
1456
  async function handleAddProfile(cwd) {
1459
1457
  const manifestPath = join(cwd, "baton.yaml");
1460
1458
  const manifest = await loadProjectManifestSafe(cwd);
1461
1459
  if (!manifest) {
1462
- p.log.error("Could not load baton.yaml");
1460
+ R.error("Could not load baton.yaml");
1463
1461
  return;
1464
1462
  }
1465
1463
  const globalSources = await getGlobalSources();
1466
1464
  if (globalSources.length === 0) {
1467
- p.log.warn("No global sources configured. Run: baton source connect <url>");
1465
+ R.warn("No global sources configured. Run: baton source connect <url>");
1468
1466
  return;
1469
1467
  }
1470
1468
  let sourceString;
1471
1469
  if (globalSources.length === 1) {
1472
1470
  sourceString = globalSources[0].url;
1473
- p.log.info(`Using source: ${globalSources[0].name} (${sourceString})`);
1471
+ R.info(`Using source: ${globalSources[0].name} (${sourceString})`);
1474
1472
  } else {
1475
1473
  const defaultSource = await getDefaultGlobalSource();
1476
- const selectedUrl = await p.select({
1474
+ const selectedUrl = await Je({
1477
1475
  message: "Select a source repository:",
1478
1476
  options: globalSources.map((s) => ({
1479
1477
  value: s.url,
@@ -1482,26 +1480,26 @@ async function handleAddProfile(cwd) {
1482
1480
  })),
1483
1481
  initialValue: defaultSource?.url
1484
1482
  });
1485
- if (p.isCancel(selectedUrl)) {
1486
- p.log.warn("Cancelled.");
1483
+ if (Ct(selectedUrl)) {
1484
+ R.warn("Cancelled.");
1487
1485
  return;
1488
1486
  }
1489
1487
  sourceString = selectedUrl;
1490
1488
  }
1491
1489
  const selectedSource = await selectProfileFromSource(sourceString);
1492
1490
  if (manifest.profiles.some((pr) => pr.source === selectedSource)) {
1493
- p.log.warn(`Profile "${selectedSource}" is already installed.`);
1491
+ R.warn(`Profile "${selectedSource}" is already installed.`);
1494
1492
  return;
1495
1493
  }
1496
1494
  manifest.profiles.push({ source: selectedSource });
1497
- await writeFile(manifestPath, stringify(manifest), "utf-8");
1498
- p.log.success(`Added profile: ${selectedSource}`);
1499
- const shouldSync = await p.confirm({
1495
+ await writeFile(manifestPath, (0, import_dist.stringify)(manifest), "utf-8");
1496
+ R.success(`Added profile: ${selectedSource}`);
1497
+ const shouldSync = await Re({
1500
1498
  message: "Sync profiles now?",
1501
1499
  initialValue: true
1502
1500
  });
1503
- if (p.isCancel(shouldSync) || !shouldSync) {
1504
- p.log.info("Run 'baton sync' later to apply the new profile.");
1501
+ if (Ct(shouldSync) || !shouldSync) {
1502
+ R.info("Run 'baton sync' later to apply the new profile.");
1505
1503
  return;
1506
1504
  }
1507
1505
  await runBatonSync(cwd);
@@ -1510,14 +1508,14 @@ async function handleRemoveProfile(cwd) {
1510
1508
  const manifestPath = join(cwd, "baton.yaml");
1511
1509
  const manifest = await loadProjectManifestSafe(cwd);
1512
1510
  if (!manifest) {
1513
- p.log.error("Could not load baton.yaml");
1511
+ R.error("Could not load baton.yaml");
1514
1512
  return;
1515
1513
  }
1516
1514
  if (manifest.profiles.length === 0) {
1517
- p.log.warn("No profiles installed.");
1515
+ R.warn("No profiles installed.");
1518
1516
  return;
1519
1517
  }
1520
- const selected = await p.select({
1518
+ const selected = await Je({
1521
1519
  message: "Which profile do you want to remove?",
1522
1520
  options: manifest.profiles.map((pr) => ({
1523
1521
  value: pr.source,
@@ -1525,42 +1523,42 @@ async function handleRemoveProfile(cwd) {
1525
1523
  hint: pr.version ? `v${pr.version}` : void 0
1526
1524
  }))
1527
1525
  });
1528
- if (p.isCancel(selected)) {
1529
- p.log.warn("Cancelled.");
1526
+ if (Ct(selected)) {
1527
+ R.warn("Cancelled.");
1530
1528
  return;
1531
1529
  }
1532
1530
  const profileSource = selected;
1533
- const confirmed = await p.confirm({
1531
+ const confirmed = await Re({
1534
1532
  message: `Remove profile "${profileSource}"?`,
1535
1533
  initialValue: false
1536
1534
  });
1537
- if (p.isCancel(confirmed) || !confirmed) {
1538
- p.log.warn("Cancelled.");
1535
+ if (Ct(confirmed) || !confirmed) {
1536
+ R.warn("Cancelled.");
1539
1537
  return;
1540
1538
  }
1541
1539
  const profileIndex = manifest.profiles.findIndex((pr) => pr.source === profileSource);
1542
1540
  manifest.profiles.splice(profileIndex, 1);
1543
- await writeFile(manifestPath, stringify(manifest), "utf-8");
1544
- p.log.success(`Removed profile: ${profileSource}`);
1545
- p.log.info("Run 'baton sync' to clean up synced files.");
1541
+ await writeFile(manifestPath, (0, import_dist.stringify)(manifest), "utf-8");
1542
+ R.success(`Removed profile: ${profileSource}`);
1543
+ R.info("Run 'baton sync' to clean up synced files.");
1546
1544
  }
1547
1545
  async function handleRemoveBaton(cwd) {
1548
- p.log.warn("This will remove Baton from your project:");
1549
- p.log.info(" - baton.yaml (project manifest)");
1550
- p.log.info(" - baton.lock (lockfile)");
1551
- const confirmed = await p.confirm({
1546
+ R.warn("This will remove Baton from your project:");
1547
+ R.info(" - baton.yaml (project manifest)");
1548
+ R.info(" - baton.lock (lockfile)");
1549
+ const confirmed = await Re({
1552
1550
  message: "Are you sure you want to remove Baton from this project?",
1553
1551
  initialValue: false
1554
1552
  });
1555
- if (p.isCancel(confirmed) || !confirmed) {
1556
- p.log.warn("Cancelled.");
1553
+ if (Ct(confirmed) || !confirmed) {
1554
+ R.warn("Cancelled.");
1557
1555
  return false;
1558
1556
  }
1559
1557
  await rm(join(cwd, "baton.yaml"), { force: true });
1560
1558
  await rm(join(cwd, "baton.lock"), { force: true });
1561
- p.log.success("Baton has been removed from this project.");
1562
- p.log.info("Note: Synced files (rules, skills, memory) were not removed.");
1563
- p.log.info("Run 'baton sync' before removing to clean up, or delete them manually.");
1559
+ R.success("Baton has been removed from this project.");
1560
+ R.info("Note: Synced files (rules, skills, memory) were not removed.");
1561
+ R.info("Run 'baton sync' before removing to clean up, or delete them manually.");
1564
1562
  return true;
1565
1563
  }
1566
1564
  const manageCommand = defineCommand({
@@ -1571,13 +1569,13 @@ const manageCommand = defineCommand({
1571
1569
  async run() {
1572
1570
  const cwd = process.cwd();
1573
1571
  if (!await loadProjectManifestSafe(cwd)) {
1574
- p.intro("Baton Manage");
1575
- p.cancel("baton.yaml not found. Run 'baton init' first.");
1572
+ We("Baton Manage");
1573
+ Ne("baton.yaml not found. Run 'baton init' first.");
1576
1574
  process.exit(1);
1577
1575
  }
1578
- p.intro("Baton Manage");
1576
+ We("Baton Manage");
1579
1577
  while (true) {
1580
- const action = await p.select({
1578
+ const action = await Je({
1581
1579
  message: "What would you like to do?",
1582
1580
  options: [
1583
1581
  {
@@ -1606,8 +1604,8 @@ const manageCommand = defineCommand({
1606
1604
  }
1607
1605
  ]
1608
1606
  });
1609
- if (p.isCancel(action) || action === "quit") {
1610
- p.outro("Goodbye!");
1607
+ if (Ct(action) || action === "quit") {
1608
+ Le("Goodbye!");
1611
1609
  return;
1612
1610
  }
1613
1611
  if (action === "overview") {
@@ -1625,7 +1623,7 @@ const manageCommand = defineCommand({
1625
1623
  } else if (action === "remove-baton") {
1626
1624
  console.log("");
1627
1625
  if (await handleRemoveBaton(cwd)) {
1628
- p.outro("Goodbye!");
1626
+ Le("Goodbye!");
1629
1627
  return;
1630
1628
  }
1631
1629
  console.log("");
@@ -1642,9 +1640,9 @@ const profileCommand = defineCommand({
1642
1640
  description: "Manage profiles (create, list, remove)"
1643
1641
  },
1644
1642
  subCommands: {
1645
- create: () => import("./create-CqfUSGj7.mjs").then((m) => m.createCommand),
1646
- list: () => import("./list-o76RXPxE.mjs").then((m) => m.profileListCommand),
1647
- remove: () => import("./remove-BB883RDx.mjs").then((m) => m.profileRemoveCommand)
1643
+ create: () => import("./create-Diqnd3ci.mjs").then((m) => m.createCommand),
1644
+ list: () => import("./list-B5xUVBTU.mjs").then((m) => m.profileListCommand),
1645
+ remove: () => import("./remove-6S8F9xcE.mjs").then((m) => m.profileRemoveCommand)
1648
1646
  }
1649
1647
  });
1650
1648
 
@@ -1680,14 +1678,14 @@ const connectCommand = defineCommand({
1680
1678
  const url = args.url;
1681
1679
  const customName = args.name;
1682
1680
  if (customName && !KEBAB_CASE_REGEX.test(customName)) {
1683
- p.cancel("Source name must be kebab-case (e.g., my-source)");
1681
+ Ne("Source name must be kebab-case (e.g., my-source)");
1684
1682
  process.exit(1);
1685
1683
  }
1686
1684
  try {
1687
1685
  parseSource(url);
1688
1686
  } catch (error) {
1689
1687
  const message = error instanceof SourceParseError ? error.message : `Invalid source: ${error.message}`;
1690
- p.cancel(message);
1688
+ Ne(message);
1691
1689
  process.exit(1);
1692
1690
  }
1693
1691
  try {
@@ -1696,20 +1694,20 @@ const connectCommand = defineCommand({
1696
1694
  description: args.description
1697
1695
  });
1698
1696
  const displayName = args.name || url;
1699
- p.log.success(`Connected source: ${displayName}`);
1700
- const shouldSync = await p.confirm({ message: "Would you like to sync profiles from this source now?" });
1701
- if (p.isCancel(shouldSync) || !shouldSync) {
1702
- p.outro("Source connected. Run 'baton init' to set up profiles.");
1697
+ R.success(`Connected source: ${displayName}`);
1698
+ const shouldSync = await Re({ message: "Would you like to sync profiles from this source now?" });
1699
+ if (Ct(shouldSync) || !shouldSync) {
1700
+ Le("Source connected. Run 'baton init' to set up profiles.");
1703
1701
  return;
1704
1702
  }
1705
- p.outro("Starting profile sync...");
1703
+ Le("Starting profile sync...");
1706
1704
  const profiles = await selectMultipleProfilesFromSource(url);
1707
1705
  if (profiles.length > 0) {
1708
- p.log.success(`Selected ${profiles.length} profile(s) for sync.`);
1709
- p.note("Run 'baton init' in your project directory to install these profiles.", "Next step");
1706
+ R.success(`Selected ${profiles.length} profile(s) for sync.`);
1707
+ Ve("Run 'baton init' in your project directory to install these profiles.", "Next step");
1710
1708
  }
1711
1709
  } catch (error) {
1712
- p.cancel(`Failed to connect source: ${error.message}`);
1710
+ Ne(`Failed to connect source: ${error.message}`);
1713
1711
  process.exit(1);
1714
1712
  }
1715
1713
  }
@@ -1717,13 +1715,14 @@ const connectCommand = defineCommand({
1717
1715
 
1718
1716
  //#endregion
1719
1717
  //#region src/commands/source/create.ts
1718
+ var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
1720
1719
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
1721
1720
  async function runInteractiveWizard(overrides = {}) {
1722
- p.intro("Create a new Baton source repository");
1721
+ We("Create a new Baton source repository");
1723
1722
  let name;
1724
1723
  if (overrides.name) name = overrides.name;
1725
1724
  else {
1726
- const result = await p.text({
1725
+ const result = await Ze({
1727
1726
  message: "What is the name of your source repository?",
1728
1727
  placeholder: "my-team-profile",
1729
1728
  validate: (value) => {
@@ -1731,8 +1730,8 @@ async function runInteractiveWizard(overrides = {}) {
1731
1730
  if (!KEBAB_CASE_REGEX.test(value)) return "Name must be in kebab-case (lowercase, hyphens only)";
1732
1731
  }
1733
1732
  });
1734
- if (p.isCancel(result)) {
1735
- p.cancel("Operation cancelled.");
1733
+ if (Ct(result)) {
1734
+ Ne("Operation cancelled.");
1736
1735
  process.exit(0);
1737
1736
  }
1738
1737
  name = String(result);
@@ -1740,12 +1739,12 @@ async function runInteractiveWizard(overrides = {}) {
1740
1739
  let git;
1741
1740
  if (overrides.git !== void 0) git = overrides.git;
1742
1741
  else {
1743
- const result = await p.confirm({
1742
+ const result = await Re({
1744
1743
  message: "Initialize Git repository?",
1745
1744
  initialValue: true
1746
1745
  });
1747
- if (p.isCancel(result)) {
1748
- p.cancel("Operation cancelled.");
1746
+ if (Ct(result)) {
1747
+ Ne("Operation cancelled.");
1749
1748
  process.exit(0);
1750
1749
  }
1751
1750
  git = result;
@@ -1753,12 +1752,12 @@ async function runInteractiveWizard(overrides = {}) {
1753
1752
  let withInitialProfile;
1754
1753
  if (overrides.withInitialProfile !== void 0) withInitialProfile = overrides.withInitialProfile;
1755
1754
  else {
1756
- const result = await p.confirm({
1755
+ const result = await Re({
1757
1756
  message: "Create initial profile in profiles/default/?",
1758
1757
  initialValue: true
1759
1758
  });
1760
- if (p.isCancel(result)) {
1761
- p.cancel("Operation cancelled.");
1759
+ if (Ct(result)) {
1760
+ Ne("Operation cancelled.");
1762
1761
  process.exit(0);
1763
1762
  }
1764
1763
  withInitialProfile = result;
@@ -1792,7 +1791,7 @@ async function copyDirectory(src, dest, variables) {
1792
1791
  ".ttf",
1793
1792
  ".eot"
1794
1793
  ]).has(entry.name.substring(entry.name.lastIndexOf(".")))) await writeFile(destPath, content);
1795
- else await writeFile(destPath, Handlebars.compile(content, { noEscape: true })(variables));
1794
+ else await writeFile(destPath, import_lib.default.compile(content, { noEscape: true })(variables));
1796
1795
  }
1797
1796
  }
1798
1797
  }
@@ -1800,7 +1799,7 @@ async function copyDirectory(src, dest, variables) {
1800
1799
  * Initialize Git repository and create initial commit
1801
1800
  */
1802
1801
  async function initializeGit(targetDir) {
1803
- const git = simpleGit(targetDir);
1802
+ const git = esm_default(targetDir);
1804
1803
  await git.init();
1805
1804
  await git.add(".");
1806
1805
  await git.commit("Initial baton source setup");
@@ -1929,7 +1928,7 @@ const sourceCreateCommand = defineCommand({
1929
1928
  overrides.withInitialProfile = false;
1930
1929
  }
1931
1930
  const options = await runInteractiveWizard(overrides);
1932
- const spinner = p.spinner();
1931
+ const spinner = bt();
1933
1932
  spinner.start("Creating source repository...");
1934
1933
  try {
1935
1934
  const targetDir = await scaffoldSourceRepo(options);
@@ -1937,7 +1936,7 @@ const sourceCreateCommand = defineCommand({
1937
1936
  const features = [];
1938
1937
  if (options.withInitialProfile) features.push("Initial Profile: profiles/default/");
1939
1938
  if (options.git) features.push("Git: Initialized with initial commit");
1940
- if (features.length > 0) p.note(features.join("\n"), "Features");
1939
+ if (features.length > 0) Ve(features.join("\n"), "Features");
1941
1940
  const org = options.name.includes("-") ? options.name.split("-")[0] : options.name;
1942
1941
  const nextSteps = [];
1943
1942
  nextSteps.push(` cd ${options.name}`);
@@ -1949,7 +1948,7 @@ const sourceCreateCommand = defineCommand({
1949
1948
  nextSteps.push("");
1950
1949
  nextSteps.push(" # Share with your team:");
1951
1950
  nextSteps.push(` baton source connect https://github.com/${org}/${options.name}.git`);
1952
- p.outro(`Source repository "${options.name}" created successfully!\n\nNext steps:\n${nextSteps.join("\n")}`);
1951
+ Le(`Source repository "${options.name}" created successfully!\n\nNext steps:\n${nextSteps.join("\n")}`);
1953
1952
  } catch (error) {
1954
1953
  spinner.stop("Failed to create source repository");
1955
1954
  throw error;
@@ -1979,24 +1978,24 @@ const disconnectCommand = defineCommand({
1979
1978
  const sourceIdentifier = args.source;
1980
1979
  const matchedSource = (await getGlobalSources()).find((s) => s.name === sourceIdentifier || s.url === sourceIdentifier);
1981
1980
  if (!matchedSource) {
1982
- p.cancel(`Source "${sourceIdentifier}" not found in global configuration.`);
1981
+ Ne(`Source "${sourceIdentifier}" not found in global configuration.`);
1983
1982
  process.exit(1);
1984
1983
  }
1985
- p.log.warn(`Disconnecting source "${matchedSource.name}" (${matchedSource.url}) will affect any projects using profiles from this source.`);
1986
- p.log.info("Projects that reference this source will no longer be able to sync or update their profiles.");
1987
- const confirmed = await p.confirm({
1984
+ R.warn(`Disconnecting source "${matchedSource.name}" (${matchedSource.url}) will affect any projects using profiles from this source.`);
1985
+ R.info("Projects that reference this source will no longer be able to sync or update their profiles.");
1986
+ const confirmed = await Re({
1988
1987
  message: `Are you sure you want to disconnect source "${matchedSource.name}"?`,
1989
1988
  initialValue: false
1990
1989
  });
1991
- if (p.isCancel(confirmed) || !confirmed) {
1992
- p.cancel("Operation cancelled.");
1990
+ if (Ct(confirmed) || !confirmed) {
1991
+ Ne("Operation cancelled.");
1993
1992
  process.exit(0);
1994
1993
  }
1995
1994
  try {
1996
1995
  await removeGlobalSource(sourceIdentifier);
1997
- p.outro(`Disconnected source: ${matchedSource.name}`);
1996
+ Le(`Disconnected source: ${matchedSource.name}`);
1998
1997
  } catch (error) {
1999
- p.cancel(`Failed to disconnect source: ${error.message}`);
1998
+ Ne(`Failed to disconnect source: ${error.message}`);
2000
1999
  process.exit(1);
2001
2000
  }
2002
2001
  }
@@ -2017,8 +2016,8 @@ const listCommand = defineCommand({
2017
2016
  async run() {
2018
2017
  const sources = await getGlobalSources();
2019
2018
  if (sources.length === 0) {
2020
- p.log.info("No global sources configured.");
2021
- p.note("Add a source with:\n baton source connect <url>", "Tip");
2019
+ R.info("No global sources configured.");
2020
+ Ve("Add a source with:\n baton source connect <url>", "Tip");
2022
2021
  return;
2023
2022
  }
2024
2023
  console.log("\n🌐 Global Sources\n");
@@ -2160,25 +2159,25 @@ async function cleanupOrphanedFiles(params) {
2160
2159
  const orphanedPaths = [...previousPaths].filter((prev) => !currentPaths.has(prev));
2161
2160
  if (orphanedPaths.length === 0) return;
2162
2161
  if (dryRun) {
2163
- p.log.warn(`Would remove ${orphanedPaths.length} orphaned file(s):`);
2164
- for (const orphanedPath of orphanedPaths) p.log.info(` Removed: ${orphanedPath}`);
2162
+ R.warn(`Would remove ${orphanedPaths.length} orphaned file(s):`);
2163
+ for (const orphanedPath of orphanedPaths) R.info(` Removed: ${orphanedPath}`);
2165
2164
  return;
2166
2165
  }
2167
- p.log.warn(`Found ${orphanedPaths.length} orphaned file(s) to remove:`);
2168
- for (const orphanedPath of orphanedPaths) p.log.info(` Removed: ${orphanedPath}`);
2166
+ R.warn(`Found ${orphanedPaths.length} orphaned file(s) to remove:`);
2167
+ for (const orphanedPath of orphanedPaths) R.info(` Removed: ${orphanedPath}`);
2169
2168
  let shouldRemove = autoYes;
2170
2169
  if (!autoYes) {
2171
- const confirmed = await p.confirm({
2170
+ const confirmed = await Re({
2172
2171
  message: `Remove ${orphanedPaths.length} orphaned file(s)?`,
2173
2172
  initialValue: true
2174
2173
  });
2175
- if (p.isCancel(confirmed)) {
2176
- p.log.info("Skipped orphan removal.");
2174
+ if (Ct(confirmed)) {
2175
+ R.info("Skipped orphan removal.");
2177
2176
  shouldRemove = false;
2178
2177
  } else shouldRemove = confirmed;
2179
2178
  }
2180
2179
  if (!shouldRemove) {
2181
- p.log.info("Orphan removal skipped.");
2180
+ R.info("Orphan removal skipped.");
2182
2181
  return;
2183
2182
  }
2184
2183
  spinner.start("Removing orphaned files...");
@@ -2237,7 +2236,7 @@ const syncCommand = defineCommand({
2237
2236
  let category;
2238
2237
  if (categoryArg) {
2239
2238
  if (!validCategories.includes(categoryArg)) {
2240
- p.cancel(`Invalid category "${categoryArg}". Valid categories: ${validCategories.join(", ")}`);
2239
+ Ne(`Invalid category "${categoryArg}". Valid categories: ${validCategories.join(", ")}`);
2241
2240
  process.exit(1);
2242
2241
  }
2243
2242
  category = categoryArg;
@@ -2245,7 +2244,7 @@ const syncCommand = defineCommand({
2245
2244
  const syncAi = !category || category === "ai";
2246
2245
  const syncFiles = !category || category === "files";
2247
2246
  const syncIde = !category || category === "ide";
2248
- p.intro(category ? `🔄 Baton Sync (category: ${category})` : "🔄 Baton Sync");
2247
+ We(category ? `🔄 Baton Sync (category: ${category})` : "🔄 Baton Sync");
2249
2248
  const stats = {
2250
2249
  created: 0,
2251
2250
  errors: 0
@@ -2257,8 +2256,8 @@ const syncCommand = defineCommand({
2257
2256
  try {
2258
2257
  projectManifest = await loadProjectManifest(manifestPath);
2259
2258
  } catch (error) {
2260
- if (error instanceof FileNotFoundError) p.cancel("baton.yaml not found. Run `baton init` first.");
2261
- else p.cancel(`Failed to load baton.yaml: ${error instanceof Error ? error.message : String(error)}`);
2259
+ if (error instanceof FileNotFoundError) Ne("baton.yaml not found. Run `baton init` first.");
2260
+ else Ne(`Failed to load baton.yaml: ${error instanceof Error ? error.message : String(error)}`);
2262
2261
  process.exit(1);
2263
2262
  }
2264
2263
  const previousPaths = /* @__PURE__ */ new Set();
@@ -2266,19 +2265,19 @@ const syncCommand = defineCommand({
2266
2265
  const previousLock = await readLock(resolve(projectRoot, "baton.lock"));
2267
2266
  for (const pkg of Object.values(previousLock.packages)) for (const filePath of Object.keys(pkg.integrity)) previousPaths.add(filePath);
2268
2267
  } catch {}
2269
- const spinner = p.spinner();
2268
+ const spinner = bt();
2270
2269
  spinner.start("Resolving profile chain...");
2271
2270
  const allProfiles = [];
2272
2271
  const sourceShas = /* @__PURE__ */ new Map();
2273
2272
  for (const profileSource of projectManifest.profiles || []) try {
2274
- if (verbose) p.log.info(`Resolving source: ${profileSource.source}`);
2273
+ if (verbose) R.info(`Resolving source: ${profileSource.source}`);
2275
2274
  const parsed = parseSource(profileSource.source);
2276
2275
  let manifestPath;
2277
2276
  if (parsed.provider === "local" || parsed.provider === "file") {
2278
2277
  const absolutePath = parsed.path.startsWith("/") ? parsed.path : resolve(projectRoot, parsed.path);
2279
2278
  manifestPath = resolve(absolutePath, "baton.profile.yaml");
2280
2279
  try {
2281
- const git = simpleGit(absolutePath);
2280
+ const git = esm_default(absolutePath);
2282
2281
  await git.checkIsRepo();
2283
2282
  const sha = await git.revparse(["HEAD"]);
2284
2283
  sourceShas.set(profileSource.source, sha.trim());
@@ -2307,7 +2306,7 @@ const syncCommand = defineCommand({
2307
2306
  }
2308
2307
  if (allProfiles.length === 0) {
2309
2308
  spinner.stop("No profiles configured");
2310
- p.outro("Nothing to sync. Run `baton manage` to add a profile.");
2309
+ Le("Nothing to sync. Run `baton manage` to add a profile.");
2311
2310
  process.exit(2);
2312
2311
  }
2313
2312
  spinner.stop(`Resolved ${allProfiles.length} profile(s)`);
@@ -2389,7 +2388,7 @@ const syncCommand = defineCommand({
2389
2388
  if (!files) continue;
2390
2389
  const targetDir = getIdePlatformTargetDir(ideKey);
2391
2390
  if (!targetDir) {
2392
- if (!isKnownIdePlatform(ideKey)) p.log.warn(`Unknown IDE platform "${ideKey}" in profile "${profile.name}" — skipping. Register it in the IDE platform registry.`);
2391
+ if (!isKnownIdePlatform(ideKey)) R.warn(`Unknown IDE platform "${ideKey}" in profile "${profile.name}" — skipping. Register it in the IDE platform registry.`);
2393
2392
  continue;
2394
2393
  }
2395
2394
  for (const fileName of files) {
@@ -2419,7 +2418,7 @@ const syncCommand = defineCommand({
2419
2418
  }
2420
2419
  const mergedIdeCount = ideMap.size;
2421
2420
  spinner.stop(`Merged: ${mergedSkills.length} skills, ${mergedRules.length} rules, ${mergedMemory.length} memory files, ${mergedCommandCount} commands, ${mergedFileCount} files, ${mergedIdeCount} IDE configs`);
2422
- if (allWeightWarnings.length > 0) for (const w of allWeightWarnings) p.log.warn(`Weight conflict: "${w.profileA}" and "${w.profileB}" both define ${w.category} "${w.key}" with weight ${w.weight}. Last declared wins.`);
2421
+ if (allWeightWarnings.length > 0) for (const w of allWeightWarnings) R.warn(`Weight conflict: "${w.profileA}" and "${w.profileB}" both define ${w.category} "${w.key}" with weight ${w.weight}. Last declared wins.`);
2423
2422
  spinner.start("Computing tool intersection...");
2424
2423
  const globalAiTools = await getGlobalAiTools();
2425
2424
  const globalIdePlatforms = await getGlobalIdePlatforms();
@@ -2449,26 +2448,26 @@ const syncCommand = defineCommand({
2449
2448
  syncedAiTools = detectedAgents;
2450
2449
  syncedIdePlatforms = null;
2451
2450
  if (detectedAgents.length > 0) {
2452
- p.log.warn("No AI tools configured. Run `baton ai-tools scan` to configure your tools.");
2453
- p.log.info(`Falling back to detected tools: ${detectedAgents.join(", ")}`);
2451
+ R.warn("No AI tools configured. Run `baton ai-tools scan` to configure your tools.");
2452
+ R.info(`Falling back to detected tools: ${detectedAgents.join(", ")}`);
2454
2453
  }
2455
2454
  }
2456
2455
  if (syncedAiTools.length === 0 && detectedAgents.length === 0) {
2457
2456
  spinner.stop("No AI tools available");
2458
- p.cancel("No AI tools found. Install an AI coding tool first.");
2457
+ Ne("No AI tools found. Install an AI coding tool first.");
2459
2458
  process.exit(1);
2460
2459
  }
2461
2460
  if (syncedAiTools.length === 0) {
2462
2461
  spinner.stop("No AI tools in intersection");
2463
- p.cancel("No AI tools match between your configuration and profile support. Run `baton ai-tools scan` or check your profile's supported tools.");
2462
+ Ne("No AI tools match between your configuration and profile support. Run `baton ai-tools scan` or check your profile's supported tools.");
2464
2463
  process.exit(1);
2465
2464
  }
2466
2465
  if (allIntersections) for (const [source, intersection] of allIntersections) if (verbose) {
2467
- p.log.step(`Intersection for ${source}`);
2466
+ R.step(`Intersection for ${source}`);
2468
2467
  displayIntersection(intersection);
2469
2468
  } else {
2470
2469
  const summary = formatIntersectionSummary(intersection);
2471
- p.log.info(`Syncing for: ${summary}`);
2470
+ R.info(`Syncing for: ${summary}`);
2472
2471
  }
2473
2472
  const ideSummary = syncedIdePlatforms && syncedIdePlatforms.length > 0 ? ` | IDE platforms: ${syncedIdePlatforms.join(", ")}` : "";
2474
2473
  spinner.stop(`Syncing AI tools: ${syncedAiTools.join(", ")}${ideSummary}`);
@@ -2477,8 +2476,8 @@ const syncCommand = defineCommand({
2477
2476
  if (legacyFiles.length > 0 && !dryRun) {
2478
2477
  spinner.stop(`Found ${legacyFiles.length} legacy file(s)`);
2479
2478
  if (!autoYes) {
2480
- p.note(`Found legacy configuration files:\n${legacyFiles.map((f) => ` - ${f.legacyPath}`).join("\n")}`, "Legacy Files");
2481
- p.log.warn("Run migration manually with appropriate action (migrate/copy/skip)");
2479
+ Ve(`Found legacy configuration files:\n${legacyFiles.map((f) => ` - ${f.legacyPath}`).join("\n")}`, "Legacy Files");
2480
+ R.warn("Run migration manually with appropriate action (migrate/copy/skip)");
2482
2481
  }
2483
2482
  } else spinner.stop("No legacy files found");
2484
2483
  spinner.start("Processing configurations...");
@@ -2506,7 +2505,7 @@ const syncCommand = defineCommand({
2506
2505
  }
2507
2506
  const contentAccumulator = /* @__PURE__ */ new Map();
2508
2507
  if (!dryRun && syncAi) for (const adapter of adapters) {
2509
- if (verbose) p.log.step(`[${adapter.key}] Placing memory files...`);
2508
+ if (verbose) R.step(`[${adapter.key}] Placing memory files...`);
2510
2509
  for (const memoryEntry of mergedMemory) try {
2511
2510
  const contentParts = [];
2512
2511
  for (const contribution of memoryEntry.contributions) {
@@ -2552,7 +2551,7 @@ const syncCommand = defineCommand({
2552
2551
  }
2553
2552
  }
2554
2553
  if (!dryRun && syncAi) for (const adapter of adapters) {
2555
- if (verbose) p.log.step(`[${adapter.key}] Placing skills...`);
2554
+ if (verbose) R.step(`[${adapter.key}] Placing skills...`);
2556
2555
  for (const skillItem of mergedSkills) try {
2557
2556
  const profileDir = profileLocalPaths.get(skillItem.profileName);
2558
2557
  if (!profileDir) {
@@ -2586,7 +2585,7 @@ const syncCommand = defineCommand({
2586
2585
  }
2587
2586
  if (verbose) {
2588
2587
  const label = placed > 0 ? `${placed} file(s) created` : "unchanged, skipped";
2589
- p.log.info(` -> ${absoluteTargetDir}/ (${label})`);
2588
+ R.info(` -> ${absoluteTargetDir}/ (${label})`);
2590
2589
  }
2591
2590
  } catch (error) {
2592
2591
  spinner.message(`Error placing skill ${skillItem.name} for ${adapter.name}: ${error}`);
@@ -2594,7 +2593,7 @@ const syncCommand = defineCommand({
2594
2593
  }
2595
2594
  }
2596
2595
  if (!dryRun && syncAi) for (const adapter of adapters) {
2597
- if (verbose) p.log.step(`[${adapter.key}] Placing rules...`);
2596
+ if (verbose) R.step(`[${adapter.key}] Placing rules...`);
2598
2597
  for (const ruleEntry of mergedRules) try {
2599
2598
  const isUniversal = ruleEntry.agents.length === 0;
2600
2599
  const isForThisAdapter = ruleEntry.agents.includes(adapter.key);
@@ -2651,14 +2650,14 @@ const syncCommand = defineCommand({
2651
2650
  }
2652
2651
  if (verbose) {
2653
2652
  const label = result.action === "skipped" ? "unchanged, skipped" : result.action;
2654
- p.log.info(` -> ${result.path} (${label})`);
2653
+ R.info(` -> ${result.path} (${label})`);
2655
2654
  }
2656
2655
  } catch (error) {
2657
2656
  spinner.message(`Error placing accumulated content to ${absolutePath}: ${error}`);
2658
2657
  stats.errors++;
2659
2658
  }
2660
2659
  if (!dryRun && syncAi) for (const adapter of adapters) {
2661
- if (verbose) p.log.step(`[${adapter.key}] Placing commands...`);
2660
+ if (verbose) R.step(`[${adapter.key}] Placing commands...`);
2662
2661
  for (const profile of allProfiles) {
2663
2662
  const profileDir = profileLocalPaths.get(profile.name);
2664
2663
  if (!profileDir) continue;
@@ -2681,7 +2680,7 @@ const syncCommand = defineCommand({
2681
2680
  };
2682
2681
  if (verbose) {
2683
2682
  const label = result.action === "skipped" ? "unchanged, skipped" : result.action;
2684
- p.log.info(` -> ${result.path} (${label})`);
2683
+ R.info(` -> ${result.path} (${label})`);
2685
2684
  }
2686
2685
  } catch (error) {
2687
2686
  spinner.message(`Error placing command ${commandName} for ${adapter.name}: ${error}`);
@@ -2704,8 +2703,8 @@ const syncCommand = defineCommand({
2704
2703
  if (await readFile(targetPath, "utf-8").catch(() => void 0) !== content) {
2705
2704
  await writeFile(targetPath, content, "utf-8");
2706
2705
  stats.created++;
2707
- if (verbose) p.log.info(` -> ${fileEntry.target} (created)`);
2708
- } else if (verbose) p.log.info(` -> ${fileEntry.target} (unchanged, skipped)`);
2706
+ if (verbose) R.info(` -> ${fileEntry.target} (created)`);
2707
+ } else if (verbose) R.info(` -> ${fileEntry.target} (unchanged, skipped)`);
2709
2708
  const fpf = getOrCreatePlacedFiles(placedFiles, fileEntry.profileName);
2710
2709
  fpf[fileEntry.target] = {
2711
2710
  content,
@@ -2717,7 +2716,7 @@ const syncCommand = defineCommand({
2717
2716
  }
2718
2717
  if (!dryRun && syncIde) for (const ideEntry of ideMap.values()) try {
2719
2718
  if (syncedIdePlatforms !== null && !syncedIdePlatforms.includes(ideEntry.ideKey)) {
2720
- if (verbose) p.log.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (skipped — IDE platform "${ideEntry.ideKey}" not in intersection)`);
2719
+ if (verbose) R.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (skipped — IDE platform "${ideEntry.ideKey}" not in intersection)`);
2721
2720
  continue;
2722
2721
  }
2723
2722
  const profileDir = profileLocalPaths.get(ideEntry.profileName);
@@ -2734,8 +2733,8 @@ const syncCommand = defineCommand({
2734
2733
  if (await readFile(targetPath, "utf-8").catch(() => void 0) !== content) {
2735
2734
  await writeFile(targetPath, content, "utf-8");
2736
2735
  stats.created++;
2737
- if (verbose) p.log.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (created)`);
2738
- } else if (verbose) p.log.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (unchanged, skipped)`);
2736
+ if (verbose) R.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (created)`);
2737
+ } else if (verbose) R.info(` -> ${ideEntry.targetDir}/${ideEntry.fileName} (unchanged, skipped)`);
2739
2738
  const ideRelPath = `${ideEntry.targetDir}/${ideEntry.fileName}`;
2740
2739
  const ipf = getOrCreatePlacedFiles(placedFiles, ideEntry.profileName);
2741
2740
  ipf[ideRelPath] = {
@@ -2789,14 +2788,14 @@ const syncCommand = defineCommand({
2789
2788
  parts.push(` • ${filteredIdeCount} IDE configs`);
2790
2789
  }
2791
2790
  const categoryLabel = category ? ` (category: ${category})` : "";
2792
- p.outro(`[Dry Run${categoryLabel}] Would sync:\n${parts.join("\n")}\n\nFor ${adapters.length} agent(s): ${syncedAiTools.join(", ")}`);
2791
+ Le(`[Dry Run${categoryLabel}] Would sync:\n${parts.join("\n")}\n\nFor ${adapters.length} agent(s): ${syncedAiTools.join(", ")}`);
2793
2792
  } else {
2794
2793
  const categoryLabel = category ? ` (category: ${category})` : "";
2795
- p.outro(`✅ Sync complete${categoryLabel}! Configurations updated.`);
2794
+ Le(`✅ Sync complete${categoryLabel}! Configurations updated.`);
2796
2795
  }
2797
2796
  process.exit(stats.errors > 0 ? 1 : 0);
2798
2797
  } catch (error) {
2799
- p.cancel(`Sync failed: ${error}`);
2798
+ Ne(`Sync failed: ${error}`);
2800
2799
  process.exit(1);
2801
2800
  }
2802
2801
  }
@@ -2824,18 +2823,18 @@ const updateCommand = defineCommand({
2824
2823
  async run({ args }) {
2825
2824
  const dryRun = args["dry-run"];
2826
2825
  const autoConfirm = args.yes;
2827
- p.intro("Baton Update");
2826
+ We("Baton Update");
2828
2827
  const cwd = process.cwd();
2829
2828
  const manifestPath = resolve(cwd, "baton.yaml");
2830
2829
  const lockfilePath = resolve(cwd, "baton.lock");
2831
- const spinner = p.spinner();
2830
+ const spinner = bt();
2832
2831
  spinner.start("Loading project configuration");
2833
2832
  let manifest;
2834
2833
  try {
2835
2834
  manifest = await loadProjectManifest(manifestPath);
2836
2835
  } catch (error) {
2837
2836
  spinner.stop("Failed to load baton.yaml");
2838
- p.cancel(error instanceof Error ? error.message : "Could not load project manifest");
2837
+ Ne(error instanceof Error ? error.message : "Could not load project manifest");
2839
2838
  process.exit(1);
2840
2839
  }
2841
2840
  let lockfile = null;
@@ -2844,7 +2843,7 @@ const updateCommand = defineCommand({
2844
2843
  spinner.stop("Configuration loaded");
2845
2844
  } catch {
2846
2845
  spinner.stop("Configuration loaded (no lockfile found)");
2847
- p.note("No lockfile found. Run 'baton sync' first to create one.");
2846
+ Ve("No lockfile found. Run 'baton sync' first to create one.");
2848
2847
  }
2849
2848
  spinner.start("Checking for updates");
2850
2849
  const updateCandidates = [];
@@ -2865,14 +2864,14 @@ const updateCommand = defineCommand({
2865
2864
  });
2866
2865
  }
2867
2866
  } catch (error) {
2868
- if (error instanceof SourceParseError) p.log.warn(`Skipping invalid source: ${profile.source}`);
2867
+ if (error instanceof SourceParseError) R.warn(`Skipping invalid source: ${profile.source}`);
2869
2868
  }
2870
2869
  spinner.stop("Update check complete");
2871
2870
  if (updateCandidates.length === 0) {
2872
- p.outro("All packages are up to date!");
2871
+ Le("All packages are up to date!");
2873
2872
  process.exit(0);
2874
2873
  }
2875
- p.note(`Found ${updateCandidates.length} update${updateCandidates.length > 1 ? "s" : ""}`);
2874
+ Ve(`Found ${updateCandidates.length} update${updateCandidates.length > 1 ? "s" : ""}`);
2876
2875
  for (const candidate of updateCandidates) {
2877
2876
  console.log(`\n📦 ${candidate.name}: ${candidate.currentVersion} → ${candidate.latestVersion}`);
2878
2877
  if (candidate.changes.length > 0) {
@@ -2881,16 +2880,16 @@ const updateCommand = defineCommand({
2881
2880
  }
2882
2881
  }
2883
2882
  if (dryRun) {
2884
- p.outro("Dry-run mode enabled. No changes were made.\nRun 'baton update' without --dry-run to apply updates.");
2883
+ Le("Dry-run mode enabled. No changes were made.\nRun 'baton update' without --dry-run to apply updates.");
2885
2884
  process.exit(0);
2886
2885
  }
2887
2886
  if (!autoConfirm) {
2888
- const confirmed = await p.confirm({
2887
+ const confirmed = await Re({
2889
2888
  message: `Apply ${updateCandidates.length} update${updateCandidates.length > 1 ? "s" : ""}?`,
2890
2889
  initialValue: true
2891
2890
  });
2892
- if (p.isCancel(confirmed) || !confirmed) {
2893
- p.cancel("Update cancelled");
2891
+ if (Ct(confirmed) || !confirmed) {
2892
+ Ne("Update cancelled");
2894
2893
  process.exit(0);
2895
2894
  }
2896
2895
  }
@@ -2901,7 +2900,7 @@ const updateCommand = defineCommand({
2901
2900
  const url = parsed.provider === "github" || parsed.provider === "gitlab" ? parsed.url : parsed.provider === "git" ? parsed.url : "";
2902
2901
  if (!url) {
2903
2902
  spinner.stop("Update failed");
2904
- p.cancel(`Cannot update local source: ${candidate.name}`);
2903
+ Ne(`Cannot update local source: ${candidate.name}`);
2905
2904
  process.exit(1);
2906
2905
  }
2907
2906
  const clonedSource = await cloneGitSource({
@@ -2919,7 +2918,7 @@ const updateCommand = defineCommand({
2919
2918
  };
2920
2919
  } catch (error) {
2921
2920
  spinner.stop("Update failed");
2922
- p.cancel(`Failed to update ${candidate.name}: ${error instanceof Error ? error.message : "Unknown error"}`);
2921
+ Ne(`Failed to update ${candidate.name}: ${error instanceof Error ? error.message : "Unknown error"}`);
2923
2922
  process.exit(1);
2924
2923
  }
2925
2924
  const newLock = generateLock(updatedPackages);
@@ -2932,7 +2931,7 @@ const updateCommand = defineCommand({
2932
2931
  await writeLock(lockfile, lockfilePath);
2933
2932
  } else await writeLock(newLock, lockfilePath);
2934
2933
  spinner.stop("Updates applied successfully");
2935
- p.outro(`✅ Updated ${updateCandidates.length} package${updateCandidates.length > 1 ? "s" : ""}!\n\nRun 'baton sync' to apply the updated configurations.`);
2934
+ Le(`✅ Updated ${updateCandidates.length} package${updateCandidates.length > 1 ? "s" : ""}!\n\nRun 'baton sync' to apply the updated configurations.`);
2936
2935
  process.exit(0);
2937
2936
  }
2938
2937
  });
@@ -2958,7 +2957,7 @@ async function getChangeSummary(parsed, fromVersion, toVersion) {
2958
2957
  ref: toVersion,
2959
2958
  subpath: parsed.provider !== "local" && "subpath" in parsed ? parsed.subpath : void 0
2960
2959
  });
2961
- const simpleGit = (await import("simple-git")).default;
2960
+ const simpleGit = (await import("./esm-CuRZ1S4C.mjs")).default;
2962
2961
  return (await simpleGit(clonedSource.localPath).log({
2963
2962
  from: fromVersion,
2964
2963
  to: toVersion,