@baton-dx/cli 0.3.0 → 0.3.1
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/{create-BG_VVOTI.mjs → create-BOcW-DBk.mjs} +2 -2
- package/dist/{create-BG_VVOTI.mjs.map → create-BOcW-DBk.mjs.map} +1 -1
- package/dist/index.mjs +33 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{list-CCzjta6J.mjs → list-DmzVXCNF.mjs} +2 -2
- package/dist/{list-CCzjta6J.mjs.map → list-DmzVXCNF.mjs.map} +1 -1
- package/dist/{src-BgiJfm14.mjs → src-C3-Vz-R7.mjs} +44 -3
- package/dist/src-C3-Vz-R7.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/src-BgiJfm14.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { r as __toESM } from "./chunk-BbwQpWto.mjs";
|
|
3
3
|
import { a as Ne, h as defineCommand, i as Le, l as We, p as Ct, t as findSourceRoot, u as Ze } from "./context-detection-DqOTnD6_.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { Z as KEBAB_CASE_REGEX, h as require_lib } from "./src-C3-Vz-R7.mjs";
|
|
5
5
|
import "./agent-detection-DTiVeO5W.mjs";
|
|
6
6
|
import "./esm-BagM-kVd.mjs";
|
|
7
7
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
@@ -79,4 +79,4 @@ async function copyProfileTemplate(sourceDir, targetDir, variables) {
|
|
|
79
79
|
|
|
80
80
|
//#endregion
|
|
81
81
|
export { createCommand };
|
|
82
|
-
//# sourceMappingURL=create-
|
|
82
|
+
//# sourceMappingURL=create-BOcW-DBk.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-
|
|
1
|
+
{"version":3,"file":"create-BOcW-DBk.mjs","names":["p.text","p.isCancel","Handlebars"],"sources":["../src/commands/profile/create.ts"],"sourcesContent":["import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { KEBAB_CASE_REGEX } from \"@baton-dx/core\";\nimport * as p from \"@clack/prompts\";\nimport { defineCommand } from \"citty\";\nimport Handlebars from \"handlebars\";\nimport { findSourceRoot } from \"../../utils/context-detection.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const createCommand = defineCommand({\n meta: {\n name: \"create\",\n description: \"Create a new profile in your source repository\",\n },\n args: {\n name: {\n type: \"positional\",\n description: \"Profile name (kebab-case)\",\n required: false,\n },\n },\n async run({ args }) {\n p.intro(\"Create Profile\");\n\n // Check for baton.source.yaml in current or parent directories\n const sourceRoot = await findSourceRoot();\n if (!sourceRoot) {\n p.cancel(\"This command must be run inside a source directory (baton.source.yaml not found)\");\n process.exit(1);\n }\n\n // Get profile name — from argument or wizard prompt\n let name = args.name as string | undefined;\n\n if (!name) {\n const nameInput = await p.text({\n message: \"Profile name (kebab-case)\",\n placeholder: \"e.g., backend, frontend, my-profile\",\n validate(value) {\n if (!value || value.trim().length === 0) {\n return \"Profile name is required\";\n }\n if (!KEBAB_CASE_REGEX.test(value.trim())) {\n return \"Profile name must be in kebab-case (e.g., my-profile, backend, frontend)\";\n }\n },\n });\n\n if (p.isCancel(nameInput)) {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n }\n\n name = (nameInput as string).trim();\n }\n\n // Validate name format (kebab-case)\n if (!KEBAB_CASE_REGEX.test(name)) {\n p.cancel(\"Profile name must be in kebab-case (e.g., my-profile, backend, frontend)\");\n process.exit(1);\n }\n\n // Check if profile already exists in profiles/ directory\n const targetDir = join(sourceRoot, \"profiles\", name);\n try {\n await readdir(targetDir);\n p.cancel(`Profile '${name}' already exists in profiles/${name}/`);\n process.exit(1);\n } catch {\n // Directory doesn't exist - good to proceed\n }\n\n // Create profile directory\n await mkdir(targetDir, { recursive: true });\n\n // Copy minimal template files\n const templateDir = join(__dirname, \"templates\", \"profile\", \"minimal\");\n await copyProfileTemplate(templateDir, targetDir, { name });\n\n p.outro(`Profile '${name}' created in profiles/${name}/`);\n },\n});\n\n/**\n * Recursively copy profile template with variable substitution\n */\nasync function copyProfileTemplate(\n sourceDir: string,\n targetDir: string,\n variables: { name: string },\n): Promise<void> {\n const entries = await readdir(sourceDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const sourcePath = join(sourceDir, entry.name);\n const targetPath = join(targetDir, entry.name);\n\n if (entry.isDirectory()) {\n await mkdir(targetPath, { recursive: true });\n await copyProfileTemplate(sourcePath, targetPath, variables);\n } else {\n // Read file content\n const content = await readFile(sourcePath, \"utf-8\");\n\n // Apply Handlebars substitution for text files\n const processed = Handlebars.compile(content, { noEscape: true })(variables);\n\n // Write processed content\n await writeFile(targetPath, processed, \"utf-8\");\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AASA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEzD,MAAa,gBAAgB,cAAc;CACzC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,EACJ,MAAM;EACJ,MAAM;EACN,aAAa;EACb,UAAU;EACX,EACF;CACD,MAAM,IAAI,EAAE,QAAQ;AAClB,KAAQ,iBAAiB;EAGzB,MAAM,aAAa,MAAM,gBAAgB;AACzC,MAAI,CAAC,YAAY;AACf,MAAS,mFAAmF;AAC5F,WAAQ,KAAK,EAAE;;EAIjB,IAAI,OAAO,KAAK;AAEhB,MAAI,CAAC,MAAM;GACT,MAAM,YAAY,MAAMA,GAAO;IAC7B,SAAS;IACT,aAAa;IACb,SAAS,OAAO;AACd,SAAI,CAAC,SAAS,MAAM,MAAM,CAAC,WAAW,EACpC,QAAO;AAET,SAAI,CAAC,iBAAiB,KAAK,MAAM,MAAM,CAAC,CACtC,QAAO;;IAGZ,CAAC;AAEF,OAAIC,GAAW,UAAU,EAAE;AACzB,OAAS,aAAa;AACtB,YAAQ,KAAK,EAAE;;AAGjB,UAAQ,UAAqB,MAAM;;AAIrC,MAAI,CAAC,iBAAiB,KAAK,KAAK,EAAE;AAChC,MAAS,2EAA2E;AACpF,WAAQ,KAAK,EAAE;;EAIjB,MAAM,YAAY,KAAK,YAAY,YAAY,KAAK;AACpD,MAAI;AACF,SAAM,QAAQ,UAAU;AACxB,MAAS,YAAY,KAAK,+BAA+B,KAAK,GAAG;AACjE,WAAQ,KAAK,EAAE;UACT;AAKR,QAAM,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;AAI3C,QAAM,oBADc,KAAK,WAAW,aAAa,WAAW,UAAU,EAC/B,WAAW,EAAE,MAAM,CAAC;AAE3D,KAAQ,YAAY,KAAK,wBAAwB,KAAK,GAAG;;CAE5D,CAAC;;;;AAKF,eAAe,oBACb,WACA,WACA,WACe;CACf,MAAM,UAAU,MAAM,QAAQ,WAAW,EAAE,eAAe,MAAM,CAAC;AAEjE,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,aAAa,KAAK,WAAW,MAAM,KAAK;EAC9C,MAAM,aAAa,KAAK,WAAW,MAAM,KAAK;AAE9C,MAAI,MAAM,aAAa,EAAE;AACvB,SAAM,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;AAC5C,SAAM,oBAAoB,YAAY,YAAY,UAAU;SACvD;GAEL,MAAM,UAAU,MAAM,SAAS,YAAY,QAAQ;AAMnD,SAAM,UAAU,YAHEC,mBAAW,QAAQ,SAAS,EAAE,UAAU,MAAM,CAAC,CAAC,UAAU,EAGrC,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { r as __toESM } from "./chunk-BbwQpWto.mjs";
|
|
3
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-DqOTnD6_.mjs";
|
|
4
|
-
import { $ as
|
|
4
|
+
import { $ as SourceParseError, A as discoverProfilesInSourceRepo, B as getIdePlatformTargetDir, C as isLockedProfile, D as resolveProfileChain, E as resolveProfileSupport, F as writeLock, G as getAllAdapters, H as idePlatformRegistry, I as resolveVersion, J as loadLockfile, K as parseFrontmatter, L as cloneGitSource, M as removePlacedFiles, N as generateLock, O as detectLegacyPaths, P as readLock, Q as FileNotFoundError, R as collectProfileSupportPatterns, S as getProfileWeight, T as mergeContentParts, U as isKnownIdePlatform, V as getRegisteredIdePlatforms, W as getAdaptersForKeys, X as loadProjectManifest, Y as loadProfileManifest, Z as KEBAB_CASE_REGEX, _ as mergeMemoryWithWarnings, a as clearIdeCache, b as mergeSkills, c as getDefaultGlobalSource, d as getGlobalSources, et as getAgentConfig, f as removeGlobalSource, g as mergeMemory, h as require_lib, i as computeIntersection, j as findSourceManifest, k as placeFile, l as getGlobalAiTools, m as setGlobalIdePlatforms, n as readProjectPreferences, nt as getAllAgentKeys, o as detectInstalledIdes, p as setGlobalAiTools, q as parseSource, r as writeProjectPreferences, s as addGlobalSource, t as resolvePreferences, tt as getAgentPath, u as getGlobalIdePlatforms, v as mergeRules, w as sortProfilesByWeight, x as mergeSkillsWithWarnings, y as mergeRulesWithWarnings, z as updateGitignore } from "./src-C3-Vz-R7.mjs";
|
|
5
5
|
import { n as detectInstalledAgents, t as clearAgentCache } from "./agent-detection-DTiVeO5W.mjs";
|
|
6
6
|
import { d as esm_default } from "./esm-BagM-kVd.mjs";
|
|
7
|
-
import { access, mkdir, readFile, readdir, rm,
|
|
8
|
-
import { dirname, join, resolve } from "node:path";
|
|
7
|
+
import { access, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
8
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
|
|
@@ -1965,13 +1965,33 @@ async function handleRemoveBaton(cwd) {
|
|
|
1965
1965
|
R.warn("Cancelled.");
|
|
1966
1966
|
return false;
|
|
1967
1967
|
}
|
|
1968
|
+
const lockPath = join(cwd, "baton.lock");
|
|
1969
|
+
await cleanupPlacedFilesFromLock(lockPath, cwd);
|
|
1968
1970
|
await rm(join(cwd, "baton.yaml"), { force: true });
|
|
1969
|
-
await rm(
|
|
1971
|
+
await rm(lockPath, { force: true });
|
|
1970
1972
|
R.success("Baton has been removed from this project.");
|
|
1971
|
-
R.info("Note: Synced files (rules, skills, memory) were not removed.");
|
|
1972
|
-
R.info("Run 'baton sync' before removing to clean up, or delete them manually.");
|
|
1973
1973
|
return true;
|
|
1974
1974
|
}
|
|
1975
|
+
async function cleanupPlacedFilesFromLock(lockPath, projectRoot) {
|
|
1976
|
+
let placedPaths;
|
|
1977
|
+
try {
|
|
1978
|
+
const lockfile = await readLock(lockPath);
|
|
1979
|
+
placedPaths = Object.values(lockfile.packages).flatMap((pkg) => Object.keys(pkg.integrity));
|
|
1980
|
+
} catch (error) {
|
|
1981
|
+
if (error instanceof FileNotFoundError) return;
|
|
1982
|
+
return;
|
|
1983
|
+
}
|
|
1984
|
+
if (placedPaths.length === 0) return;
|
|
1985
|
+
R.info(`Found ${placedPaths.length} placed file(s):`);
|
|
1986
|
+
for (const filePath of placedPaths) R.info(` ${filePath}`);
|
|
1987
|
+
const shouldClean = await Re({
|
|
1988
|
+
message: `Also remove ${placedPaths.length} placed file(s)?`,
|
|
1989
|
+
initialValue: false
|
|
1990
|
+
});
|
|
1991
|
+
if (Ct(shouldClean) || !shouldClean) return;
|
|
1992
|
+
const removedCount = await removePlacedFiles(placedPaths, projectRoot);
|
|
1993
|
+
R.success(`Removed ${removedCount} placed file(s).`);
|
|
1994
|
+
}
|
|
1975
1995
|
function formatIdeName(ideKey) {
|
|
1976
1996
|
return {
|
|
1977
1997
|
vscode: "VS Code",
|
|
@@ -2209,8 +2229,8 @@ const profileCommand = defineCommand({
|
|
|
2209
2229
|
description: "Manage profiles (create, list, remove)"
|
|
2210
2230
|
},
|
|
2211
2231
|
subCommands: {
|
|
2212
|
-
create: () => import("./create-
|
|
2213
|
-
list: () => import("./list-
|
|
2232
|
+
create: () => import("./create-BOcW-DBk.mjs").then((m) => m.createCommand),
|
|
2233
|
+
list: () => import("./list-DmzVXCNF.mjs").then((m) => m.profileListCommand),
|
|
2214
2234
|
remove: () => import("./remove-BBs6Mv8t.mjs").then((m) => m.profileRemoveCommand)
|
|
2215
2235
|
}
|
|
2216
2236
|
});
|
|
@@ -2750,23 +2770,7 @@ async function cleanupOrphanedFiles(params) {
|
|
|
2750
2770
|
return;
|
|
2751
2771
|
}
|
|
2752
2772
|
spinner.start("Removing orphaned files...");
|
|
2753
|
-
|
|
2754
|
-
for (const orphanedPath of orphanedPaths) {
|
|
2755
|
-
const absolutePath = orphanedPath.startsWith("/") ? orphanedPath : resolve(projectRoot, orphanedPath);
|
|
2756
|
-
try {
|
|
2757
|
-
await unlink(absolutePath);
|
|
2758
|
-
removedCount++;
|
|
2759
|
-
let dir = dirname(absolutePath);
|
|
2760
|
-
while (dir !== projectRoot && dir.startsWith(projectRoot)) try {
|
|
2761
|
-
if ((await readdir(dir)).length === 0) {
|
|
2762
|
-
await rmdir(dir);
|
|
2763
|
-
dir = dirname(dir);
|
|
2764
|
-
} else break;
|
|
2765
|
-
} catch {
|
|
2766
|
-
break;
|
|
2767
|
-
}
|
|
2768
|
-
} catch {}
|
|
2769
|
-
}
|
|
2773
|
+
const removedCount = await removePlacedFiles(orphanedPaths, projectRoot);
|
|
2770
2774
|
spinner.stop(`Removed ${removedCount} orphaned file(s)`);
|
|
2771
2775
|
}
|
|
2772
2776
|
const syncCommand = defineCommand({
|
|
@@ -3214,9 +3218,10 @@ const syncCommand = defineCommand({
|
|
|
3214
3218
|
const combinedContent = entry.parts.join("\n\n");
|
|
3215
3219
|
const result = await placeFile(combinedContent, entry.adapter, entry.type, "project", entry.name, placementConfig);
|
|
3216
3220
|
if (result.action !== "skipped") stats.created++;
|
|
3221
|
+
const relPath = isAbsolute(result.path) ? relative(projectRoot, result.path) : result.path;
|
|
3217
3222
|
for (const profileName of entry.profiles) {
|
|
3218
3223
|
const pf = getOrCreatePlacedFiles(placedFiles, profileName);
|
|
3219
|
-
pf[
|
|
3224
|
+
pf[relPath] = {
|
|
3220
3225
|
content: combinedContent,
|
|
3221
3226
|
tool: entry.adapter.key,
|
|
3222
3227
|
category: "ai"
|
|
@@ -3246,8 +3251,9 @@ const syncCommand = defineCommand({
|
|
|
3246
3251
|
}
|
|
3247
3252
|
const result = await placeFile(content, adapter, "commands", "project", commandName, placementConfig);
|
|
3248
3253
|
if (result.action !== "skipped") stats.created++;
|
|
3254
|
+
const cmdRelPath = isAbsolute(result.path) ? relative(projectRoot, result.path) : result.path;
|
|
3249
3255
|
const pf = getOrCreatePlacedFiles(placedFiles, profile.name);
|
|
3250
|
-
pf[
|
|
3256
|
+
pf[cmdRelPath] = {
|
|
3251
3257
|
content,
|
|
3252
3258
|
tool: adapter.key,
|
|
3253
3259
|
category: "ai"
|