@caliber-ai/cli 0.14.0 → 0.14.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/bin.js +79 -83
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1185,20 +1185,8 @@ function writeClaudeConfig(config) {
|
|
|
1185
1185
|
const written = [];
|
|
1186
1186
|
fs9.writeFileSync("CLAUDE.md", config.claudeMd);
|
|
1187
1187
|
written.push("CLAUDE.md");
|
|
1188
|
-
const claudeDir = ".claude";
|
|
1189
|
-
if (!fs9.existsSync(claudeDir)) fs9.mkdirSync(claudeDir, { recursive: true });
|
|
1190
|
-
fs9.writeFileSync(
|
|
1191
|
-
path10.join(claudeDir, "settings.json"),
|
|
1192
|
-
JSON.stringify(config.settings, null, 2)
|
|
1193
|
-
);
|
|
1194
|
-
written.push(path10.join(claudeDir, "settings.json"));
|
|
1195
|
-
fs9.writeFileSync(
|
|
1196
|
-
path10.join(claudeDir, "settings.local.json"),
|
|
1197
|
-
JSON.stringify(config.settingsLocal, null, 2)
|
|
1198
|
-
);
|
|
1199
|
-
written.push(path10.join(claudeDir, "settings.local.json"));
|
|
1200
1188
|
if (config.skills?.length) {
|
|
1201
|
-
const skillsDir = path10.join(
|
|
1189
|
+
const skillsDir = path10.join(".claude", "skills");
|
|
1202
1190
|
if (!fs9.existsSync(skillsDir)) fs9.mkdirSync(skillsDir, { recursive: true });
|
|
1203
1191
|
for (const skill of config.skills) {
|
|
1204
1192
|
const filename = `${skill.name.replace(/[^a-z0-9-]/gi, "-").toLowerCase()}.md`;
|
|
@@ -1212,9 +1200,7 @@ function writeClaudeConfig(config) {
|
|
|
1212
1200
|
try {
|
|
1213
1201
|
if (fs9.existsSync(".mcp.json")) {
|
|
1214
1202
|
const existing = JSON.parse(fs9.readFileSync(".mcp.json", "utf-8"));
|
|
1215
|
-
if (existing.mcpServers)
|
|
1216
|
-
existingServers = existing.mcpServers;
|
|
1217
|
-
}
|
|
1203
|
+
if (existing.mcpServers) existingServers = existing.mcpServers;
|
|
1218
1204
|
}
|
|
1219
1205
|
} catch {
|
|
1220
1206
|
}
|
|
@@ -1319,7 +1305,11 @@ function fileChecksum(filePath) {
|
|
|
1319
1305
|
// src/writers/index.ts
|
|
1320
1306
|
function writeSetup(setup) {
|
|
1321
1307
|
const filesToWrite = getFilesToWrite(setup);
|
|
1322
|
-
const
|
|
1308
|
+
const filesToDelete = (setup.deletions || []).map((d) => d.filePath).filter((f) => fs13.existsSync(f));
|
|
1309
|
+
const existingFiles = [
|
|
1310
|
+
...filesToWrite.filter((f) => fs13.existsSync(f)),
|
|
1311
|
+
...filesToDelete
|
|
1312
|
+
];
|
|
1323
1313
|
const backupDir = existingFiles.length > 0 ? createBackup(existingFiles) : void 0;
|
|
1324
1314
|
const written = [];
|
|
1325
1315
|
if ((setup.targetAgent === "claude" || setup.targetAgent === "both") && setup.claude) {
|
|
@@ -1328,15 +1318,28 @@ function writeSetup(setup) {
|
|
|
1328
1318
|
if ((setup.targetAgent === "cursor" || setup.targetAgent === "both") && setup.cursor) {
|
|
1329
1319
|
written.push(...writeCursorConfig(setup.cursor));
|
|
1330
1320
|
}
|
|
1321
|
+
const deleted = [];
|
|
1322
|
+
for (const filePath of filesToDelete) {
|
|
1323
|
+
fs13.unlinkSync(filePath);
|
|
1324
|
+
deleted.push(filePath);
|
|
1325
|
+
}
|
|
1331
1326
|
ensureGitignore();
|
|
1332
|
-
const entries =
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1327
|
+
const entries = [
|
|
1328
|
+
...written.map((file) => ({
|
|
1329
|
+
path: file,
|
|
1330
|
+
action: existingFiles.includes(file) ? "modified" : "created",
|
|
1331
|
+
checksum: fileChecksum(file),
|
|
1332
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1333
|
+
})),
|
|
1334
|
+
...deleted.map((file) => ({
|
|
1335
|
+
path: file,
|
|
1336
|
+
action: "deleted",
|
|
1337
|
+
checksum: "",
|
|
1338
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1339
|
+
}))
|
|
1340
|
+
];
|
|
1338
1341
|
writeManifest({ version: 1, backupDir, entries });
|
|
1339
|
-
return { written, backupDir };
|
|
1342
|
+
return { written, deleted, backupDir };
|
|
1340
1343
|
}
|
|
1341
1344
|
function undoSetup() {
|
|
1342
1345
|
const manifest = readManifest();
|
|
@@ -1351,7 +1354,7 @@ function undoSetup() {
|
|
|
1351
1354
|
fs13.unlinkSync(entry.path);
|
|
1352
1355
|
removed.push(entry.path);
|
|
1353
1356
|
}
|
|
1354
|
-
} else if (entry.action === "modified" && manifest.backupDir) {
|
|
1357
|
+
} else if ((entry.action === "modified" || entry.action === "deleted") && manifest.backupDir) {
|
|
1355
1358
|
if (restoreBackup(manifest.backupDir, entry.path)) {
|
|
1356
1359
|
restored.push(entry.path);
|
|
1357
1360
|
}
|
|
@@ -1366,7 +1369,7 @@ function undoSetup() {
|
|
|
1366
1369
|
function getFilesToWrite(setup) {
|
|
1367
1370
|
const files = [];
|
|
1368
1371
|
if ((setup.targetAgent === "claude" || setup.targetAgent === "both") && setup.claude) {
|
|
1369
|
-
files.push("CLAUDE.md"
|
|
1372
|
+
files.push("CLAUDE.md");
|
|
1370
1373
|
if (setup.claude.mcpServers) files.push(".mcp.json");
|
|
1371
1374
|
if (setup.claude.skills) {
|
|
1372
1375
|
for (const s of setup.claude.skills) {
|
|
@@ -1582,10 +1585,10 @@ async function initCommand(options) {
|
|
|
1582
1585
|
`));
|
|
1583
1586
|
console.log(chalk3.dim(" Configure your coding agent environment\n"));
|
|
1584
1587
|
console.log(chalk3.bold(" What is Caliber?\n"));
|
|
1585
|
-
console.log(chalk3.dim(" Caliber
|
|
1586
|
-
console.log(chalk3.dim("
|
|
1587
|
-
console.log(chalk3.dim("
|
|
1588
|
-
console.log(chalk3.dim("
|
|
1588
|
+
console.log(chalk3.dim(" Caliber audits your AI agent configurations and suggests targeted"));
|
|
1589
|
+
console.log(chalk3.dim(" improvements. It analyzes CLAUDE.md, .cursorrules, skills, and MCP"));
|
|
1590
|
+
console.log(chalk3.dim(" servers against your actual codebase \u2014 keeping what works, fixing"));
|
|
1591
|
+
console.log(chalk3.dim(" what's stale, and adding what's missing.\n"));
|
|
1589
1592
|
console.log(chalk3.bold(" How it works:\n"));
|
|
1590
1593
|
console.log(chalk3.dim(" 1. Scan Analyze your code, dependencies, and file structure"));
|
|
1591
1594
|
console.log(chalk3.dim(" 2. Match Detect existing configs and check for teammate setups"));
|
|
@@ -1704,9 +1707,9 @@ async function initCommand(options) {
|
|
|
1704
1707
|
if (isEmpty) {
|
|
1705
1708
|
fingerprint.description = await promptInput("What will you build in this project?");
|
|
1706
1709
|
}
|
|
1707
|
-
console.log(chalk3.hex("#6366f1").bold(" Step 4/6 \u2014
|
|
1708
|
-
console.log(chalk3.dim(" AI is
|
|
1709
|
-
console.log(chalk3.dim("
|
|
1710
|
+
console.log(chalk3.hex("#6366f1").bold(" Step 4/6 \u2014 Auditing your configs\n"));
|
|
1711
|
+
console.log(chalk3.dim(" AI is auditing your CLAUDE.md, skills, and rules against your"));
|
|
1712
|
+
console.log(chalk3.dim(" project's actual codebase and conventions.\n"));
|
|
1710
1713
|
console.log(chalk3.dim(" This usually takes 1\u20133 minutes on first run.\n"));
|
|
1711
1714
|
let generatedSetup = null;
|
|
1712
1715
|
let rawOutput;
|
|
@@ -1795,11 +1798,21 @@ async function initCommand(options) {
|
|
|
1795
1798
|
try {
|
|
1796
1799
|
const result = writeSetup(generatedSetup);
|
|
1797
1800
|
writeSpinner.succeed("Config files written");
|
|
1798
|
-
trackEvent("setup_applied", {
|
|
1801
|
+
trackEvent("setup_applied", {
|
|
1802
|
+
files_written: result.written.length,
|
|
1803
|
+
files_deleted: result.deleted.length,
|
|
1804
|
+
target_agent: targetAgent
|
|
1805
|
+
});
|
|
1799
1806
|
console.log(chalk3.bold("\nFiles created/updated:"));
|
|
1800
1807
|
for (const file of result.written) {
|
|
1801
1808
|
console.log(` ${chalk3.green("\u2713")} ${file}`);
|
|
1802
1809
|
}
|
|
1810
|
+
if (result.deleted.length > 0) {
|
|
1811
|
+
console.log(chalk3.bold("\nFiles removed:"));
|
|
1812
|
+
for (const file of result.deleted) {
|
|
1813
|
+
console.log(` ${chalk3.red("\u2717")} ${file}`);
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1803
1816
|
if (result.backupDir) {
|
|
1804
1817
|
console.log(chalk3.dim(`
|
|
1805
1818
|
Backups saved to ${result.backupDir}`));
|
|
@@ -1936,39 +1949,20 @@ async function promptAction() {
|
|
|
1936
1949
|
function printSetupSummary(setup) {
|
|
1937
1950
|
const claude = setup.claude;
|
|
1938
1951
|
const cursor = setup.cursor;
|
|
1952
|
+
const fileDescriptions = setup.fileDescriptions;
|
|
1953
|
+
const deletions = setup.deletions;
|
|
1939
1954
|
console.log("");
|
|
1940
|
-
console.log(chalk3.bold("
|
|
1955
|
+
console.log(chalk3.bold(" Proposed changes:\n"));
|
|
1956
|
+
const getDescription = (filePath) => {
|
|
1957
|
+
return fileDescriptions?.[filePath];
|
|
1958
|
+
};
|
|
1941
1959
|
if (claude) {
|
|
1942
1960
|
if (claude.claudeMd) {
|
|
1943
1961
|
const icon = fs16.existsSync("CLAUDE.md") ? chalk3.yellow("~") : chalk3.green("+");
|
|
1944
|
-
const
|
|
1962
|
+
const desc = getDescription("CLAUDE.md");
|
|
1945
1963
|
console.log(` ${icon} ${chalk3.bold("CLAUDE.md")}`);
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
if (sections.length > 0) {
|
|
1949
|
-
console.log(chalk3.dim(` Sections: ${sections.join(", ")}`));
|
|
1950
|
-
}
|
|
1951
|
-
console.log("");
|
|
1952
|
-
}
|
|
1953
|
-
if (claude.settings) {
|
|
1954
|
-
const icon = fs16.existsSync(".claude/settings.json") ? chalk3.yellow("~") : chalk3.green("+");
|
|
1955
|
-
const settings = claude.settings;
|
|
1956
|
-
const perms = settings.permissions?.allow || [];
|
|
1957
|
-
console.log(` ${icon} ${chalk3.bold(".claude/settings.json")}`);
|
|
1958
|
-
console.log(chalk3.dim(" Pre-approved shell commands so Claude doesn't ask permission each time."));
|
|
1959
|
-
if (perms.length > 0) {
|
|
1960
|
-
console.log(chalk3.dim(` Allows: ${summarizePermissions(perms)}`));
|
|
1961
|
-
}
|
|
1962
|
-
console.log("");
|
|
1963
|
-
}
|
|
1964
|
-
if (claude.settingsLocal) {
|
|
1965
|
-
const icon = fs16.existsSync(".claude/settings.local.json") ? chalk3.yellow("~") : chalk3.green("+");
|
|
1966
|
-
const settings = claude.settingsLocal;
|
|
1967
|
-
const perms = settings.permissions?.allow || [];
|
|
1968
|
-
console.log(` ${icon} ${chalk3.bold(".claude/settings.local.json")}`);
|
|
1969
|
-
console.log(chalk3.dim(" Your personal permission overrides (not shared with teammates)."));
|
|
1970
|
-
if (perms.length > 0) {
|
|
1971
|
-
console.log(chalk3.dim(` Allows: ${summarizePermissions(perms)}`));
|
|
1964
|
+
if (desc) {
|
|
1965
|
+
console.log(chalk3.dim(` ${desc}`));
|
|
1972
1966
|
}
|
|
1973
1967
|
console.log("");
|
|
1974
1968
|
}
|
|
@@ -1977,8 +1971,9 @@ function printSetupSummary(setup) {
|
|
|
1977
1971
|
for (const skill of skills) {
|
|
1978
1972
|
const skillPath = `.claude/skills/${skill.name.replace(/[^a-z0-9-]/gi, "-").toLowerCase()}.md`;
|
|
1979
1973
|
const icon = fs16.existsSync(skillPath) ? chalk3.yellow("~") : chalk3.green("+");
|
|
1974
|
+
const desc = getDescription(skillPath);
|
|
1980
1975
|
console.log(` ${icon} ${chalk3.bold(skillPath)}`);
|
|
1981
|
-
console.log(chalk3.dim(` ${summarizeSkill(skill)}`));
|
|
1976
|
+
console.log(chalk3.dim(` ${desc || summarizeSkill(skill)}`));
|
|
1982
1977
|
console.log("");
|
|
1983
1978
|
}
|
|
1984
1979
|
}
|
|
@@ -1986,18 +1981,18 @@ function printSetupSummary(setup) {
|
|
|
1986
1981
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
1987
1982
|
const icon = fs16.existsSync(".mcp.json") ? chalk3.yellow("~") : chalk3.green("+");
|
|
1988
1983
|
const serverNames = Object.keys(mcpServers);
|
|
1984
|
+
const desc = getDescription(".mcp.json");
|
|
1989
1985
|
console.log(` ${icon} ${chalk3.bold(".mcp.json")}`);
|
|
1990
|
-
console.log(chalk3.dim(
|
|
1991
|
-
console.log(chalk3.dim(` Servers: ${serverNames.join(", ")}`));
|
|
1986
|
+
console.log(chalk3.dim(` ${desc || `servers: ${serverNames.join(", ")}`}`));
|
|
1992
1987
|
console.log("");
|
|
1993
1988
|
}
|
|
1994
1989
|
}
|
|
1995
1990
|
if (cursor) {
|
|
1996
1991
|
if (cursor.cursorrules) {
|
|
1997
1992
|
const icon = fs16.existsSync(".cursorrules") ? chalk3.yellow("~") : chalk3.green("+");
|
|
1993
|
+
const desc = getDescription(".cursorrules");
|
|
1998
1994
|
console.log(` ${icon} ${chalk3.bold(".cursorrules")}`);
|
|
1999
|
-
console.log(chalk3.dim(
|
|
2000
|
-
console.log(chalk3.dim(" and conventions. Cursor reads this at the start of every session."));
|
|
1995
|
+
if (desc) console.log(chalk3.dim(` ${desc}`));
|
|
2001
1996
|
console.log("");
|
|
2002
1997
|
}
|
|
2003
1998
|
const rules = cursor.rules;
|
|
@@ -2005,9 +2000,14 @@ function printSetupSummary(setup) {
|
|
|
2005
2000
|
for (const rule of rules) {
|
|
2006
2001
|
const rulePath = `.cursor/rules/${rule.filename}`;
|
|
2007
2002
|
const icon = fs16.existsSync(rulePath) ? chalk3.yellow("~") : chalk3.green("+");
|
|
2003
|
+
const desc = getDescription(rulePath);
|
|
2008
2004
|
console.log(` ${icon} ${chalk3.bold(rulePath)}`);
|
|
2009
|
-
|
|
2010
|
-
|
|
2005
|
+
if (desc) {
|
|
2006
|
+
console.log(chalk3.dim(` ${desc}`));
|
|
2007
|
+
} else {
|
|
2008
|
+
const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
|
|
2009
|
+
if (firstLine) console.log(chalk3.dim(` ${firstLine.trim().slice(0, 80)}`));
|
|
2010
|
+
}
|
|
2011
2011
|
console.log("");
|
|
2012
2012
|
}
|
|
2013
2013
|
}
|
|
@@ -2015,24 +2015,22 @@ function printSetupSummary(setup) {
|
|
|
2015
2015
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
2016
2016
|
const icon = fs16.existsSync(".cursor/mcp.json") ? chalk3.yellow("~") : chalk3.green("+");
|
|
2017
2017
|
const serverNames = Object.keys(mcpServers);
|
|
2018
|
+
const desc = getDescription(".cursor/mcp.json");
|
|
2018
2019
|
console.log(` ${icon} ${chalk3.bold(".cursor/mcp.json")}`);
|
|
2019
|
-
console.log(chalk3.dim(
|
|
2020
|
-
console.log(
|
|
2020
|
+
console.log(chalk3.dim(` ${desc || `servers: ${serverNames.join(", ")}`}`));
|
|
2021
|
+
console.log("");
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
if (Array.isArray(deletions) && deletions.length > 0) {
|
|
2025
|
+
for (const del of deletions) {
|
|
2026
|
+
console.log(` ${chalk3.red("-")} ${chalk3.bold(del.filePath)}`);
|
|
2027
|
+
console.log(chalk3.dim(` ${del.reason}`));
|
|
2021
2028
|
console.log("");
|
|
2022
2029
|
}
|
|
2023
2030
|
}
|
|
2024
|
-
console.log(` ${chalk3.green("+")} ${chalk3.dim("new")} ${chalk3.yellow("~")} ${chalk3.dim("modified")}`);
|
|
2031
|
+
console.log(` ${chalk3.green("+")} ${chalk3.dim("new")} ${chalk3.yellow("~")} ${chalk3.dim("modified")} ${chalk3.red("-")} ${chalk3.dim("removed")}`);
|
|
2025
2032
|
console.log("");
|
|
2026
2033
|
}
|
|
2027
|
-
function extractClaudeMdSections(md) {
|
|
2028
|
-
return md.split("\n").filter((line) => /^##\s+/.test(line)).map((line) => line.replace(/^##\s+/, "").trim());
|
|
2029
|
-
}
|
|
2030
|
-
function summarizePermissions(permissions, maxShow = 3) {
|
|
2031
|
-
if (permissions.length === 0) return "None";
|
|
2032
|
-
const shown = permissions.slice(0, maxShow).join(", ");
|
|
2033
|
-
const remaining = permissions.length - maxShow;
|
|
2034
|
-
return remaining > 0 ? `${shown} (+${remaining} more)` : shown;
|
|
2035
|
-
}
|
|
2036
2034
|
function summarizeSkill(skill) {
|
|
2037
2035
|
const lines = skill.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"));
|
|
2038
2036
|
return lines[0]?.trim().slice(0, 80) || skill.name;
|
|
@@ -2043,8 +2041,6 @@ function collectSetupFiles(setup) {
|
|
|
2043
2041
|
const cursor = setup.cursor;
|
|
2044
2042
|
if (claude) {
|
|
2045
2043
|
if (claude.claudeMd) files.push({ path: "CLAUDE.md", content: claude.claudeMd });
|
|
2046
|
-
if (claude.settings) files.push({ path: ".claude/settings.json", content: JSON.stringify(claude.settings, null, 2) });
|
|
2047
|
-
if (claude.settingsLocal) files.push({ path: ".claude/settings.local.json", content: JSON.stringify(claude.settingsLocal, null, 2) });
|
|
2048
2044
|
const skills = claude.skills;
|
|
2049
2045
|
if (Array.isArray(skills)) {
|
|
2050
2046
|
for (const skill of skills) {
|