@baton-dx/cli 0.3.1 → 0.3.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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { c as Ve, h as defineCommand, i as Le, l as We, n as isInSourceRepo } from "./context-detection-DqOTnD6_.mjs";
3
- import { A as discoverProfilesInSourceRepo } from "./src-C3-Vz-R7.mjs";
3
+ import { M as discoverProfilesInSourceRepo } from "./src-BCGnnv5D.mjs";
4
4
  import "./agent-detection-DTiVeO5W.mjs";
5
5
  import "./esm-BagM-kVd.mjs";
6
6
 
@@ -53,4 +53,4 @@ Note: Must be run from a source repository (directory with baton.source.yaml)`
53
53
 
54
54
  //#endregion
55
55
  export { profileListCommand };
56
- //# sourceMappingURL=list-DmzVXCNF.mjs.map
56
+ //# sourceMappingURL=list-DSLwzhBG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-DmzVXCNF.mjs","names":[],"sources":["../src/commands/profile/list.ts"],"sourcesContent":["import { discoverProfilesInSourceRepo } from \"@baton-dx/core\";\nimport * as p from \"@clack/prompts\";\nimport { defineCommand } from \"citty\";\nimport { isInSourceRepo } from \"../../utils/context-detection.js\";\n\nexport const profileListCommand = defineCommand({\n meta: {\n name: \"profile list\",\n description: `List all profiles in the current source repository\n\nShows a table of all profiles with:\n - Profile name (root profile marked with \"(root)\")\n - Version from baton.profile.yaml\n - Description from profile manifest\n\nExamples:\n baton profile list\n\nNote: Must be run from a source repository (directory with baton.source.yaml)`,\n },\n run: async () => {\n p.intro(\"List Profiles\");\n\n // Check if we're in a source repo\n const inSourceRepo = await isInSourceRepo();\n if (!inSourceRepo) {\n p.outro(\n \"Error: Not in a source repository. Run this command from a directory containing baton.source.yaml\",\n );\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Discover all profiles in the profiles/ directory\n const profiles = await discoverProfilesInSourceRepo(cwd);\n\n if (profiles.length === 0) {\n p.outro(\"No profiles found.\");\n process.exit(0);\n }\n\n // Build table output\n const lines: string[] = [];\n lines.push(\"┌─────────────────────┬─────────┬────────────────────────────────────┐\");\n lines.push(\"│ Name │ Version │ Description │\");\n lines.push(\"├─────────────────────┼─────────┼────────────────────────────────────┤\");\n\n for (const profile of profiles) {\n const name = profile.name;\n const version = profile.version || \"-\";\n const description = profile.description || \"-\";\n\n // Pad columns to fixed width\n const namePadded = name.padEnd(19);\n const versionPadded = version.padEnd(7);\n const descPadded = description.padEnd(34);\n\n lines.push(`│ ${namePadded} │ ${versionPadded} │ ${descPadded} │`);\n }\n\n lines.push(\"└─────────────────────┴─────────┴────────────────────────────────────┘\");\n\n p.note(lines.join(\"\\n\"), \"Profiles\");\n p.outro(`Found ${profiles.length} profile${profiles.length === 1 ? \"\" : \"s\"}`);\n process.exit(0);\n },\n});\n"],"mappings":";;;;;;;AAKA,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,MAAM;EACN,aAAa;;;;;;;;;;;EAWd;CACD,KAAK,YAAY;AACf,KAAQ,gBAAgB;AAIxB,MAAI,CADiB,MAAM,gBAAgB,EACxB;AACjB,MACE,oGACD;AACD,WAAQ,KAAK,EAAE;;EAMjB,MAAM,WAAW,MAAM,6BAHX,QAAQ,KAAK,CAG+B;AAExD,MAAI,SAAS,WAAW,GAAG;AACzB,MAAQ,qBAAqB;AAC7B,WAAQ,KAAK,EAAE;;EAIjB,MAAM,QAAkB,EAAE;AAC1B,QAAM,KAAK,yEAAyE;AACpF,QAAM,KAAK,yEAAyE;AACpF,QAAM,KAAK,yEAAyE;AAEpF,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,OAAO,QAAQ;GACrB,MAAM,UAAU,QAAQ,WAAW;GACnC,MAAM,cAAc,QAAQ,eAAe;GAG3C,MAAM,aAAa,KAAK,OAAO,GAAG;GAClC,MAAM,gBAAgB,QAAQ,OAAO,EAAE;GACvC,MAAM,aAAa,YAAY,OAAO,GAAG;AAEzC,SAAM,KAAK,KAAK,WAAW,KAAK,cAAc,KAAK,WAAW,IAAI;;AAGpE,QAAM,KAAK,yEAAyE;AAEpF,KAAO,MAAM,KAAK,KAAK,EAAE,WAAW;AACpC,KAAQ,SAAS,SAAS,OAAO,UAAU,SAAS,WAAW,IAAI,KAAK,MAAM;AAC9E,UAAQ,KAAK,EAAE;;CAElB,CAAC"}
1
+ {"version":3,"file":"list-DSLwzhBG.mjs","names":[],"sources":["../src/commands/profile/list.ts"],"sourcesContent":["import { discoverProfilesInSourceRepo } from \"@baton-dx/core\";\nimport * as p from \"@clack/prompts\";\nimport { defineCommand } from \"citty\";\nimport { isInSourceRepo } from \"../../utils/context-detection.js\";\n\nexport const profileListCommand = defineCommand({\n meta: {\n name: \"profile list\",\n description: `List all profiles in the current source repository\n\nShows a table of all profiles with:\n - Profile name (root profile marked with \"(root)\")\n - Version from baton.profile.yaml\n - Description from profile manifest\n\nExamples:\n baton profile list\n\nNote: Must be run from a source repository (directory with baton.source.yaml)`,\n },\n run: async () => {\n p.intro(\"List Profiles\");\n\n // Check if we're in a source repo\n const inSourceRepo = await isInSourceRepo();\n if (!inSourceRepo) {\n p.outro(\n \"Error: Not in a source repository. Run this command from a directory containing baton.source.yaml\",\n );\n process.exit(1);\n }\n\n const cwd = process.cwd();\n\n // Discover all profiles in the profiles/ directory\n const profiles = await discoverProfilesInSourceRepo(cwd);\n\n if (profiles.length === 0) {\n p.outro(\"No profiles found.\");\n process.exit(0);\n }\n\n // Build table output\n const lines: string[] = [];\n lines.push(\"┌─────────────────────┬─────────┬────────────────────────────────────┐\");\n lines.push(\"│ Name │ Version │ Description │\");\n lines.push(\"├─────────────────────┼─────────┼────────────────────────────────────┤\");\n\n for (const profile of profiles) {\n const name = profile.name;\n const version = profile.version || \"-\";\n const description = profile.description || \"-\";\n\n // Pad columns to fixed width\n const namePadded = name.padEnd(19);\n const versionPadded = version.padEnd(7);\n const descPadded = description.padEnd(34);\n\n lines.push(`│ ${namePadded} │ ${versionPadded} │ ${descPadded} │`);\n }\n\n lines.push(\"└─────────────────────┴─────────┴────────────────────────────────────┘\");\n\n p.note(lines.join(\"\\n\"), \"Profiles\");\n p.outro(`Found ${profiles.length} profile${profiles.length === 1 ? \"\" : \"s\"}`);\n process.exit(0);\n },\n});\n"],"mappings":";;;;;;;AAKA,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,MAAM;EACN,aAAa;;;;;;;;;;;EAWd;CACD,KAAK,YAAY;AACf,KAAQ,gBAAgB;AAIxB,MAAI,CADiB,MAAM,gBAAgB,EACxB;AACjB,MACE,oGACD;AACD,WAAQ,KAAK,EAAE;;EAMjB,MAAM,WAAW,MAAM,6BAHX,QAAQ,KAAK,CAG+B;AAExD,MAAI,SAAS,WAAW,GAAG;AACzB,MAAQ,qBAAqB;AAC7B,WAAQ,KAAK,EAAE;;EAIjB,MAAM,QAAkB,EAAE;AAC1B,QAAM,KAAK,yEAAyE;AACpF,QAAM,KAAK,yEAAyE;AACpF,QAAM,KAAK,yEAAyE;AAEpF,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,OAAO,QAAQ;GACrB,MAAM,UAAU,QAAQ,WAAW;GACnC,MAAM,cAAc,QAAQ,eAAe;GAG3C,MAAM,aAAa,KAAK,OAAO,GAAG;GAClC,MAAM,gBAAgB,QAAQ,OAAO,EAAE;GACvC,MAAM,aAAa,YAAY,OAAO,GAAG;AAEzC,SAAM,KAAK,KAAK,WAAW,KAAK,cAAc,KAAK,WAAW,IAAI;;AAGpE,QAAM,KAAK,yEAAyE;AAEpF,KAAO,MAAM,KAAK,KAAK,EAAE,WAAW;AACpC,KAAQ,SAAS,SAAS,OAAO,UAAU,SAAS,WAAW,IAAI,KAAK,MAAM;AAC9E,UAAQ,KAAK,EAAE;;CAElB,CAAC"}
@@ -3874,7 +3874,8 @@ const projectManifestSchema = objectType({
3874
3874
  profiles: arrayType(profileSourceSchema),
3875
3875
  extras: extrasSectionSchema,
3876
3876
  overrides: overridesSectionSchema,
3877
- variables: recordType(stringType(), stringType()).optional()
3877
+ variables: recordType(stringType(), stringType()).optional(),
3878
+ gitignore: booleanType().optional()
3878
3879
  });
3879
3880
 
3880
3881
  //#endregion
@@ -4665,56 +4666,29 @@ function getRegisteredIdePlatforms() {
4665
4666
  //#endregion
4666
4667
  //#region ../core/src/utils/gitignore.ts
4667
4668
  /**
4668
- * Collect gitignore patterns from the profile's declared tool support.
4669
- *
4670
- * Unlike collectSyncedPatterns (which uses the developer's intersection),
4671
- * this function generates patterns for ALL tools the profile supports.
4672
- * This ensures consistent .gitignore across all team members regardless
4673
- * of which tools each developer has installed.
4669
+ * Extract directory from a dynamic path and add it as a pattern.
4670
+ * For static paths (no `_probe` placeholder resolved), adds the file itself.
4674
4671
  *
4675
- * Returns deduplicated, sorted patterns including baton.lock.
4676
- */
4677
- function collectProfileSupportPatterns(options) {
4678
- const patterns = /* @__PURE__ */ new Set();
4679
- const { profileAiTools, profileIdePlatforms, fileTargets, hasContent } = options;
4680
- if (profileAiTools.length > 0 && hasContent) {
4681
- const adapters = getAdaptersForKeys(profileAiTools);
4682
- for (const adapter of adapters) {
4683
- addDirPattern(patterns, adapter.getPath("commands", "project", "_probe"));
4684
- addDirPattern(patterns, adapter.getPath("skills", "project", "_probe"));
4685
- addPathPattern(patterns, adapter.getPath("rules", "project", "_probe"));
4686
- addPathPattern(patterns, adapter.getPath("memory", "project", "_probe"));
4687
- addDirPattern(patterns, adapter.getPath("agents", "project", "_probe"));
4688
- for (const legacyPath of adapter.getLegacyPaths("rules")) patterns.add(legacyPath);
4689
- }
4690
- }
4691
- for (const ideKey of profileIdePlatforms) {
4692
- const targetDir = getIdePlatformTargetDir(ideKey);
4693
- if (targetDir) {
4694
- const dir = targetDir.endsWith("/") ? targetDir : `${targetDir}/`;
4695
- patterns.add(dir);
4696
- }
4697
- }
4698
- for (const target of fileTargets) patterns.add(target);
4699
- patterns.add("baton.lock");
4700
- return [...patterns].sort();
4701
- }
4702
- /**
4703
- * Extract directory from a path and add it as a pattern.
4704
- * E.g. ".claude/commands/_probe.md" -> ".claude/commands/"
4672
+ * E.g. ".claude/commands/_probe.md" -> ".claude/commands/" (dynamic)
4673
+ * E.g. ".github/copilot-instructions.md" -> ".github/copilot-instructions.md" (static)
4705
4674
  */
4706
4675
  function addDirPattern(patterns, path) {
4707
4676
  const lastSlash = path.lastIndexOf("/");
4708
- if (lastSlash > 0) patterns.add(path.substring(0, lastSlash + 1));
4677
+ if (lastSlash > 0) if (path.includes("_probe")) patterns.add(path.substring(0, lastSlash + 1));
4678
+ else patterns.add(path);
4709
4679
  }
4710
4680
  /**
4711
- * Add a path pattern directory if it contains slashes, root file otherwise.
4712
- * E.g. ".claude/rules/_probe.md" -> ".claude/rules/"
4713
- * E.g. "CLAUDE.md" -> "CLAUDE.md"
4681
+ * Add a path pattern. Dynamic paths (containing `_probe`) are reduced to their
4682
+ * directory; static paths and root-level files are added as-is.
4683
+ *
4684
+ * E.g. ".claude/rules/_probe.md" -> ".claude/rules/" (dynamic)
4685
+ * E.g. ".github/copilot-instructions.md" -> ".github/copilot-instructions.md" (static)
4686
+ * E.g. "CLAUDE.md" -> "CLAUDE.md" (root file)
4714
4687
  */
4715
4688
  function addPathPattern(patterns, path) {
4716
4689
  const lastSlash = path.lastIndexOf("/");
4717
- if (lastSlash > 0) patterns.add(path.substring(0, lastSlash + 1));
4690
+ if (lastSlash > 0) if (path.includes("_probe")) patterns.add(path.substring(0, lastSlash + 1));
4691
+ else patterns.add(path);
4718
4692
  else if (path) patterns.add(path);
4719
4693
  }
4720
4694
  /**
@@ -4758,6 +4732,62 @@ async function updateGitignore(projectRoot, patterns) {
4758
4732
  await writeFile(gitignorePath, newContent, "utf-8");
4759
4733
  return true;
4760
4734
  }
4735
+ /**
4736
+ * Remove the "# Baton managed ... # End Baton managed" section from .gitignore.
4737
+ *
4738
+ * Used when the project has `gitignore: false` to clean up any previously
4739
+ * written managed section.
4740
+ *
4741
+ * @returns true if a section was removed, false if none existed
4742
+ */
4743
+ async function removeGitignoreManagedSection(projectRoot) {
4744
+ const gitignorePath = join(projectRoot, ".gitignore");
4745
+ let content = "";
4746
+ try {
4747
+ content = await readFile(gitignorePath, "utf-8");
4748
+ } catch {
4749
+ return false;
4750
+ }
4751
+ const startIdx = content.indexOf(BATON_SECTION_START);
4752
+ const endIdx = content.indexOf(BATON_SECTION_END);
4753
+ if (startIdx === -1 || endIdx === -1) return false;
4754
+ const newContent = (content.substring(0, startIdx).replace(/\n+$/, "\n") + content.substring(endIdx + 19).replace(/^\n+/, "\n")).trim();
4755
+ await writeFile(gitignorePath, newContent ? `${newContent}\n` : "", "utf-8");
4756
+ return true;
4757
+ }
4758
+ /**
4759
+ * Collect comprehensive gitignore patterns for ALL known AI tools and IDE platforms.
4760
+ *
4761
+ * Generates patterns for the entire tool and IDE registry, ensuring stable,
4762
+ * predictable .gitignore content regardless of which tools a profile supports
4763
+ * or a developer has installed.
4764
+ *
4765
+ * Returns deduplicated, sorted patterns including baton.lock.
4766
+ */
4767
+ function collectComprehensivePatterns(options) {
4768
+ const patterns = /* @__PURE__ */ new Set();
4769
+ const { fileTargets } = options;
4770
+ const allAdapters = getAllAdapters();
4771
+ for (const adapter of allAdapters) {
4772
+ addDirPattern(patterns, adapter.getPath("commands", "project", "_probe"));
4773
+ addDirPattern(patterns, adapter.getPath("skills", "project", "_probe"));
4774
+ addPathPattern(patterns, adapter.getPath("rules", "project", "_probe"));
4775
+ addPathPattern(patterns, adapter.getPath("memory", "project", "_probe"));
4776
+ addDirPattern(patterns, adapter.getPath("agents", "project", "_probe"));
4777
+ for (const legacyPath of adapter.getLegacyPaths("rules")) patterns.add(legacyPath);
4778
+ }
4779
+ const allIdePlatforms = getRegisteredIdePlatforms();
4780
+ for (const ideKey of allIdePlatforms) {
4781
+ const targetDir = getIdePlatformTargetDir(ideKey);
4782
+ if (targetDir) {
4783
+ const dir = targetDir.endsWith("/") ? targetDir : `${targetDir}/`;
4784
+ patterns.add(dir);
4785
+ }
4786
+ }
4787
+ for (const target of fileTargets) patterns.add(target);
4788
+ patterns.add("baton.lock");
4789
+ return [...patterns].sort();
4790
+ }
4761
4791
 
4762
4792
  //#endregion
4763
4793
  //#region ../core/src/sources/git-clone.ts
@@ -14321,12 +14351,23 @@ const globalConfigSchema = objectType({
14321
14351
  //#endregion
14322
14352
  //#region ../core/src/config/global-config.ts
14323
14353
  /**
14354
+ * Returns the Baton home directory path.
14355
+ *
14356
+ * Respects the `BATON_HOME` environment variable for testing and custom locations.
14357
+ * Falls back to `~/.baton` when not set.
14358
+ *
14359
+ * @returns Absolute path to the Baton home directory
14360
+ */
14361
+ function getBatonHome() {
14362
+ return process.env.BATON_HOME ?? join(homedir(), ".baton");
14363
+ }
14364
+ /**
14324
14365
  * Returns the path to the global Baton configuration file.
14325
14366
  *
14326
- * @returns Absolute path to ~/.baton/config.yaml
14367
+ * @returns Absolute path to ~/.baton/config.yaml (or $BATON_HOME/config.yaml)
14327
14368
  */
14328
14369
  function getGlobalConfigPath() {
14329
- return join(homedir(), ".baton", "config.yaml");
14370
+ return join(getBatonHome(), "config.yaml");
14330
14371
  }
14331
14372
  /**
14332
14373
  * Loads the global Baton configuration from ~/.baton/config.yaml
@@ -14359,7 +14400,7 @@ async function loadGlobalConfig() {
14359
14400
  async function saveGlobalConfig(config) {
14360
14401
  const validated = globalConfigSchema.parse(config);
14361
14402
  const configPath = getGlobalConfigPath();
14362
- await mkdir(join(homedir(), ".baton"), { recursive: true });
14403
+ await mkdir(getBatonHome(), { recursive: true });
14363
14404
  await writeFile(configPath, (0, import_dist.stringify)(validated), "utf-8");
14364
14405
  }
14365
14406
  /**
@@ -14681,5 +14722,5 @@ async function resolvePreferences(projectRoot) {
14681
14722
  }
14682
14723
 
14683
14724
  //#endregion
14684
- export { SourceParseError as $, discoverProfilesInSourceRepo as A, getIdePlatformTargetDir as B, isLockedProfile as C, resolveProfileChain as D, resolveProfileSupport as E, writeLock as F, getAllAdapters as G, idePlatformRegistry as H, resolveVersion as I, loadLockfile as J, parseFrontmatter as K, cloneGitSource as L, removePlacedFiles as M, generateLock as N, detectLegacyPaths as O, readLock as P, FileNotFoundError as Q, collectProfileSupportPatterns as R, getProfileWeight as S, mergeContentParts as T, isKnownIdePlatform as U, getRegisteredIdePlatforms as V, getAdaptersForKeys as W, loadProjectManifest as X, loadProfileManifest as Y, KEBAB_CASE_REGEX as Z, mergeMemoryWithWarnings as _, clearIdeCache as a, mergeSkills as b, getDefaultGlobalSource as c, getGlobalSources as d, getAgentConfig as et, removeGlobalSource as f, mergeMemory as g, require_lib as h, computeIntersection as i, findSourceManifest as j, placeFile as k, getGlobalAiTools as l, setGlobalIdePlatforms as m, readProjectPreferences as n, getAllAgentKeys as nt, detectInstalledIdes as o, setGlobalAiTools as p, parseSource as q, writeProjectPreferences as r, addGlobalSource as s, resolvePreferences as t, getAgentPath as tt, getGlobalIdePlatforms as u, mergeRules as v, sortProfilesByWeight as w, mergeSkillsWithWarnings as x, mergeRulesWithWarnings as y, updateGitignore as z };
14685
- //# sourceMappingURL=src-C3-Vz-R7.mjs.map
14725
+ export { loadProfileManifest as $, detectLegacyPaths as A, collectComprehensivePatterns as B, mergeSkillsWithWarnings as C, mergeContentParts as D, sortProfilesByWeight as E, generateLock as F, getRegisteredIdePlatforms as G, removeGitignoreManagedSection as H, readLock as I, getAdaptersForKeys as J, idePlatformRegistry as K, writeLock as L, discoverProfilesInSourceRepo as M, findSourceManifest as N, resolveProfileSupport as O, removePlacedFiles as P, loadLockfile as Q, resolveVersion as R, mergeSkills as S, isLockedProfile as T, updateGitignore as U, ensureBatonDirGitignored as V, getIdePlatformTargetDir as W, parseFrontmatter as X, getAllAdapters as Y, parseSource as Z, require_lib as _, clearIdeCache as a, getAgentPath as at, mergeRules as b, getBatonHome as c, getGlobalConfigPath as d, loadProjectManifest as et, getGlobalIdePlatforms as f, setGlobalIdePlatforms as g, setGlobalAiTools as h, computeIntersection as i, getAgentConfig as it, placeFile as j, resolveProfileChain as k, getDefaultGlobalSource as l, removeGlobalSource as m, readProjectPreferences as n, FileNotFoundError as nt, detectInstalledIdes as o, getAllAgentKeys as ot, getGlobalSources as p, isKnownIdePlatform as q, writeProjectPreferences as r, SourceParseError as rt, addGlobalSource as s, resolvePreferences as t, KEBAB_CASE_REGEX as tt, getGlobalAiTools as u, mergeMemory as v, getProfileWeight as w, mergeRulesWithWarnings as x, mergeMemoryWithWarnings as y, cloneGitSource as z };
14726
+ //# sourceMappingURL=src-BCGnnv5D.mjs.map