@rely-ai/caliber 1.18.0 → 1.18.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/README.md +1 -1
- package/dist/bin.js +394 -379
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(config_exports, {
|
|
|
26
26
|
DEFAULT_FAST_MODELS: () => DEFAULT_FAST_MODELS,
|
|
27
27
|
DEFAULT_MODELS: () => DEFAULT_MODELS,
|
|
28
28
|
getConfigFilePath: () => getConfigFilePath,
|
|
29
|
+
getDisplayModel: () => getDisplayModel,
|
|
29
30
|
getFastModel: () => getFastModel,
|
|
30
31
|
loadConfig: () => loadConfig,
|
|
31
32
|
readConfigFile: () => readConfigFile,
|
|
@@ -105,6 +106,12 @@ function writeConfigFile(config) {
|
|
|
105
106
|
function getConfigFilePath() {
|
|
106
107
|
return CONFIG_FILE;
|
|
107
108
|
}
|
|
109
|
+
function getDisplayModel(config) {
|
|
110
|
+
if (config.model === "default" && config.provider === "claude-cli") {
|
|
111
|
+
return process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)";
|
|
112
|
+
}
|
|
113
|
+
return config.model;
|
|
114
|
+
}
|
|
108
115
|
function getFastModel() {
|
|
109
116
|
if (process.env.CALIBER_FAST_MODEL) return process.env.CALIBER_FAST_MODEL;
|
|
110
117
|
if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL;
|
|
@@ -218,9 +225,8 @@ import { fileURLToPath } from "url";
|
|
|
218
225
|
|
|
219
226
|
// src/commands/init.ts
|
|
220
227
|
import path19 from "path";
|
|
221
|
-
import
|
|
228
|
+
import chalk9 from "chalk";
|
|
222
229
|
import ora2 from "ora";
|
|
223
|
-
import readline3 from "readline";
|
|
224
230
|
import select5 from "@inquirer/select";
|
|
225
231
|
import checkbox from "@inquirer/checkbox";
|
|
226
232
|
import fs24 from "fs";
|
|
@@ -3449,7 +3455,7 @@ description: ${skill.description}
|
|
|
3449
3455
|
`;
|
|
3450
3456
|
return frontmatter + skill.content;
|
|
3451
3457
|
}
|
|
3452
|
-
function collectSetupFiles(setup) {
|
|
3458
|
+
function collectSetupFiles(setup, targetAgent) {
|
|
3453
3459
|
const files = [];
|
|
3454
3460
|
const claude = setup.claude;
|
|
3455
3461
|
const cursor = setup.cursor;
|
|
@@ -3487,7 +3493,8 @@ function collectSetupFiles(setup) {
|
|
|
3487
3493
|
}
|
|
3488
3494
|
}
|
|
3489
3495
|
}
|
|
3490
|
-
|
|
3496
|
+
const codexTargeted = targetAgent ? targetAgent.includes("codex") : false;
|
|
3497
|
+
if (codexTargeted && !fs15.existsSync("AGENTS.md") && !(codex && codex.agentsMd)) {
|
|
3491
3498
|
const agentRefs = [];
|
|
3492
3499
|
if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
|
|
3493
3500
|
if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
|
|
@@ -3812,12 +3819,12 @@ var GENERATION_MESSAGES = [
|
|
|
3812
3819
|
"Analyzing your project structure and dependencies...",
|
|
3813
3820
|
"Mapping out build commands and test workflows...",
|
|
3814
3821
|
"Reviewing coding patterns and conventions...",
|
|
3815
|
-
"
|
|
3822
|
+
"Extracting architecture and key file references...",
|
|
3816
3823
|
"Designing skills tailored to your codebase...",
|
|
3817
|
-
"
|
|
3824
|
+
"Writing concise, grounded config content...",
|
|
3818
3825
|
"Optimizing settings for your development workflow...",
|
|
3819
3826
|
"Building coding guidelines from your project style...",
|
|
3820
|
-
"
|
|
3827
|
+
"Cross-referencing project files for accuracy...",
|
|
3821
3828
|
"Assembling your complete agent configuration..."
|
|
3822
3829
|
];
|
|
3823
3830
|
var REFINE_MESSAGES = [
|
|
@@ -3893,15 +3900,9 @@ var SpinnerMessages = class {
|
|
|
3893
3900
|
}
|
|
3894
3901
|
};
|
|
3895
3902
|
|
|
3896
|
-
// src/
|
|
3897
|
-
init_config();
|
|
3898
|
-
|
|
3899
|
-
// src/commands/interactive-provider-setup.ts
|
|
3900
|
-
init_config();
|
|
3903
|
+
// src/utils/prompt.ts
|
|
3901
3904
|
import chalk4 from "chalk";
|
|
3902
3905
|
import readline2 from "readline";
|
|
3903
|
-
import select3 from "@inquirer/select";
|
|
3904
|
-
import confirm from "@inquirer/confirm";
|
|
3905
3906
|
function promptInput(question) {
|
|
3906
3907
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
3907
3908
|
return new Promise((resolve2) => {
|
|
@@ -3911,12 +3912,21 @@ function promptInput(question) {
|
|
|
3911
3912
|
});
|
|
3912
3913
|
});
|
|
3913
3914
|
}
|
|
3915
|
+
|
|
3916
|
+
// src/commands/init.ts
|
|
3917
|
+
init_config();
|
|
3918
|
+
|
|
3919
|
+
// src/commands/interactive-provider-setup.ts
|
|
3920
|
+
init_config();
|
|
3921
|
+
import chalk5 from "chalk";
|
|
3922
|
+
import select3 from "@inquirer/select";
|
|
3923
|
+
import confirm from "@inquirer/confirm";
|
|
3914
3924
|
var PROVIDER_CHOICES = [
|
|
3915
|
-
{ name: "Claude Code \u2014
|
|
3916
|
-
{ name: "Cursor
|
|
3917
|
-
{ name: "Anthropic
|
|
3918
|
-
{ name: "Google Vertex AI
|
|
3919
|
-
{ name: "OpenAI
|
|
3925
|
+
{ name: "Claude Code \u2014 use your existing subscription (no API key)", value: "claude-cli" },
|
|
3926
|
+
{ name: "Cursor \u2014 use your existing subscription (no API key)", value: "cursor" },
|
|
3927
|
+
{ name: "Anthropic \u2014 API key from console.anthropic.com", value: "anthropic" },
|
|
3928
|
+
{ name: "Google Vertex AI \u2014 Claude models via GCP", value: "vertex" },
|
|
3929
|
+
{ name: "OpenAI \u2014 or any OpenAI-compatible endpoint", value: "openai" }
|
|
3920
3930
|
];
|
|
3921
3931
|
async function runInteractiveProviderSetup(options) {
|
|
3922
3932
|
const message = options?.selectMessage ?? "Select LLM provider";
|
|
@@ -3929,34 +3939,34 @@ async function runInteractiveProviderSetup(options) {
|
|
|
3929
3939
|
case "claude-cli": {
|
|
3930
3940
|
config.model = "default";
|
|
3931
3941
|
if (!isClaudeCliAvailable()) {
|
|
3932
|
-
console.log(
|
|
3933
|
-
console.log(
|
|
3934
|
-
console.log(
|
|
3942
|
+
console.log(chalk5.yellow("\n Claude Code CLI not found."));
|
|
3943
|
+
console.log(chalk5.dim(" Install it: ") + chalk5.hex("#83D1EB")("npm install -g @anthropic-ai/claude-code"));
|
|
3944
|
+
console.log(chalk5.dim(" Then run ") + chalk5.hex("#83D1EB")("claude") + chalk5.dim(" once to log in.\n"));
|
|
3935
3945
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
3936
3946
|
if (!proceed) throw new Error("__exit__");
|
|
3937
3947
|
} else {
|
|
3938
|
-
console.log(
|
|
3948
|
+
console.log(chalk5.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
|
|
3939
3949
|
}
|
|
3940
3950
|
break;
|
|
3941
3951
|
}
|
|
3942
3952
|
case "cursor": {
|
|
3943
3953
|
config.model = "default";
|
|
3944
3954
|
if (!isCursorAgentAvailable()) {
|
|
3945
|
-
console.log(
|
|
3946
|
-
console.log(
|
|
3947
|
-
console.log(
|
|
3955
|
+
console.log(chalk5.yellow("\n Cursor Agent CLI not found."));
|
|
3956
|
+
console.log(chalk5.dim(" Install it: ") + chalk5.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash"));
|
|
3957
|
+
console.log(chalk5.dim(" Then run ") + chalk5.hex("#83D1EB")("agent login") + chalk5.dim(" to authenticate.\n"));
|
|
3948
3958
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
3949
3959
|
if (!proceed) throw new Error("__exit__");
|
|
3950
3960
|
} else {
|
|
3951
|
-
console.log(
|
|
3961
|
+
console.log(chalk5.dim(" Run `agent login` if you haven't, or set CURSOR_API_KEY."));
|
|
3952
3962
|
}
|
|
3953
3963
|
break;
|
|
3954
3964
|
}
|
|
3955
3965
|
case "anthropic": {
|
|
3956
|
-
console.log(
|
|
3966
|
+
console.log(chalk5.dim(" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."));
|
|
3957
3967
|
config.apiKey = await promptInput("Anthropic API key:");
|
|
3958
3968
|
if (!config.apiKey) {
|
|
3959
|
-
console.log(
|
|
3969
|
+
console.log(chalk5.red("API key is required."));
|
|
3960
3970
|
throw new Error("__exit__");
|
|
3961
3971
|
}
|
|
3962
3972
|
config.model = await promptInput(`Model (default: ${DEFAULT_MODELS.anthropic}):`) || DEFAULT_MODELS.anthropic;
|
|
@@ -3965,7 +3975,7 @@ async function runInteractiveProviderSetup(options) {
|
|
|
3965
3975
|
case "vertex": {
|
|
3966
3976
|
config.vertexProjectId = await promptInput("GCP Project ID:");
|
|
3967
3977
|
if (!config.vertexProjectId) {
|
|
3968
|
-
console.log(
|
|
3978
|
+
console.log(chalk5.red("Project ID is required."));
|
|
3969
3979
|
throw new Error("__exit__");
|
|
3970
3980
|
}
|
|
3971
3981
|
config.vertexRegion = await promptInput("Region (default: us-east5):") || "us-east5";
|
|
@@ -3976,7 +3986,7 @@ async function runInteractiveProviderSetup(options) {
|
|
|
3976
3986
|
case "openai": {
|
|
3977
3987
|
config.apiKey = await promptInput("API key:");
|
|
3978
3988
|
if (!config.apiKey) {
|
|
3979
|
-
console.log(
|
|
3989
|
+
console.log(chalk5.red("API key is required."));
|
|
3980
3990
|
throw new Error("__exit__");
|
|
3981
3991
|
}
|
|
3982
3992
|
config.baseUrl = await promptInput("Base URL (leave empty for OpenAI, or enter custom endpoint):") || void 0;
|
|
@@ -5214,7 +5224,7 @@ function computeLocalScore(dir, targetAgent) {
|
|
|
5214
5224
|
}
|
|
5215
5225
|
|
|
5216
5226
|
// src/scoring/display.ts
|
|
5217
|
-
import
|
|
5227
|
+
import chalk6 from "chalk";
|
|
5218
5228
|
var AGENT_DISPLAY_NAMES = {
|
|
5219
5229
|
claude: "Claude Code",
|
|
5220
5230
|
cursor: "Cursor",
|
|
@@ -5232,31 +5242,31 @@ var CATEGORY_ORDER = ["existence", "quality", "grounding", "accuracy", "freshnes
|
|
|
5232
5242
|
function gradeColor(grade) {
|
|
5233
5243
|
switch (grade) {
|
|
5234
5244
|
case "A":
|
|
5235
|
-
return
|
|
5245
|
+
return chalk6.green;
|
|
5236
5246
|
case "B":
|
|
5237
|
-
return
|
|
5247
|
+
return chalk6.greenBright;
|
|
5238
5248
|
case "C":
|
|
5239
|
-
return
|
|
5249
|
+
return chalk6.yellow;
|
|
5240
5250
|
case "D":
|
|
5241
|
-
return
|
|
5251
|
+
return chalk6.hex("#f97316");
|
|
5242
5252
|
case "F":
|
|
5243
|
-
return
|
|
5253
|
+
return chalk6.red;
|
|
5244
5254
|
default:
|
|
5245
|
-
return
|
|
5255
|
+
return chalk6.white;
|
|
5246
5256
|
}
|
|
5247
5257
|
}
|
|
5248
5258
|
function progressBar(score, max, width = 40) {
|
|
5249
5259
|
const filled = Math.round(score / max * width);
|
|
5250
5260
|
const empty = width - filled;
|
|
5251
|
-
const bar =
|
|
5261
|
+
const bar = chalk6.hex("#f97316")("\u2593".repeat(filled)) + chalk6.gray("\u2591".repeat(empty));
|
|
5252
5262
|
return bar;
|
|
5253
5263
|
}
|
|
5254
5264
|
function formatCheck(check) {
|
|
5255
|
-
const icon = check.passed ?
|
|
5256
|
-
const points = check.passed ?
|
|
5257
|
-
const name = check.passed ?
|
|
5258
|
-
const detail = check.detail ?
|
|
5259
|
-
const suggestion = !check.passed && check.suggestion ?
|
|
5265
|
+
const icon = check.passed ? chalk6.green("\u2713") : check.earnedPoints < 0 ? chalk6.red("\u2717") : chalk6.gray("\u2717");
|
|
5266
|
+
const points = check.passed ? chalk6.green(`+${check.earnedPoints}`.padStart(4)) : check.earnedPoints < 0 ? chalk6.red(`${check.earnedPoints}`.padStart(4)) : chalk6.gray(" \u2014");
|
|
5267
|
+
const name = check.passed ? chalk6.white(check.name) : chalk6.gray(check.name);
|
|
5268
|
+
const detail = check.detail ? chalk6.gray(` (${check.detail})`) : "";
|
|
5269
|
+
const suggestion = !check.passed && check.suggestion ? chalk6.gray(`
|
|
5260
5270
|
\u2192 ${check.suggestion}`) : "";
|
|
5261
5271
|
return ` ${icon} ${name.padEnd(38)}${points}${detail}${suggestion}`;
|
|
5262
5272
|
}
|
|
@@ -5264,19 +5274,19 @@ function displayScore(result) {
|
|
|
5264
5274
|
const gc = gradeColor(result.grade);
|
|
5265
5275
|
const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
|
|
5266
5276
|
console.log("");
|
|
5267
|
-
console.log(
|
|
5277
|
+
console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
5268
5278
|
console.log("");
|
|
5269
|
-
console.log(` ${
|
|
5279
|
+
console.log(` ${chalk6.bold("Agent Config Score")} ${gc(chalk6.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk6.bold(result.grade))}`);
|
|
5270
5280
|
console.log(` ${progressBar(result.score, result.maxScore)}`);
|
|
5271
|
-
console.log(
|
|
5281
|
+
console.log(chalk6.dim(` Target: ${agentLabel}`));
|
|
5272
5282
|
console.log("");
|
|
5273
|
-
console.log(
|
|
5283
|
+
console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
5274
5284
|
console.log("");
|
|
5275
5285
|
for (const category of CATEGORY_ORDER) {
|
|
5276
5286
|
const summary = result.categories[category];
|
|
5277
5287
|
const categoryChecks = result.checks.filter((c) => c.category === category);
|
|
5278
5288
|
console.log(
|
|
5279
|
-
|
|
5289
|
+
chalk6.gray(` ${CATEGORY_LABELS[category]}`) + chalk6.gray(" ".repeat(Math.max(1, 45 - CATEGORY_LABELS[category].length))) + chalk6.white(`${summary.earned}`) + chalk6.gray(` / ${summary.max}`)
|
|
5280
5290
|
);
|
|
5281
5291
|
for (const check of categoryChecks) {
|
|
5282
5292
|
console.log(formatCheck(check));
|
|
@@ -5289,48 +5299,48 @@ function displayScoreSummary(result) {
|
|
|
5289
5299
|
const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
|
|
5290
5300
|
console.log("");
|
|
5291
5301
|
console.log(
|
|
5292
|
-
|
|
5302
|
+
chalk6.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk6.gray(` (Grade ${result.grade})`) + chalk6.gray(` \xB7 ${agentLabel}`) + chalk6.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
|
|
5293
5303
|
);
|
|
5294
5304
|
const failing = result.checks.filter((c) => !c.passed);
|
|
5295
5305
|
if (failing.length > 0) {
|
|
5296
5306
|
const shown = failing.slice(0, 5);
|
|
5297
5307
|
for (const check of shown) {
|
|
5298
|
-
console.log(
|
|
5308
|
+
console.log(chalk6.gray(` \u2717 ${check.name}`));
|
|
5299
5309
|
}
|
|
5300
5310
|
const remaining = failing.length - shown.length;
|
|
5301
5311
|
const moreText = remaining > 0 ? ` (+${remaining} more)` : "";
|
|
5302
|
-
console.log(
|
|
5303
|
-
Run ${
|
|
5312
|
+
console.log(chalk6.dim(`
|
|
5313
|
+
Run ${chalk6.hex("#83D1EB")("caliber score")} for details.${moreText}`));
|
|
5304
5314
|
}
|
|
5305
5315
|
console.log("");
|
|
5306
5316
|
}
|
|
5307
5317
|
function displayScoreDelta(before, after) {
|
|
5308
5318
|
const delta = after.score - before.score;
|
|
5309
5319
|
const deltaStr = delta >= 0 ? `+${delta}` : `${delta}`;
|
|
5310
|
-
const deltaColor = delta >= 0 ?
|
|
5320
|
+
const deltaColor = delta >= 0 ? chalk6.green : chalk6.red;
|
|
5311
5321
|
const beforeGc = gradeColor(before.grade);
|
|
5312
5322
|
const afterGc = gradeColor(after.grade);
|
|
5313
5323
|
console.log("");
|
|
5314
|
-
console.log(
|
|
5324
|
+
console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
5315
5325
|
console.log("");
|
|
5316
5326
|
console.log(
|
|
5317
|
-
` Score: ${beforeGc(`${before.score}`)} ${
|
|
5327
|
+
` Score: ${beforeGc(`${before.score}`)} ${chalk6.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk6.gray("\u2192")} ${afterGc(after.grade)}`
|
|
5318
5328
|
);
|
|
5319
|
-
console.log(` ${progressBar(before.score, before.maxScore, 19)} ${
|
|
5329
|
+
console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk6.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
|
|
5320
5330
|
console.log("");
|
|
5321
|
-
console.log(
|
|
5331
|
+
console.log(chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
5322
5332
|
console.log("");
|
|
5323
5333
|
const improved = after.checks.filter((ac) => {
|
|
5324
5334
|
const bc = before.checks.find((b) => b.id === ac.id);
|
|
5325
5335
|
return bc && ac.earnedPoints > bc.earnedPoints;
|
|
5326
5336
|
});
|
|
5327
5337
|
if (improved.length > 0) {
|
|
5328
|
-
console.log(
|
|
5338
|
+
console.log(chalk6.gray(" What improved:"));
|
|
5329
5339
|
for (const check of improved) {
|
|
5330
5340
|
const bc = before.checks.find((b) => b.id === check.id);
|
|
5331
5341
|
const gain = check.earnedPoints - bc.earnedPoints;
|
|
5332
5342
|
console.log(
|
|
5333
|
-
|
|
5343
|
+
chalk6.green(" +") + chalk6.white(` ${check.name.padEnd(50)}`) + chalk6.green(`+${gain}`)
|
|
5334
5344
|
);
|
|
5335
5345
|
}
|
|
5336
5346
|
console.log("");
|
|
@@ -5338,7 +5348,7 @@ function displayScoreDelta(before, after) {
|
|
|
5338
5348
|
}
|
|
5339
5349
|
|
|
5340
5350
|
// src/commands/recommend.ts
|
|
5341
|
-
import
|
|
5351
|
+
import chalk8 from "chalk";
|
|
5342
5352
|
import ora from "ora";
|
|
5343
5353
|
import select4 from "@inquirer/select";
|
|
5344
5354
|
import { mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync4, existsSync as existsSync8, writeFileSync } from "fs";
|
|
@@ -5493,7 +5503,7 @@ init_config();
|
|
|
5493
5503
|
|
|
5494
5504
|
// src/telemetry/index.ts
|
|
5495
5505
|
import { PostHog } from "posthog-node";
|
|
5496
|
-
import
|
|
5506
|
+
import chalk7 from "chalk";
|
|
5497
5507
|
|
|
5498
5508
|
// src/telemetry/config.ts
|
|
5499
5509
|
import fs22 from "fs";
|
|
@@ -5565,7 +5575,7 @@ function initTelemetry() {
|
|
|
5565
5575
|
});
|
|
5566
5576
|
if (!wasNoticeShown()) {
|
|
5567
5577
|
console.log(
|
|
5568
|
-
|
|
5578
|
+
chalk7.dim(" Caliber collects anonymous usage data to improve the product.") + "\n" + chalk7.dim(" Disable with --no-traces or CALIBER_TELEMETRY_DISABLED=1\n")
|
|
5569
5579
|
);
|
|
5570
5580
|
markNoticeShown();
|
|
5571
5581
|
}
|
|
@@ -5925,7 +5935,7 @@ async function recommendCommand() {
|
|
|
5925
5935
|
]
|
|
5926
5936
|
});
|
|
5927
5937
|
if (!proceed) {
|
|
5928
|
-
console.log(
|
|
5938
|
+
console.log(chalk8.dim(" Cancelled.\n"));
|
|
5929
5939
|
return;
|
|
5930
5940
|
}
|
|
5931
5941
|
await searchAndInstallSkills();
|
|
@@ -5940,7 +5950,7 @@ async function searchAndInstallSkills() {
|
|
|
5940
5950
|
...extractTopDeps()
|
|
5941
5951
|
].filter(Boolean))];
|
|
5942
5952
|
if (technologies.length === 0) {
|
|
5943
|
-
console.log(
|
|
5953
|
+
console.log(chalk8.yellow("Could not detect any languages or dependencies. Try running from a project root."));
|
|
5944
5954
|
throw new Error("__exit__");
|
|
5945
5955
|
}
|
|
5946
5956
|
const primaryPlatform = platforms.includes("claude") ? "claude" : platforms[0];
|
|
@@ -5957,7 +5967,7 @@ async function searchAndInstallSkills() {
|
|
|
5957
5967
|
return;
|
|
5958
5968
|
}
|
|
5959
5969
|
searchSpinner.succeed(
|
|
5960
|
-
`Found ${allCandidates.length} skills` + (filteredCount > 0 ?
|
|
5970
|
+
`Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk8.dim(` (${filteredCount} already installed)`) : "")
|
|
5961
5971
|
);
|
|
5962
5972
|
let results;
|
|
5963
5973
|
const config = loadConfig();
|
|
@@ -5991,7 +6001,7 @@ async function searchAndInstallSkills() {
|
|
|
5991
6001
|
}
|
|
5992
6002
|
const unavailableCount = results.length - available.length;
|
|
5993
6003
|
fetchSpinner.succeed(
|
|
5994
|
-
`${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ?
|
|
6004
|
+
`${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk8.dim(` (${unavailableCount} unavailable)`) : "")
|
|
5995
6005
|
);
|
|
5996
6006
|
const selected = await interactiveSelect(available);
|
|
5997
6007
|
if (selected?.length) {
|
|
@@ -6014,30 +6024,30 @@ async function interactiveSelect(recs) {
|
|
|
6014
6024
|
const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
|
|
6015
6025
|
const prefixWidth = 8;
|
|
6016
6026
|
const scoreWidth = 6;
|
|
6017
|
-
lines.push(
|
|
6027
|
+
lines.push(chalk8.bold(" Skills"));
|
|
6018
6028
|
lines.push("");
|
|
6019
6029
|
if (hasScores) {
|
|
6020
|
-
const header = " ".repeat(prefixWidth) +
|
|
6030
|
+
const header = " ".repeat(prefixWidth) + chalk8.dim("Score".padEnd(scoreWidth)) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Why");
|
|
6021
6031
|
lines.push(header);
|
|
6022
6032
|
} else {
|
|
6023
|
-
const header = " ".repeat(prefixWidth) +
|
|
6033
|
+
const header = " ".repeat(prefixWidth) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Technology".padEnd(18)) + chalk8.dim("Source");
|
|
6024
6034
|
lines.push(header);
|
|
6025
6035
|
}
|
|
6026
|
-
lines.push(
|
|
6036
|
+
lines.push(chalk8.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
|
|
6027
6037
|
for (let i = 0; i < recs.length; i++) {
|
|
6028
6038
|
const rec = recs[i];
|
|
6029
|
-
const check = selected.has(i) ?
|
|
6030
|
-
const ptr = i === cursor ?
|
|
6039
|
+
const check = selected.has(i) ? chalk8.green("[x]") : "[ ]";
|
|
6040
|
+
const ptr = i === cursor ? chalk8.cyan(">") : " ";
|
|
6031
6041
|
if (hasScores) {
|
|
6032
|
-
const scoreColor = rec.score >= 90 ?
|
|
6042
|
+
const scoreColor = rec.score >= 90 ? chalk8.green : rec.score >= 70 ? chalk8.yellow : chalk8.dim;
|
|
6033
6043
|
const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
|
|
6034
|
-
lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${
|
|
6044
|
+
lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk8.dim(rec.reason.slice(0, reasonMax))}`);
|
|
6035
6045
|
} else {
|
|
6036
|
-
lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${
|
|
6046
|
+
lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk8.dim(rec.source_url || "")}`);
|
|
6037
6047
|
}
|
|
6038
6048
|
}
|
|
6039
6049
|
lines.push("");
|
|
6040
|
-
lines.push(
|
|
6050
|
+
lines.push(chalk8.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
|
|
6041
6051
|
return lines.join("\n");
|
|
6042
6052
|
}
|
|
6043
6053
|
function draw(initial) {
|
|
@@ -6086,7 +6096,7 @@ async function interactiveSelect(recs) {
|
|
|
6086
6096
|
case "\n":
|
|
6087
6097
|
cleanup();
|
|
6088
6098
|
if (selected.size === 0) {
|
|
6089
|
-
console.log(
|
|
6099
|
+
console.log(chalk8.dim("\n No skills selected.\n"));
|
|
6090
6100
|
resolve2(null);
|
|
6091
6101
|
} else {
|
|
6092
6102
|
resolve2(Array.from(selected).sort().map((i) => recs[i]));
|
|
@@ -6096,7 +6106,7 @@ async function interactiveSelect(recs) {
|
|
|
6096
6106
|
case "\x1B":
|
|
6097
6107
|
case "":
|
|
6098
6108
|
cleanup();
|
|
6099
|
-
console.log(
|
|
6109
|
+
console.log(chalk8.dim("\n Cancelled.\n"));
|
|
6100
6110
|
resolve2(null);
|
|
6101
6111
|
break;
|
|
6102
6112
|
}
|
|
@@ -6160,7 +6170,7 @@ async function installSkills(recs, platforms, contentMap) {
|
|
|
6160
6170
|
trackSkillsInstalled(installed.length);
|
|
6161
6171
|
spinner.succeed(`Installed ${installed.length} file${installed.length > 1 ? "s" : ""}`);
|
|
6162
6172
|
for (const p of installed) {
|
|
6163
|
-
console.log(
|
|
6173
|
+
console.log(chalk8.green(` \u2713 ${p}`));
|
|
6164
6174
|
}
|
|
6165
6175
|
} else {
|
|
6166
6176
|
spinner.fail("No skills were installed");
|
|
@@ -6173,19 +6183,19 @@ function printSkills(recs) {
|
|
|
6173
6183
|
const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
|
|
6174
6184
|
const scoreWidth = 6;
|
|
6175
6185
|
const prefixWidth = 2;
|
|
6176
|
-
console.log(
|
|
6186
|
+
console.log(chalk8.bold("\n Skills\n"));
|
|
6177
6187
|
if (hasScores) {
|
|
6178
|
-
console.log(" ".repeat(prefixWidth) +
|
|
6188
|
+
console.log(" ".repeat(prefixWidth) + chalk8.dim("Score".padEnd(scoreWidth)) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Why"));
|
|
6179
6189
|
} else {
|
|
6180
|
-
console.log(" ".repeat(prefixWidth) +
|
|
6190
|
+
console.log(" ".repeat(prefixWidth) + chalk8.dim("Name".padEnd(nameWidth)) + chalk8.dim("Technology".padEnd(18)) + chalk8.dim("Source"));
|
|
6181
6191
|
}
|
|
6182
|
-
console.log(
|
|
6192
|
+
console.log(chalk8.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
|
|
6183
6193
|
for (const rec of recs) {
|
|
6184
6194
|
if (hasScores) {
|
|
6185
6195
|
const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
|
|
6186
|
-
console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${
|
|
6196
|
+
console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk8.dim(rec.reason.slice(0, reasonMax))}`);
|
|
6187
6197
|
} else {
|
|
6188
|
-
console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${
|
|
6198
|
+
console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk8.dim(rec.source_url || "")}`);
|
|
6189
6199
|
}
|
|
6190
6200
|
}
|
|
6191
6201
|
console.log("");
|
|
@@ -6280,11 +6290,11 @@ function formatMs(ms) {
|
|
|
6280
6290
|
|
|
6281
6291
|
// src/commands/init.ts
|
|
6282
6292
|
function log(verbose, ...args) {
|
|
6283
|
-
if (verbose) console.log(
|
|
6293
|
+
if (verbose) console.log(chalk9.dim(` [verbose] ${args.map(String).join(" ")}`));
|
|
6284
6294
|
}
|
|
6285
6295
|
async function initCommand(options) {
|
|
6286
|
-
const brand =
|
|
6287
|
-
const title =
|
|
6296
|
+
const brand = chalk9.hex("#EB9D83");
|
|
6297
|
+
const title = chalk9.hex("#83D1EB");
|
|
6288
6298
|
console.log(brand.bold(`
|
|
6289
6299
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
6290
6300
|
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
@@ -6293,41 +6303,34 @@ async function initCommand(options) {
|
|
|
6293
6303
|
\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
|
|
6294
6304
|
\u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
6295
6305
|
`));
|
|
6296
|
-
console.log(
|
|
6297
|
-
console.log(
|
|
6298
|
-
console.log(chalk8.dim(" Caliber analyzes your codebase and creates tailored config files"));
|
|
6299
|
-
console.log(chalk8.dim(" so your AI coding agents understand your project from day one.\n"));
|
|
6306
|
+
console.log(chalk9.dim(" Scan your project and generate tailored config files for"));
|
|
6307
|
+
console.log(chalk9.dim(" Claude Code, Cursor, and Codex.\n"));
|
|
6300
6308
|
const report = options.debugReport ? new DebugReport() : null;
|
|
6301
6309
|
console.log(title.bold(" How it works:\n"));
|
|
6302
|
-
console.log(
|
|
6303
|
-
console.log(
|
|
6304
|
-
console.log(
|
|
6305
|
-
console.log(
|
|
6306
|
-
console.log(
|
|
6307
|
-
console.log(title.bold(" Step 1/5 \u2014 Connect
|
|
6310
|
+
console.log(chalk9.dim(" 1. Connect Choose your LLM provider"));
|
|
6311
|
+
console.log(chalk9.dim(" 2. Discover Scan code, dependencies, and existing configs"));
|
|
6312
|
+
console.log(chalk9.dim(" 3. Generate Build CLAUDE.md, rules, and skills for your codebase"));
|
|
6313
|
+
console.log(chalk9.dim(" 4. Review See a diff \u2014 accept, refine via chat, or decline"));
|
|
6314
|
+
console.log(chalk9.dim(" 5. Skills Search community registries and install skills\n"));
|
|
6315
|
+
console.log(title.bold(" Step 1/5 \u2014 Connect\n"));
|
|
6308
6316
|
let config = loadConfig();
|
|
6309
6317
|
if (!config) {
|
|
6310
|
-
console.log(
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
});
|
|
6315
|
-
} catch (err) {
|
|
6316
|
-
if (err.message === "__exit__") throw err;
|
|
6317
|
-
throw err;
|
|
6318
|
-
}
|
|
6318
|
+
console.log(chalk9.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
|
|
6319
|
+
await runInteractiveProviderSetup({
|
|
6320
|
+
selectMessage: "How do you want to use Caliber? (choose LLM provider)"
|
|
6321
|
+
});
|
|
6319
6322
|
config = loadConfig();
|
|
6320
6323
|
if (!config) {
|
|
6321
|
-
console.log(
|
|
6324
|
+
console.log(chalk9.red(" Setup was cancelled or failed.\n"));
|
|
6322
6325
|
throw new Error("__exit__");
|
|
6323
6326
|
}
|
|
6324
|
-
console.log(
|
|
6327
|
+
console.log(chalk9.green(" \u2713 Provider saved. Let's continue.\n"));
|
|
6325
6328
|
}
|
|
6326
6329
|
trackInitProviderSelected(config.provider, config.model);
|
|
6327
|
-
const displayModel = config
|
|
6330
|
+
const displayModel = getDisplayModel(config);
|
|
6328
6331
|
const fastModel = getFastModel();
|
|
6329
6332
|
const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
|
|
6330
|
-
console.log(
|
|
6333
|
+
console.log(chalk9.dim(modelLine + "\n"));
|
|
6331
6334
|
if (report) {
|
|
6332
6335
|
report.markStep("Provider setup");
|
|
6333
6336
|
report.addSection("LLM Provider", `- **Provider**: ${config.provider}
|
|
@@ -6335,34 +6338,20 @@ async function initCommand(options) {
|
|
|
6335
6338
|
- **Fast model**: ${fastModel || "none"}`);
|
|
6336
6339
|
}
|
|
6337
6340
|
await validateModel({ fast: true });
|
|
6338
|
-
console.log(title.bold(" Step 2/5 \u2014 Discover
|
|
6339
|
-
|
|
6340
|
-
const spinner = ora2("Analyzing project...").start();
|
|
6341
|
+
console.log(title.bold(" Step 2/5 \u2014 Discover\n"));
|
|
6342
|
+
const spinner = ora2("Scanning code, dependencies, and existing configs...").start();
|
|
6341
6343
|
const fingerprint = await collectFingerprint(process.cwd());
|
|
6342
|
-
spinner.succeed("Project
|
|
6344
|
+
spinner.succeed("Project scanned");
|
|
6343
6345
|
log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
|
|
6344
6346
|
if (options.verbose && fingerprint.codeAnalysis) {
|
|
6345
6347
|
log(options.verbose, `Code analysis: ${fingerprint.codeAnalysis.filesIncluded}/${fingerprint.codeAnalysis.filesAnalyzed} files, ~${fingerprint.codeAnalysis.includedTokens.toLocaleString()} tokens, ${fingerprint.codeAnalysis.duplicateGroups} dedup groups`);
|
|
6346
6348
|
}
|
|
6347
6349
|
trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
const parts = [`Context: ~${ca.includedTokens.toLocaleString()} tokens sent`];
|
|
6354
|
-
if (ca.truncated) {
|
|
6355
|
-
parts.push(`(${Math.round(ca.includedTokens / ca.totalProjectTokens * 100)}% of ${ca.totalProjectTokens.toLocaleString()} total)`);
|
|
6356
|
-
}
|
|
6357
|
-
if (compressionPct > 5) {
|
|
6358
|
-
parts.push(`compressed ${compressionPct}%`);
|
|
6359
|
-
}
|
|
6360
|
-
if (ca.duplicateGroups > 0) {
|
|
6361
|
-
parts.push(`${ca.duplicateGroups} duplicate group${ca.duplicateGroups === 1 ? "" : "s"} merged`);
|
|
6362
|
-
}
|
|
6363
|
-
console.log(chalk8.dim(` ${parts.join(" \xB7 ")}`));
|
|
6364
|
-
}
|
|
6365
|
-
console.log("");
|
|
6350
|
+
const langDisplay = fingerprint.languages.join(", ") || "none detected";
|
|
6351
|
+
const frameworkDisplay = fingerprint.frameworks.length > 0 ? ` (${fingerprint.frameworks.join(", ")})` : "";
|
|
6352
|
+
console.log(chalk9.dim(` Languages: ${langDisplay}${frameworkDisplay}`));
|
|
6353
|
+
console.log(chalk9.dim(` Files: ${fingerprint.fileTree.length} found
|
|
6354
|
+
`));
|
|
6366
6355
|
if (report) {
|
|
6367
6356
|
report.markStep("Fingerprint");
|
|
6368
6357
|
report.addJson("Fingerprint: Git", { remote: fingerprint.gitRemoteUrl, packageName: fingerprint.packageName });
|
|
@@ -6382,6 +6371,8 @@ async function initCommand(options) {
|
|
|
6382
6371
|
} else {
|
|
6383
6372
|
targetAgent = await promptAgent();
|
|
6384
6373
|
}
|
|
6374
|
+
console.log(chalk9.dim(` Target: ${targetAgent.join(", ")}
|
|
6375
|
+
`));
|
|
6385
6376
|
trackInitAgentSelected(targetAgent);
|
|
6386
6377
|
const preScore = computeLocalScore(process.cwd(), targetAgent);
|
|
6387
6378
|
const failingForDismissal = preScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
|
|
@@ -6395,6 +6386,7 @@ async function initCommand(options) {
|
|
|
6395
6386
|
}
|
|
6396
6387
|
}
|
|
6397
6388
|
const baselineScore = computeLocalScore(process.cwd(), targetAgent);
|
|
6389
|
+
console.log(chalk9.dim(" Current setup score:"));
|
|
6398
6390
|
displayScoreSummary(baselineScore);
|
|
6399
6391
|
if (options.verbose) {
|
|
6400
6392
|
for (const c of baselineScore.checks) {
|
|
@@ -6423,29 +6415,29 @@ async function initCommand(options) {
|
|
|
6423
6415
|
]);
|
|
6424
6416
|
if (hasExistingConfig && baselineScore.score === 100) {
|
|
6425
6417
|
trackInitScoreComputed(baselineScore.score, passingCount, failingCount, true);
|
|
6426
|
-
console.log(
|
|
6427
|
-
console.log(
|
|
6418
|
+
console.log(chalk9.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
|
|
6419
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to regenerate anyway.\n"));
|
|
6428
6420
|
if (!options.force) return;
|
|
6429
6421
|
}
|
|
6430
6422
|
const allFailingChecks = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
|
|
6431
6423
|
const llmFixableChecks = allFailingChecks.filter((c) => !NON_LLM_CHECKS.has(c.id));
|
|
6432
6424
|
trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
|
|
6433
6425
|
if (hasExistingConfig && llmFixableChecks.length === 0 && allFailingChecks.length > 0 && !options.force) {
|
|
6434
|
-
console.log(
|
|
6435
|
-
console.log(
|
|
6426
|
+
console.log(chalk9.bold.green("\n Your config is fully optimized for LLM generation.\n"));
|
|
6427
|
+
console.log(chalk9.dim(" Remaining items need CLI actions:\n"));
|
|
6436
6428
|
for (const check of allFailingChecks) {
|
|
6437
|
-
console.log(
|
|
6429
|
+
console.log(chalk9.dim(` \u2022 ${check.name}`));
|
|
6438
6430
|
if (check.suggestion) {
|
|
6439
|
-
console.log(` ${
|
|
6431
|
+
console.log(` ${chalk9.hex("#83D1EB")(check.suggestion)}`);
|
|
6440
6432
|
}
|
|
6441
6433
|
}
|
|
6442
6434
|
console.log("");
|
|
6443
|
-
console.log(
|
|
6435
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to regenerate anyway.\n"));
|
|
6444
6436
|
return;
|
|
6445
6437
|
}
|
|
6446
6438
|
const isEmpty = fingerprint.fileTree.length < 3;
|
|
6447
6439
|
if (isEmpty) {
|
|
6448
|
-
fingerprint.description = await
|
|
6440
|
+
fingerprint.description = await promptInput("What will you build in this project?");
|
|
6449
6441
|
}
|
|
6450
6442
|
let failingChecks;
|
|
6451
6443
|
let passingChecks;
|
|
@@ -6455,23 +6447,24 @@ async function initCommand(options) {
|
|
|
6455
6447
|
passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
|
|
6456
6448
|
currentScore = baselineScore.score;
|
|
6457
6449
|
if (failingChecks.length > 0) {
|
|
6458
|
-
console.log(title.bold(" Step 3/5 \u2014
|
|
6459
|
-
console.log(
|
|
6450
|
+
console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
|
|
6451
|
+
console.log(chalk9.dim(` Score is ${baselineScore.score}/100 \u2014 fine-tuning ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
|
|
6460
6452
|
`));
|
|
6461
6453
|
for (const check of failingChecks) {
|
|
6462
|
-
console.log(
|
|
6454
|
+
console.log(chalk9.dim(` \u2022 ${check.name}`));
|
|
6463
6455
|
}
|
|
6464
6456
|
console.log("");
|
|
6465
6457
|
}
|
|
6466
6458
|
} else if (hasExistingConfig) {
|
|
6467
|
-
console.log(title.bold(" Step 3/5 \u2014
|
|
6468
|
-
console.log(
|
|
6469
|
-
console.log(chalk8.dim(" and preparing improvements.\n"));
|
|
6459
|
+
console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
|
|
6460
|
+
console.log(chalk9.dim(" Auditing your existing configs against your codebase and improving them.\n"));
|
|
6470
6461
|
} else {
|
|
6471
|
-
console.log(title.bold(" Step 3/5 \u2014
|
|
6472
|
-
console.log(
|
|
6462
|
+
console.log(title.bold(" Step 3/5 \u2014 Generate\n"));
|
|
6463
|
+
console.log(chalk9.dim(" Building CLAUDE.md, rules, and skills tailored to your project.\n"));
|
|
6473
6464
|
}
|
|
6474
|
-
|
|
6465
|
+
const genModelInfo = fastModel ? ` Using ${displayModel} for docs, ${fastModel} for skills` : ` Using ${displayModel}`;
|
|
6466
|
+
console.log(chalk9.dim(genModelInfo));
|
|
6467
|
+
console.log(chalk9.dim(" This can take a couple of minutes depending on your model and provider.\n"));
|
|
6475
6468
|
if (report) {
|
|
6476
6469
|
report.markStep("Generation");
|
|
6477
6470
|
const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
|
|
@@ -6523,8 +6516,8 @@ async function initCommand(options) {
|
|
|
6523
6516
|
genSpinner.fail("Failed to generate setup.");
|
|
6524
6517
|
writeErrorLog(config, rawOutput, void 0, genStopReason);
|
|
6525
6518
|
if (rawOutput) {
|
|
6526
|
-
console.log(
|
|
6527
|
-
console.log(
|
|
6519
|
+
console.log(chalk9.dim("\nRaw LLM output (JSON parse failed):"));
|
|
6520
|
+
console.log(chalk9.dim(rawOutput.slice(0, 500)));
|
|
6528
6521
|
}
|
|
6529
6522
|
throw new Error("__exit__");
|
|
6530
6523
|
}
|
|
@@ -6537,7 +6530,7 @@ async function initCommand(options) {
|
|
|
6537
6530
|
const mins = Math.floor(elapsedMs / 6e4);
|
|
6538
6531
|
const secs = Math.floor(elapsedMs % 6e4 / 1e3);
|
|
6539
6532
|
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
6540
|
-
genSpinner.succeed(`Setup generated ${
|
|
6533
|
+
genSpinner.succeed(`Setup generated ${chalk9.dim(`in ${timeStr}`)}`);
|
|
6541
6534
|
log(options.verbose, `Generation completed: ${elapsedMs}ms, stopReason: ${genStopReason || "end_turn"}`);
|
|
6542
6535
|
printSetupSummary(generatedSetup);
|
|
6543
6536
|
const sessionHistory = [];
|
|
@@ -6545,15 +6538,15 @@ async function initCommand(options) {
|
|
|
6545
6538
|
role: "assistant",
|
|
6546
6539
|
content: summarizeSetup("Initial generation", generatedSetup)
|
|
6547
6540
|
});
|
|
6548
|
-
console.log(title.bold(" Step 4/5 \u2014 Review
|
|
6549
|
-
const setupFiles = collectSetupFiles(generatedSetup);
|
|
6541
|
+
console.log(title.bold(" Step 4/5 \u2014 Review\n"));
|
|
6542
|
+
const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
|
|
6550
6543
|
const staged = stageFiles(setupFiles, process.cwd());
|
|
6551
6544
|
const totalChanges = staged.newFiles + staged.modifiedFiles;
|
|
6552
|
-
console.log(
|
|
6545
|
+
console.log(chalk9.dim(` ${chalk9.green(`${staged.newFiles} new`)} / ${chalk9.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
|
|
6553
6546
|
`));
|
|
6554
6547
|
let action;
|
|
6555
6548
|
if (totalChanges === 0) {
|
|
6556
|
-
console.log(
|
|
6549
|
+
console.log(chalk9.dim(" No changes needed \u2014 your configs are already up to date.\n"));
|
|
6557
6550
|
cleanupStaging();
|
|
6558
6551
|
action = "accept";
|
|
6559
6552
|
} else if (options.autoApprove) {
|
|
@@ -6576,12 +6569,12 @@ async function initCommand(options) {
|
|
|
6576
6569
|
trackInitRefinementRound(refinementRound, !!generatedSetup);
|
|
6577
6570
|
if (!generatedSetup) {
|
|
6578
6571
|
cleanupStaging();
|
|
6579
|
-
console.log(
|
|
6572
|
+
console.log(chalk9.dim("Refinement cancelled. No files were modified."));
|
|
6580
6573
|
return;
|
|
6581
6574
|
}
|
|
6582
|
-
const updatedFiles = collectSetupFiles(generatedSetup);
|
|
6575
|
+
const updatedFiles = collectSetupFiles(generatedSetup, targetAgent);
|
|
6583
6576
|
const restaged = stageFiles(updatedFiles, process.cwd());
|
|
6584
|
-
console.log(
|
|
6577
|
+
console.log(chalk9.dim(` ${chalk9.green(`${restaged.newFiles} new`)} / ${chalk9.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
|
|
6585
6578
|
`));
|
|
6586
6579
|
printSetupSummary(generatedSetup);
|
|
6587
6580
|
await openReview("terminal", restaged.stagedFiles);
|
|
@@ -6590,28 +6583,30 @@ async function initCommand(options) {
|
|
|
6590
6583
|
}
|
|
6591
6584
|
cleanupStaging();
|
|
6592
6585
|
if (action === "decline") {
|
|
6593
|
-
console.log(
|
|
6586
|
+
console.log(chalk9.dim("Setup declined. No files were modified."));
|
|
6594
6587
|
return;
|
|
6595
6588
|
}
|
|
6596
6589
|
if (options.dryRun) {
|
|
6597
|
-
console.log(
|
|
6590
|
+
console.log(chalk9.yellow("\n[Dry run] Would write the following files:"));
|
|
6598
6591
|
console.log(JSON.stringify(generatedSetup, null, 2));
|
|
6599
6592
|
return;
|
|
6600
6593
|
}
|
|
6601
6594
|
const writeSpinner = ora2("Writing config files...").start();
|
|
6602
6595
|
try {
|
|
6603
|
-
if (!fs24.existsSync("AGENTS.md") && !generatedSetup.codex) {
|
|
6604
|
-
const
|
|
6605
|
-
const
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6596
|
+
if (targetAgent.includes("codex") && !fs24.existsSync("AGENTS.md") && !generatedSetup.codex) {
|
|
6597
|
+
const claude = generatedSetup.claude;
|
|
6598
|
+
const cursor = generatedSetup.cursor;
|
|
6599
|
+
const agentRefs = [];
|
|
6600
|
+
if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
|
|
6601
|
+
if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
|
|
6602
|
+
if (agentRefs.length === 0) agentRefs.push("See CLAUDE.md and .cursor/rules/ for agent configurations.");
|
|
6603
|
+
const stubContent = `# AGENTS.md
|
|
6604
|
+
|
|
6605
|
+
This project uses AI coding agents configured by [Caliber](https://github.com/rely-ai-org/caliber).
|
|
6606
|
+
|
|
6607
|
+
${agentRefs.join(" ")}
|
|
6608
|
+
`;
|
|
6609
|
+
generatedSetup.codex = { agentsMd: stubContent };
|
|
6615
6610
|
}
|
|
6616
6611
|
const result = writeSetup(generatedSetup);
|
|
6617
6612
|
writeSpinner.succeed("Config files written");
|
|
@@ -6621,26 +6616,26 @@ async function initCommand(options) {
|
|
|
6621
6616
|
0,
|
|
6622
6617
|
result.deleted.length
|
|
6623
6618
|
);
|
|
6624
|
-
console.log(
|
|
6619
|
+
console.log(chalk9.bold("\nFiles created/updated:"));
|
|
6625
6620
|
for (const file of result.written) {
|
|
6626
|
-
console.log(` ${
|
|
6621
|
+
console.log(` ${chalk9.green("\u2713")} ${file}`);
|
|
6627
6622
|
}
|
|
6628
6623
|
if (result.deleted.length > 0) {
|
|
6629
|
-
console.log(
|
|
6624
|
+
console.log(chalk9.bold("\nFiles removed:"));
|
|
6630
6625
|
for (const file of result.deleted) {
|
|
6631
|
-
console.log(` ${
|
|
6626
|
+
console.log(` ${chalk9.red("\u2717")} ${file}`);
|
|
6632
6627
|
}
|
|
6633
6628
|
}
|
|
6634
6629
|
if (result.backupDir) {
|
|
6635
|
-
console.log(
|
|
6630
|
+
console.log(chalk9.dim(`
|
|
6636
6631
|
Backups saved to ${result.backupDir}`));
|
|
6637
6632
|
}
|
|
6638
6633
|
} catch (err) {
|
|
6639
6634
|
writeSpinner.fail("Failed to write files");
|
|
6640
|
-
console.error(
|
|
6635
|
+
console.error(chalk9.red(err instanceof Error ? err.message : "Unknown error"));
|
|
6641
6636
|
throw new Error("__exit__");
|
|
6642
6637
|
}
|
|
6643
|
-
ensurePermissions();
|
|
6638
|
+
ensurePermissions(fingerprint);
|
|
6644
6639
|
const sha = getCurrentHeadSha();
|
|
6645
6640
|
writeState({
|
|
6646
6641
|
lastRefreshSha: sha ?? "",
|
|
@@ -6648,8 +6643,7 @@ async function initCommand(options) {
|
|
|
6648
6643
|
targetAgent
|
|
6649
6644
|
});
|
|
6650
6645
|
console.log("");
|
|
6651
|
-
console.log(
|
|
6652
|
-
console.log(chalk8.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
|
|
6646
|
+
console.log(chalk9.dim(" Auto-refresh: keep your configs in sync as your code changes.\n"));
|
|
6653
6647
|
let hookChoice;
|
|
6654
6648
|
if (options.autoApprove) {
|
|
6655
6649
|
hookChoice = "skip";
|
|
@@ -6661,46 +6655,46 @@ async function initCommand(options) {
|
|
|
6661
6655
|
if (hookChoice === "claude" || hookChoice === "both") {
|
|
6662
6656
|
const hookResult = installHook();
|
|
6663
6657
|
if (hookResult.installed) {
|
|
6664
|
-
console.log(` ${
|
|
6665
|
-
console.log(
|
|
6658
|
+
console.log(` ${chalk9.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
|
|
6659
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber hooks --remove") + chalk9.dim(" to disable"));
|
|
6666
6660
|
} else if (hookResult.alreadyInstalled) {
|
|
6667
|
-
console.log(
|
|
6661
|
+
console.log(chalk9.dim(" Claude Code hook already installed"));
|
|
6668
6662
|
}
|
|
6669
6663
|
const learnResult = installLearningHooks();
|
|
6670
6664
|
if (learnResult.installed) {
|
|
6671
|
-
console.log(` ${
|
|
6672
|
-
console.log(
|
|
6665
|
+
console.log(` ${chalk9.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
|
|
6666
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber learn remove") + chalk9.dim(" to disable"));
|
|
6673
6667
|
} else if (learnResult.alreadyInstalled) {
|
|
6674
|
-
console.log(
|
|
6668
|
+
console.log(chalk9.dim(" Learning hooks already installed"));
|
|
6675
6669
|
}
|
|
6676
6670
|
}
|
|
6677
6671
|
if (hookChoice === "precommit" || hookChoice === "both") {
|
|
6678
6672
|
const precommitResult = installPreCommitHook();
|
|
6679
6673
|
if (precommitResult.installed) {
|
|
6680
|
-
console.log(` ${
|
|
6681
|
-
console.log(
|
|
6674
|
+
console.log(` ${chalk9.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
|
|
6675
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber hooks --remove") + chalk9.dim(" to disable"));
|
|
6682
6676
|
} else if (precommitResult.alreadyInstalled) {
|
|
6683
|
-
console.log(
|
|
6677
|
+
console.log(chalk9.dim(" Pre-commit hook already installed"));
|
|
6684
6678
|
} else {
|
|
6685
|
-
console.log(
|
|
6679
|
+
console.log(chalk9.yellow(" Could not install pre-commit hook (not a git repository?)"));
|
|
6686
6680
|
}
|
|
6687
6681
|
}
|
|
6688
6682
|
if (hookChoice === "skip") {
|
|
6689
|
-
console.log(
|
|
6683
|
+
console.log(chalk9.dim(" Skipped auto-refresh hooks. Run ") + chalk9.hex("#83D1EB")("caliber hooks --install") + chalk9.dim(" later to enable."));
|
|
6690
6684
|
}
|
|
6691
6685
|
const afterScore = computeLocalScore(process.cwd(), targetAgent);
|
|
6692
6686
|
if (afterScore.score < baselineScore.score) {
|
|
6693
6687
|
trackInitScoreRegression(baselineScore.score, afterScore.score);
|
|
6694
6688
|
console.log("");
|
|
6695
|
-
console.log(
|
|
6689
|
+
console.log(chalk9.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
|
|
6696
6690
|
try {
|
|
6697
6691
|
const { restored, removed } = undoSetup();
|
|
6698
6692
|
if (restored.length > 0 || removed.length > 0) {
|
|
6699
|
-
console.log(
|
|
6693
|
+
console.log(chalk9.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
|
|
6700
6694
|
}
|
|
6701
6695
|
} catch {
|
|
6702
6696
|
}
|
|
6703
|
-
console.log(
|
|
6697
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber init --force") + chalk9.dim(" to override.\n"));
|
|
6704
6698
|
return;
|
|
6705
6699
|
}
|
|
6706
6700
|
if (report) {
|
|
@@ -6718,8 +6712,8 @@ async function initCommand(options) {
|
|
|
6718
6712
|
log(options.verbose, ` Still failing: ${c.name} (${c.earnedPoints}/${c.maxPoints})${c.suggestion ? ` \u2014 ${c.suggestion}` : ""}`);
|
|
6719
6713
|
}
|
|
6720
6714
|
}
|
|
6721
|
-
console.log(title.bold("\n Step 5/5 \u2014
|
|
6722
|
-
console.log(
|
|
6715
|
+
console.log(title.bold("\n Step 5/5 \u2014 Skills\n"));
|
|
6716
|
+
console.log(chalk9.dim(" Search community registries for skills that match your tech stack.\n"));
|
|
6723
6717
|
let wantsSkills;
|
|
6724
6718
|
if (options.autoApprove) {
|
|
6725
6719
|
wantsSkills = false;
|
|
@@ -6739,19 +6733,22 @@ async function initCommand(options) {
|
|
|
6739
6733
|
await searchAndInstallSkills();
|
|
6740
6734
|
} catch (err) {
|
|
6741
6735
|
if (err.message !== "__exit__") {
|
|
6742
|
-
console.log(
|
|
6736
|
+
console.log(chalk9.dim(" Skills search failed: " + (err.message || "unknown error")));
|
|
6743
6737
|
}
|
|
6744
|
-
console.log(
|
|
6738
|
+
console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber skills") + chalk9.dim(" later to try again.\n"));
|
|
6745
6739
|
}
|
|
6746
6740
|
} else {
|
|
6747
6741
|
trackInitSkillsSearch(false, 0);
|
|
6748
|
-
console.log(
|
|
6742
|
+
console.log(chalk9.dim(" Skipped. Run ") + chalk9.hex("#83D1EB")("caliber skills") + chalk9.dim(" later to browse.\n"));
|
|
6749
6743
|
}
|
|
6750
|
-
console.log(
|
|
6751
|
-
console.log(
|
|
6752
|
-
console.log(
|
|
6744
|
+
console.log(chalk9.bold.green(" Setup complete!"));
|
|
6745
|
+
console.log(chalk9.dim(" Your AI agents now understand your project's architecture, build commands,"));
|
|
6746
|
+
console.log(chalk9.dim(" testing patterns, and conventions. All changes are backed up automatically.\n"));
|
|
6747
|
+
console.log(chalk9.bold(" Next steps:\n"));
|
|
6753
6748
|
console.log(` ${title("caliber score")} See your full config breakdown`);
|
|
6754
|
-
console.log(` ${title("caliber
|
|
6749
|
+
console.log(` ${title("caliber refresh")} Update docs after code changes`);
|
|
6750
|
+
console.log(` ${title("caliber hooks")} Toggle auto-refresh hooks`);
|
|
6751
|
+
console.log(` ${title("caliber skills")} Discover community skills for your stack`);
|
|
6755
6752
|
console.log(` ${title("caliber undo")} Revert all changes from this run`);
|
|
6756
6753
|
console.log("");
|
|
6757
6754
|
if (options.showTokens) {
|
|
@@ -6761,13 +6758,13 @@ async function initCommand(options) {
|
|
|
6761
6758
|
report.markStep("Finished");
|
|
6762
6759
|
const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
|
|
6763
6760
|
report.write(reportPath);
|
|
6764
|
-
console.log(
|
|
6761
|
+
console.log(chalk9.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
|
|
6765
6762
|
`));
|
|
6766
6763
|
}
|
|
6767
6764
|
}
|
|
6768
6765
|
async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
6769
6766
|
while (true) {
|
|
6770
|
-
const message = await
|
|
6767
|
+
const message = await promptInput("\nWhat would you like to change?");
|
|
6771
6768
|
if (!message || message.toLowerCase() === "done" || message.toLowerCase() === "accept") {
|
|
6772
6769
|
return currentSetup;
|
|
6773
6770
|
}
|
|
@@ -6776,9 +6773,9 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
|
6776
6773
|
}
|
|
6777
6774
|
const isValid = await classifyRefineIntent(message);
|
|
6778
6775
|
if (!isValid) {
|
|
6779
|
-
console.log(
|
|
6780
|
-
console.log(
|
|
6781
|
-
console.log(
|
|
6776
|
+
console.log(chalk9.dim(" This doesn't look like a config change request."));
|
|
6777
|
+
console.log(chalk9.dim(" Describe what to add, remove, or modify in your configs."));
|
|
6778
|
+
console.log(chalk9.dim(' Type "done" to accept the current setup.\n'));
|
|
6782
6779
|
continue;
|
|
6783
6780
|
}
|
|
6784
6781
|
const refineSpinner = ora2("Refining setup...").start();
|
|
@@ -6799,10 +6796,10 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
|
|
|
6799
6796
|
});
|
|
6800
6797
|
refineSpinner.succeed("Setup updated");
|
|
6801
6798
|
printSetupSummary(refined);
|
|
6802
|
-
console.log(
|
|
6799
|
+
console.log(chalk9.dim('Type "done" to accept, or describe more changes.'));
|
|
6803
6800
|
} else {
|
|
6804
6801
|
refineSpinner.fail("Refinement failed \u2014 could not parse AI response.");
|
|
6805
|
-
console.log(
|
|
6802
|
+
console.log(chalk9.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
|
|
6806
6803
|
}
|
|
6807
6804
|
}
|
|
6808
6805
|
}
|
|
@@ -6870,15 +6867,6 @@ ${JSON.stringify(checkList, null, 2)}`,
|
|
|
6870
6867
|
return [];
|
|
6871
6868
|
}
|
|
6872
6869
|
}
|
|
6873
|
-
function promptInput2(question) {
|
|
6874
|
-
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
6875
|
-
return new Promise((resolve2) => {
|
|
6876
|
-
rl.question(chalk8.cyan(`${question} `), (answer) => {
|
|
6877
|
-
rl.close();
|
|
6878
|
-
resolve2(answer.trim());
|
|
6879
|
-
});
|
|
6880
|
-
});
|
|
6881
|
-
}
|
|
6882
6870
|
async function promptAgent() {
|
|
6883
6871
|
const selected = await checkbox({
|
|
6884
6872
|
message: "Which coding agents do you use? (toggle with space)",
|
|
@@ -6926,26 +6914,26 @@ function printSetupSummary(setup) {
|
|
|
6926
6914
|
const fileDescriptions = setup.fileDescriptions;
|
|
6927
6915
|
const deletions = setup.deletions;
|
|
6928
6916
|
console.log("");
|
|
6929
|
-
console.log(
|
|
6917
|
+
console.log(chalk9.bold(" Proposed changes:\n"));
|
|
6930
6918
|
const getDescription = (filePath) => {
|
|
6931
6919
|
return fileDescriptions?.[filePath];
|
|
6932
6920
|
};
|
|
6933
6921
|
if (claude) {
|
|
6934
6922
|
if (claude.claudeMd) {
|
|
6935
|
-
const icon = fs24.existsSync("CLAUDE.md") ?
|
|
6923
|
+
const icon = fs24.existsSync("CLAUDE.md") ? chalk9.yellow("~") : chalk9.green("+");
|
|
6936
6924
|
const desc = getDescription("CLAUDE.md");
|
|
6937
|
-
console.log(` ${icon} ${
|
|
6938
|
-
if (desc) console.log(
|
|
6925
|
+
console.log(` ${icon} ${chalk9.bold("CLAUDE.md")}`);
|
|
6926
|
+
if (desc) console.log(chalk9.dim(` ${desc}`));
|
|
6939
6927
|
console.log("");
|
|
6940
6928
|
}
|
|
6941
6929
|
const skills = claude.skills;
|
|
6942
6930
|
if (Array.isArray(skills) && skills.length > 0) {
|
|
6943
6931
|
for (const skill of skills) {
|
|
6944
6932
|
const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
|
|
6945
|
-
const icon = fs24.existsSync(skillPath) ?
|
|
6933
|
+
const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
|
|
6946
6934
|
const desc = getDescription(skillPath);
|
|
6947
|
-
console.log(` ${icon} ${
|
|
6948
|
-
console.log(
|
|
6935
|
+
console.log(` ${icon} ${chalk9.bold(skillPath)}`);
|
|
6936
|
+
console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
|
|
6949
6937
|
console.log("");
|
|
6950
6938
|
}
|
|
6951
6939
|
}
|
|
@@ -6953,40 +6941,40 @@ function printSetupSummary(setup) {
|
|
|
6953
6941
|
const codex = setup.codex;
|
|
6954
6942
|
if (codex) {
|
|
6955
6943
|
if (codex.agentsMd) {
|
|
6956
|
-
const icon = fs24.existsSync("AGENTS.md") ?
|
|
6944
|
+
const icon = fs24.existsSync("AGENTS.md") ? chalk9.yellow("~") : chalk9.green("+");
|
|
6957
6945
|
const desc = getDescription("AGENTS.md");
|
|
6958
|
-
console.log(` ${icon} ${
|
|
6959
|
-
if (desc) console.log(
|
|
6946
|
+
console.log(` ${icon} ${chalk9.bold("AGENTS.md")}`);
|
|
6947
|
+
if (desc) console.log(chalk9.dim(` ${desc}`));
|
|
6960
6948
|
console.log("");
|
|
6961
6949
|
}
|
|
6962
6950
|
const codexSkills = codex.skills;
|
|
6963
6951
|
if (Array.isArray(codexSkills) && codexSkills.length > 0) {
|
|
6964
6952
|
for (const skill of codexSkills) {
|
|
6965
6953
|
const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
|
|
6966
|
-
const icon = fs24.existsSync(skillPath) ?
|
|
6954
|
+
const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
|
|
6967
6955
|
const desc = getDescription(skillPath);
|
|
6968
|
-
console.log(` ${icon} ${
|
|
6969
|
-
console.log(
|
|
6956
|
+
console.log(` ${icon} ${chalk9.bold(skillPath)}`);
|
|
6957
|
+
console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
|
|
6970
6958
|
console.log("");
|
|
6971
6959
|
}
|
|
6972
6960
|
}
|
|
6973
6961
|
}
|
|
6974
6962
|
if (cursor) {
|
|
6975
6963
|
if (cursor.cursorrules) {
|
|
6976
|
-
const icon = fs24.existsSync(".cursorrules") ?
|
|
6964
|
+
const icon = fs24.existsSync(".cursorrules") ? chalk9.yellow("~") : chalk9.green("+");
|
|
6977
6965
|
const desc = getDescription(".cursorrules");
|
|
6978
|
-
console.log(` ${icon} ${
|
|
6979
|
-
if (desc) console.log(
|
|
6966
|
+
console.log(` ${icon} ${chalk9.bold(".cursorrules")}`);
|
|
6967
|
+
if (desc) console.log(chalk9.dim(` ${desc}`));
|
|
6980
6968
|
console.log("");
|
|
6981
6969
|
}
|
|
6982
6970
|
const cursorSkills = cursor.skills;
|
|
6983
6971
|
if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
|
|
6984
6972
|
for (const skill of cursorSkills) {
|
|
6985
6973
|
const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
|
|
6986
|
-
const icon = fs24.existsSync(skillPath) ?
|
|
6974
|
+
const icon = fs24.existsSync(skillPath) ? chalk9.yellow("~") : chalk9.green("+");
|
|
6987
6975
|
const desc = getDescription(skillPath);
|
|
6988
|
-
console.log(` ${icon} ${
|
|
6989
|
-
console.log(
|
|
6976
|
+
console.log(` ${icon} ${chalk9.bold(skillPath)}`);
|
|
6977
|
+
console.log(chalk9.dim(` ${desc || skill.description || skill.name}`));
|
|
6990
6978
|
console.log("");
|
|
6991
6979
|
}
|
|
6992
6980
|
}
|
|
@@ -6994,35 +6982,67 @@ function printSetupSummary(setup) {
|
|
|
6994
6982
|
if (Array.isArray(rules) && rules.length > 0) {
|
|
6995
6983
|
for (const rule of rules) {
|
|
6996
6984
|
const rulePath = `.cursor/rules/${rule.filename}`;
|
|
6997
|
-
const icon = fs24.existsSync(rulePath) ?
|
|
6985
|
+
const icon = fs24.existsSync(rulePath) ? chalk9.yellow("~") : chalk9.green("+");
|
|
6998
6986
|
const desc = getDescription(rulePath);
|
|
6999
|
-
console.log(` ${icon} ${
|
|
6987
|
+
console.log(` ${icon} ${chalk9.bold(rulePath)}`);
|
|
7000
6988
|
if (desc) {
|
|
7001
|
-
console.log(
|
|
6989
|
+
console.log(chalk9.dim(` ${desc}`));
|
|
7002
6990
|
} else {
|
|
7003
6991
|
const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
|
|
7004
|
-
if (firstLine) console.log(
|
|
6992
|
+
if (firstLine) console.log(chalk9.dim(` ${firstLine.trim().slice(0, 80)}`));
|
|
7005
6993
|
}
|
|
7006
6994
|
console.log("");
|
|
7007
6995
|
}
|
|
7008
6996
|
}
|
|
7009
6997
|
}
|
|
7010
|
-
if (!codex && !fs24.existsSync("AGENTS.md")) {
|
|
7011
|
-
console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
|
|
7012
|
-
console.log(chalk8.dim(" Cross-agent coordination file"));
|
|
7013
|
-
console.log("");
|
|
7014
|
-
}
|
|
7015
6998
|
if (Array.isArray(deletions) && deletions.length > 0) {
|
|
7016
6999
|
for (const del of deletions) {
|
|
7017
|
-
console.log(` ${
|
|
7018
|
-
console.log(
|
|
7000
|
+
console.log(` ${chalk9.red("-")} ${chalk9.bold(del.filePath)}`);
|
|
7001
|
+
console.log(chalk9.dim(` ${del.reason}`));
|
|
7019
7002
|
console.log("");
|
|
7020
7003
|
}
|
|
7021
7004
|
}
|
|
7022
|
-
console.log(` ${
|
|
7005
|
+
console.log(` ${chalk9.green("+")} ${chalk9.dim("new")} ${chalk9.yellow("~")} ${chalk9.dim("modified")} ${chalk9.red("-")} ${chalk9.dim("removed")}`);
|
|
7023
7006
|
console.log("");
|
|
7024
7007
|
}
|
|
7025
|
-
function
|
|
7008
|
+
function derivePermissions(fingerprint) {
|
|
7009
|
+
const perms = ["Bash(git *)"];
|
|
7010
|
+
const langs = new Set(fingerprint.languages.map((l) => l.toLowerCase()));
|
|
7011
|
+
const tools = new Set(fingerprint.tools.map((t) => t.toLowerCase()));
|
|
7012
|
+
const hasFile = (name) => fingerprint.fileTree.some((f) => f === name || f === `./${name}`);
|
|
7013
|
+
if (langs.has("typescript") || langs.has("javascript") || hasFile("package.json")) {
|
|
7014
|
+
perms.push("Bash(npm run *)", "Bash(npx *)");
|
|
7015
|
+
}
|
|
7016
|
+
if (langs.has("python") || hasFile("pyproject.toml") || hasFile("requirements.txt")) {
|
|
7017
|
+
perms.push("Bash(python *)", "Bash(pip *)", "Bash(pytest *)");
|
|
7018
|
+
}
|
|
7019
|
+
if (langs.has("go") || hasFile("go.mod")) {
|
|
7020
|
+
perms.push("Bash(go *)");
|
|
7021
|
+
}
|
|
7022
|
+
if (langs.has("rust") || hasFile("Cargo.toml")) {
|
|
7023
|
+
perms.push("Bash(cargo *)");
|
|
7024
|
+
}
|
|
7025
|
+
if (langs.has("java") || langs.has("kotlin")) {
|
|
7026
|
+
if (hasFile("gradlew")) perms.push("Bash(./gradlew *)");
|
|
7027
|
+
if (hasFile("mvnw")) perms.push("Bash(./mvnw *)");
|
|
7028
|
+
if (hasFile("pom.xml")) perms.push("Bash(mvn *)");
|
|
7029
|
+
if (hasFile("build.gradle") || hasFile("build.gradle.kts")) perms.push("Bash(gradle *)");
|
|
7030
|
+
}
|
|
7031
|
+
if (langs.has("ruby") || hasFile("Gemfile")) {
|
|
7032
|
+
perms.push("Bash(bundle *)", "Bash(rake *)");
|
|
7033
|
+
}
|
|
7034
|
+
if (tools.has("terraform") || hasFile("main.tf")) {
|
|
7035
|
+
perms.push("Bash(terraform *)");
|
|
7036
|
+
}
|
|
7037
|
+
if (tools.has("docker") || hasFile("Dockerfile") || hasFile("docker-compose.yml")) {
|
|
7038
|
+
perms.push("Bash(docker *)");
|
|
7039
|
+
}
|
|
7040
|
+
if (hasFile("Makefile")) {
|
|
7041
|
+
perms.push("Bash(make *)");
|
|
7042
|
+
}
|
|
7043
|
+
return [...new Set(perms)];
|
|
7044
|
+
}
|
|
7045
|
+
function ensurePermissions(fingerprint) {
|
|
7026
7046
|
const settingsPath = ".claude/settings.json";
|
|
7027
7047
|
let settings = {};
|
|
7028
7048
|
try {
|
|
@@ -7034,12 +7054,7 @@ function ensurePermissions() {
|
|
|
7034
7054
|
const permissions = settings.permissions ?? {};
|
|
7035
7055
|
const allow = permissions.allow;
|
|
7036
7056
|
if (Array.isArray(allow) && allow.length > 0) return;
|
|
7037
|
-
permissions.allow =
|
|
7038
|
-
"Bash(npm run *)",
|
|
7039
|
-
"Bash(npx vitest *)",
|
|
7040
|
-
"Bash(npx tsc *)",
|
|
7041
|
-
"Bash(git *)"
|
|
7042
|
-
];
|
|
7057
|
+
permissions.allow = derivePermissions(fingerprint);
|
|
7043
7058
|
settings.permissions = permissions;
|
|
7044
7059
|
if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
|
|
7045
7060
|
fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
@@ -7047,20 +7062,20 @@ function ensurePermissions() {
|
|
|
7047
7062
|
function displayTokenUsage() {
|
|
7048
7063
|
const summary = getUsageSummary();
|
|
7049
7064
|
if (summary.length === 0) {
|
|
7050
|
-
console.log(
|
|
7065
|
+
console.log(chalk9.dim(" Token tracking not available for this provider.\n"));
|
|
7051
7066
|
return;
|
|
7052
7067
|
}
|
|
7053
|
-
console.log(
|
|
7068
|
+
console.log(chalk9.bold(" Token usage:\n"));
|
|
7054
7069
|
let totalIn = 0;
|
|
7055
7070
|
let totalOut = 0;
|
|
7056
7071
|
for (const m of summary) {
|
|
7057
7072
|
totalIn += m.inputTokens;
|
|
7058
7073
|
totalOut += m.outputTokens;
|
|
7059
|
-
const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ?
|
|
7060
|
-
console.log(` ${
|
|
7074
|
+
const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ? chalk9.dim(` (cache: ${m.cacheReadTokens.toLocaleString()} read, ${m.cacheWriteTokens.toLocaleString()} write)`) : "";
|
|
7075
|
+
console.log(` ${chalk9.dim(m.model)}: ${m.inputTokens.toLocaleString()} in / ${m.outputTokens.toLocaleString()} out (${m.calls} call${m.calls === 1 ? "" : "s"})${cacheInfo}`);
|
|
7061
7076
|
}
|
|
7062
7077
|
if (summary.length > 1) {
|
|
7063
|
-
console.log(` ${
|
|
7078
|
+
console.log(` ${chalk9.dim("Total")}: ${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out`);
|
|
7064
7079
|
}
|
|
7065
7080
|
console.log("");
|
|
7066
7081
|
}
|
|
@@ -7081,14 +7096,14 @@ function writeErrorLog(config, rawOutput, error, stopReason) {
|
|
|
7081
7096
|
lines.push("## Raw LLM Output", "```", rawOutput || "(empty)", "```");
|
|
7082
7097
|
fs24.mkdirSync(path19.join(process.cwd(), ".caliber"), { recursive: true });
|
|
7083
7098
|
fs24.writeFileSync(logPath, lines.join("\n"));
|
|
7084
|
-
console.log(
|
|
7099
|
+
console.log(chalk9.dim(`
|
|
7085
7100
|
Error log written to .caliber/error-log.md`));
|
|
7086
7101
|
} catch {
|
|
7087
7102
|
}
|
|
7088
7103
|
}
|
|
7089
7104
|
|
|
7090
7105
|
// src/commands/undo.ts
|
|
7091
|
-
import
|
|
7106
|
+
import chalk10 from "chalk";
|
|
7092
7107
|
import ora3 from "ora";
|
|
7093
7108
|
function undoCommand() {
|
|
7094
7109
|
const spinner = ora3("Reverting setup...").start();
|
|
@@ -7101,26 +7116,26 @@ function undoCommand() {
|
|
|
7101
7116
|
trackUndoExecuted();
|
|
7102
7117
|
spinner.succeed("Setup reverted successfully.\n");
|
|
7103
7118
|
if (restored.length > 0) {
|
|
7104
|
-
console.log(
|
|
7119
|
+
console.log(chalk10.cyan(" Restored from backup:"));
|
|
7105
7120
|
for (const file of restored) {
|
|
7106
|
-
console.log(` ${
|
|
7121
|
+
console.log(` ${chalk10.green("\u21A9")} ${file}`);
|
|
7107
7122
|
}
|
|
7108
7123
|
}
|
|
7109
7124
|
if (removed.length > 0) {
|
|
7110
|
-
console.log(
|
|
7125
|
+
console.log(chalk10.cyan(" Removed:"));
|
|
7111
7126
|
for (const file of removed) {
|
|
7112
|
-
console.log(` ${
|
|
7127
|
+
console.log(` ${chalk10.red("\u2717")} ${file}`);
|
|
7113
7128
|
}
|
|
7114
7129
|
}
|
|
7115
7130
|
console.log("");
|
|
7116
7131
|
} catch (err) {
|
|
7117
|
-
spinner.fail(
|
|
7132
|
+
spinner.fail(chalk10.red(err instanceof Error ? err.message : "Undo failed"));
|
|
7118
7133
|
throw new Error("__exit__");
|
|
7119
7134
|
}
|
|
7120
7135
|
}
|
|
7121
7136
|
|
|
7122
7137
|
// src/commands/status.ts
|
|
7123
|
-
import
|
|
7138
|
+
import chalk11 from "chalk";
|
|
7124
7139
|
import fs25 from "fs";
|
|
7125
7140
|
init_config();
|
|
7126
7141
|
async function statusCommand(options) {
|
|
@@ -7135,40 +7150,40 @@ async function statusCommand(options) {
|
|
|
7135
7150
|
}, null, 2));
|
|
7136
7151
|
return;
|
|
7137
7152
|
}
|
|
7138
|
-
console.log(
|
|
7153
|
+
console.log(chalk11.bold("\nCaliber Status\n"));
|
|
7139
7154
|
if (config) {
|
|
7140
|
-
console.log(` LLM: ${
|
|
7155
|
+
console.log(` LLM: ${chalk11.green(config.provider)} (${config.model})`);
|
|
7141
7156
|
} else {
|
|
7142
|
-
console.log(` LLM: ${
|
|
7157
|
+
console.log(` LLM: ${chalk11.yellow("Not configured")} \u2014 run ${chalk11.hex("#83D1EB")("caliber config")}`);
|
|
7143
7158
|
}
|
|
7144
7159
|
if (!manifest) {
|
|
7145
|
-
console.log(` Setup: ${
|
|
7146
|
-
console.log(
|
|
7160
|
+
console.log(` Setup: ${chalk11.dim("No setup applied")}`);
|
|
7161
|
+
console.log(chalk11.dim("\n Run ") + chalk11.hex("#83D1EB")("caliber init") + chalk11.dim(" to get started.\n"));
|
|
7147
7162
|
return;
|
|
7148
7163
|
}
|
|
7149
|
-
console.log(` Files managed: ${
|
|
7164
|
+
console.log(` Files managed: ${chalk11.cyan(manifest.entries.length.toString())}`);
|
|
7150
7165
|
for (const entry of manifest.entries) {
|
|
7151
7166
|
const exists = fs25.existsSync(entry.path);
|
|
7152
|
-
const icon = exists ?
|
|
7167
|
+
const icon = exists ? chalk11.green("\u2713") : chalk11.red("\u2717");
|
|
7153
7168
|
console.log(` ${icon} ${entry.path} (${entry.action})`);
|
|
7154
7169
|
}
|
|
7155
7170
|
console.log("");
|
|
7156
7171
|
}
|
|
7157
7172
|
|
|
7158
7173
|
// src/commands/regenerate.ts
|
|
7159
|
-
import
|
|
7174
|
+
import chalk12 from "chalk";
|
|
7160
7175
|
import ora4 from "ora";
|
|
7161
7176
|
import select6 from "@inquirer/select";
|
|
7162
7177
|
init_config();
|
|
7163
7178
|
async function regenerateCommand(options) {
|
|
7164
7179
|
const config = loadConfig();
|
|
7165
7180
|
if (!config) {
|
|
7166
|
-
console.log(
|
|
7181
|
+
console.log(chalk12.red("No LLM provider configured. Run ") + chalk12.hex("#83D1EB")("caliber config") + chalk12.red(" first."));
|
|
7167
7182
|
throw new Error("__exit__");
|
|
7168
7183
|
}
|
|
7169
7184
|
const manifest = readManifest();
|
|
7170
7185
|
if (!manifest) {
|
|
7171
|
-
console.log(
|
|
7186
|
+
console.log(chalk12.yellow("No existing setup found. Run ") + chalk12.hex("#83D1EB")("caliber init") + chalk12.yellow(" first."));
|
|
7172
7187
|
throw new Error("__exit__");
|
|
7173
7188
|
}
|
|
7174
7189
|
const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
|
|
@@ -7179,7 +7194,7 @@ async function regenerateCommand(options) {
|
|
|
7179
7194
|
const baselineScore = computeLocalScore(process.cwd(), targetAgent);
|
|
7180
7195
|
displayScoreSummary(baselineScore);
|
|
7181
7196
|
if (baselineScore.score === 100) {
|
|
7182
|
-
console.log(
|
|
7197
|
+
console.log(chalk12.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
|
|
7183
7198
|
return;
|
|
7184
7199
|
}
|
|
7185
7200
|
const genSpinner = ora4("Regenerating setup...").start();
|
|
@@ -7217,21 +7232,21 @@ async function regenerateCommand(options) {
|
|
|
7217
7232
|
throw new Error("__exit__");
|
|
7218
7233
|
}
|
|
7219
7234
|
genSpinner.succeed("Setup regenerated");
|
|
7220
|
-
const setupFiles = collectSetupFiles(generatedSetup);
|
|
7235
|
+
const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
|
|
7221
7236
|
const staged = stageFiles(setupFiles, process.cwd());
|
|
7222
7237
|
const totalChanges = staged.newFiles + staged.modifiedFiles;
|
|
7223
|
-
console.log(
|
|
7224
|
-
${
|
|
7238
|
+
console.log(chalk12.dim(`
|
|
7239
|
+
${chalk12.green(`${staged.newFiles} new`)} / ${chalk12.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
|
|
7225
7240
|
`));
|
|
7226
7241
|
if (totalChanges === 0) {
|
|
7227
|
-
console.log(
|
|
7242
|
+
console.log(chalk12.dim(" No changes needed \u2014 your configs are already up to date.\n"));
|
|
7228
7243
|
cleanupStaging();
|
|
7229
7244
|
return;
|
|
7230
7245
|
}
|
|
7231
7246
|
if (options.dryRun) {
|
|
7232
|
-
console.log(
|
|
7247
|
+
console.log(chalk12.yellow("[Dry run] Would write:"));
|
|
7233
7248
|
for (const f of staged.stagedFiles) {
|
|
7234
|
-
console.log(` ${f.isNew ?
|
|
7249
|
+
console.log(` ${f.isNew ? chalk12.green("+") : chalk12.yellow("~")} ${f.relativePath}`);
|
|
7235
7250
|
}
|
|
7236
7251
|
cleanupStaging();
|
|
7237
7252
|
return;
|
|
@@ -7250,7 +7265,7 @@ async function regenerateCommand(options) {
|
|
|
7250
7265
|
});
|
|
7251
7266
|
cleanupStaging();
|
|
7252
7267
|
if (action === "decline") {
|
|
7253
|
-
console.log(
|
|
7268
|
+
console.log(chalk12.dim("Regeneration cancelled. No files were modified."));
|
|
7254
7269
|
return;
|
|
7255
7270
|
}
|
|
7256
7271
|
const writeSpinner = ora4("Writing config files...").start();
|
|
@@ -7258,20 +7273,20 @@ async function regenerateCommand(options) {
|
|
|
7258
7273
|
const result = writeSetup(generatedSetup);
|
|
7259
7274
|
writeSpinner.succeed("Config files written");
|
|
7260
7275
|
for (const file of result.written) {
|
|
7261
|
-
console.log(` ${
|
|
7276
|
+
console.log(` ${chalk12.green("\u2713")} ${file}`);
|
|
7262
7277
|
}
|
|
7263
7278
|
if (result.deleted.length > 0) {
|
|
7264
7279
|
for (const file of result.deleted) {
|
|
7265
|
-
console.log(` ${
|
|
7280
|
+
console.log(` ${chalk12.red("\u2717")} ${file}`);
|
|
7266
7281
|
}
|
|
7267
7282
|
}
|
|
7268
7283
|
if (result.backupDir) {
|
|
7269
|
-
console.log(
|
|
7284
|
+
console.log(chalk12.dim(`
|
|
7270
7285
|
Backups saved to ${result.backupDir}`));
|
|
7271
7286
|
}
|
|
7272
7287
|
} catch (err) {
|
|
7273
7288
|
writeSpinner.fail("Failed to write files");
|
|
7274
|
-
console.error(
|
|
7289
|
+
console.error(chalk12.red(err instanceof Error ? err.message : "Unknown error"));
|
|
7275
7290
|
throw new Error("__exit__");
|
|
7276
7291
|
}
|
|
7277
7292
|
const sha = getCurrentHeadSha();
|
|
@@ -7283,25 +7298,25 @@ async function regenerateCommand(options) {
|
|
|
7283
7298
|
const afterScore = computeLocalScore(process.cwd(), targetAgent);
|
|
7284
7299
|
if (afterScore.score < baselineScore.score) {
|
|
7285
7300
|
console.log("");
|
|
7286
|
-
console.log(
|
|
7301
|
+
console.log(chalk12.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
|
|
7287
7302
|
try {
|
|
7288
7303
|
const { restored, removed } = undoSetup();
|
|
7289
7304
|
if (restored.length > 0 || removed.length > 0) {
|
|
7290
|
-
console.log(
|
|
7305
|
+
console.log(chalk12.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
|
|
7291
7306
|
}
|
|
7292
7307
|
} catch {
|
|
7293
7308
|
}
|
|
7294
|
-
console.log(
|
|
7309
|
+
console.log(chalk12.dim(" Run ") + chalk12.hex("#83D1EB")("caliber init --force") + chalk12.dim(" to override.\n"));
|
|
7295
7310
|
return;
|
|
7296
7311
|
}
|
|
7297
7312
|
displayScoreDelta(baselineScore, afterScore);
|
|
7298
7313
|
trackRegenerateCompleted(action, Date.now());
|
|
7299
|
-
console.log(
|
|
7300
|
-
console.log(
|
|
7314
|
+
console.log(chalk12.bold.green(" Regeneration complete!"));
|
|
7315
|
+
console.log(chalk12.dim(" Run ") + chalk12.hex("#83D1EB")("caliber undo") + chalk12.dim(" to revert changes.\n"));
|
|
7301
7316
|
}
|
|
7302
7317
|
|
|
7303
7318
|
// src/commands/score.ts
|
|
7304
|
-
import
|
|
7319
|
+
import chalk13 from "chalk";
|
|
7305
7320
|
async function scoreCommand(options) {
|
|
7306
7321
|
const dir = process.cwd();
|
|
7307
7322
|
const target = options.agent ?? readState()?.targetAgent;
|
|
@@ -7316,14 +7331,14 @@ async function scoreCommand(options) {
|
|
|
7316
7331
|
return;
|
|
7317
7332
|
}
|
|
7318
7333
|
displayScore(result);
|
|
7319
|
-
const separator =
|
|
7334
|
+
const separator = chalk13.gray(" " + "\u2500".repeat(53));
|
|
7320
7335
|
console.log(separator);
|
|
7321
7336
|
if (result.score < 40) {
|
|
7322
|
-
console.log(
|
|
7337
|
+
console.log(chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber init") + chalk13.gray(" to generate a complete, optimized setup."));
|
|
7323
7338
|
} else if (result.score < 70) {
|
|
7324
|
-
console.log(
|
|
7339
|
+
console.log(chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber init") + chalk13.gray(" to improve your setup."));
|
|
7325
7340
|
} else {
|
|
7326
|
-
console.log(
|
|
7341
|
+
console.log(chalk13.green(" Looking good!") + chalk13.gray(" Run ") + chalk13.hex("#83D1EB")("caliber regenerate") + chalk13.gray(" to rebuild from scratch."));
|
|
7327
7342
|
}
|
|
7328
7343
|
console.log("");
|
|
7329
7344
|
}
|
|
@@ -7331,7 +7346,7 @@ async function scoreCommand(options) {
|
|
|
7331
7346
|
// src/commands/refresh.ts
|
|
7332
7347
|
import fs28 from "fs";
|
|
7333
7348
|
import path22 from "path";
|
|
7334
|
-
import
|
|
7349
|
+
import chalk14 from "chalk";
|
|
7335
7350
|
import ora5 from "ora";
|
|
7336
7351
|
|
|
7337
7352
|
// src/lib/git-diff.ts
|
|
@@ -7530,7 +7545,7 @@ function discoverGitRepos(parentDir) {
|
|
|
7530
7545
|
}
|
|
7531
7546
|
async function refreshSingleRepo(repoDir, options) {
|
|
7532
7547
|
const quiet = !!options.quiet;
|
|
7533
|
-
const prefix = options.label ? `${
|
|
7548
|
+
const prefix = options.label ? `${chalk14.bold(options.label)} ` : "";
|
|
7534
7549
|
const state = readState();
|
|
7535
7550
|
const lastSha = state?.lastRefreshSha ?? null;
|
|
7536
7551
|
const diff = collectDiff(lastSha);
|
|
@@ -7539,7 +7554,7 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
7539
7554
|
if (currentSha) {
|
|
7540
7555
|
writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
7541
7556
|
}
|
|
7542
|
-
log2(quiet,
|
|
7557
|
+
log2(quiet, chalk14.dim(`${prefix}No changes since last refresh.`));
|
|
7543
7558
|
return;
|
|
7544
7559
|
}
|
|
7545
7560
|
const spinner = quiet ? null : ora5(`${prefix}Analyzing changes...`).start();
|
|
@@ -7571,10 +7586,10 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
7571
7586
|
if (options.dryRun) {
|
|
7572
7587
|
spinner?.info(`${prefix}Dry run \u2014 would update:`);
|
|
7573
7588
|
for (const doc of response.docsUpdated) {
|
|
7574
|
-
console.log(` ${
|
|
7589
|
+
console.log(` ${chalk14.yellow("~")} ${doc}`);
|
|
7575
7590
|
}
|
|
7576
7591
|
if (response.changesSummary) {
|
|
7577
|
-
console.log(
|
|
7592
|
+
console.log(chalk14.dim(`
|
|
7578
7593
|
${response.changesSummary}`));
|
|
7579
7594
|
}
|
|
7580
7595
|
return;
|
|
@@ -7583,10 +7598,10 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
7583
7598
|
trackRefreshCompleted(written.length, Date.now());
|
|
7584
7599
|
spinner?.succeed(`${prefix}Updated ${written.length} doc${written.length === 1 ? "" : "s"}`);
|
|
7585
7600
|
for (const file of written) {
|
|
7586
|
-
log2(quiet, ` ${
|
|
7601
|
+
log2(quiet, ` ${chalk14.green("\u2713")} ${file}`);
|
|
7587
7602
|
}
|
|
7588
7603
|
if (response.changesSummary) {
|
|
7589
|
-
log2(quiet,
|
|
7604
|
+
log2(quiet, chalk14.dim(`
|
|
7590
7605
|
${response.changesSummary}`));
|
|
7591
7606
|
}
|
|
7592
7607
|
if (currentSha) {
|
|
@@ -7603,7 +7618,7 @@ async function refreshCommand(options) {
|
|
|
7603
7618
|
const config = loadConfig();
|
|
7604
7619
|
if (!config) {
|
|
7605
7620
|
if (quiet) return;
|
|
7606
|
-
console.log(
|
|
7621
|
+
console.log(chalk14.red("No LLM provider configured. Run ") + chalk14.hex("#83D1EB")("caliber config") + chalk14.red(" (e.g. choose Cursor) or set an API key."));
|
|
7607
7622
|
throw new Error("__exit__");
|
|
7608
7623
|
}
|
|
7609
7624
|
await validateModel({ fast: true });
|
|
@@ -7614,10 +7629,10 @@ async function refreshCommand(options) {
|
|
|
7614
7629
|
const repos = discoverGitRepos(process.cwd());
|
|
7615
7630
|
if (repos.length === 0) {
|
|
7616
7631
|
if (quiet) return;
|
|
7617
|
-
console.log(
|
|
7632
|
+
console.log(chalk14.red("Not inside a git repository and no git repos found in child directories."));
|
|
7618
7633
|
throw new Error("__exit__");
|
|
7619
7634
|
}
|
|
7620
|
-
log2(quiet,
|
|
7635
|
+
log2(quiet, chalk14.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
|
|
7621
7636
|
`));
|
|
7622
7637
|
const originalDir = process.cwd();
|
|
7623
7638
|
for (const repo of repos) {
|
|
@@ -7627,7 +7642,7 @@ async function refreshCommand(options) {
|
|
|
7627
7642
|
await refreshSingleRepo(repo, { ...options, label: repoName });
|
|
7628
7643
|
} catch (err) {
|
|
7629
7644
|
if (err instanceof Error && err.message === "__exit__") continue;
|
|
7630
|
-
log2(quiet,
|
|
7645
|
+
log2(quiet, chalk14.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
|
|
7631
7646
|
}
|
|
7632
7647
|
}
|
|
7633
7648
|
process.chdir(originalDir);
|
|
@@ -7635,13 +7650,13 @@ async function refreshCommand(options) {
|
|
|
7635
7650
|
if (err instanceof Error && err.message === "__exit__") throw err;
|
|
7636
7651
|
if (quiet) return;
|
|
7637
7652
|
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
7638
|
-
console.log(
|
|
7653
|
+
console.log(chalk14.red(`Refresh failed: ${msg}`));
|
|
7639
7654
|
throw new Error("__exit__");
|
|
7640
7655
|
}
|
|
7641
7656
|
}
|
|
7642
7657
|
|
|
7643
7658
|
// src/commands/hooks.ts
|
|
7644
|
-
import
|
|
7659
|
+
import chalk15 from "chalk";
|
|
7645
7660
|
var HOOKS = [
|
|
7646
7661
|
{
|
|
7647
7662
|
id: "session-end",
|
|
@@ -7661,13 +7676,13 @@ var HOOKS = [
|
|
|
7661
7676
|
}
|
|
7662
7677
|
];
|
|
7663
7678
|
function printStatus() {
|
|
7664
|
-
console.log(
|
|
7679
|
+
console.log(chalk15.bold("\n Hooks\n"));
|
|
7665
7680
|
for (const hook of HOOKS) {
|
|
7666
7681
|
const installed = hook.isInstalled();
|
|
7667
|
-
const icon = installed ?
|
|
7668
|
-
const state = installed ?
|
|
7682
|
+
const icon = installed ? chalk15.green("\u2713") : chalk15.dim("\u2717");
|
|
7683
|
+
const state = installed ? chalk15.green("enabled") : chalk15.dim("disabled");
|
|
7669
7684
|
console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
|
|
7670
|
-
console.log(
|
|
7685
|
+
console.log(chalk15.dim(` ${hook.description}`));
|
|
7671
7686
|
}
|
|
7672
7687
|
console.log("");
|
|
7673
7688
|
}
|
|
@@ -7676,9 +7691,9 @@ async function hooksCommand(options) {
|
|
|
7676
7691
|
for (const hook of HOOKS) {
|
|
7677
7692
|
const result = hook.install();
|
|
7678
7693
|
if (result.alreadyInstalled) {
|
|
7679
|
-
console.log(
|
|
7694
|
+
console.log(chalk15.dim(` ${hook.label} already enabled.`));
|
|
7680
7695
|
} else {
|
|
7681
|
-
console.log(
|
|
7696
|
+
console.log(chalk15.green(" \u2713") + ` ${hook.label} enabled`);
|
|
7682
7697
|
}
|
|
7683
7698
|
}
|
|
7684
7699
|
return;
|
|
@@ -7687,9 +7702,9 @@ async function hooksCommand(options) {
|
|
|
7687
7702
|
for (const hook of HOOKS) {
|
|
7688
7703
|
const result = hook.remove();
|
|
7689
7704
|
if (result.notFound) {
|
|
7690
|
-
console.log(
|
|
7705
|
+
console.log(chalk15.dim(` ${hook.label} already disabled.`));
|
|
7691
7706
|
} else {
|
|
7692
|
-
console.log(
|
|
7707
|
+
console.log(chalk15.green(" \u2713") + ` ${hook.label} removed`);
|
|
7693
7708
|
}
|
|
7694
7709
|
}
|
|
7695
7710
|
return;
|
|
@@ -7704,18 +7719,18 @@ async function hooksCommand(options) {
|
|
|
7704
7719
|
const states = HOOKS.map((h) => h.isInstalled());
|
|
7705
7720
|
function render() {
|
|
7706
7721
|
const lines = [];
|
|
7707
|
-
lines.push(
|
|
7722
|
+
lines.push(chalk15.bold(" Hooks"));
|
|
7708
7723
|
lines.push("");
|
|
7709
7724
|
for (let i = 0; i < HOOKS.length; i++) {
|
|
7710
7725
|
const hook = HOOKS[i];
|
|
7711
7726
|
const enabled = states[i];
|
|
7712
|
-
const toggle = enabled ?
|
|
7713
|
-
const ptr = i === cursor ?
|
|
7727
|
+
const toggle = enabled ? chalk15.green("[on] ") : chalk15.dim("[off]");
|
|
7728
|
+
const ptr = i === cursor ? chalk15.cyan(">") : " ";
|
|
7714
7729
|
lines.push(` ${ptr} ${toggle} ${hook.label}`);
|
|
7715
|
-
lines.push(
|
|
7730
|
+
lines.push(chalk15.dim(` ${hook.description}`));
|
|
7716
7731
|
}
|
|
7717
7732
|
lines.push("");
|
|
7718
|
-
lines.push(
|
|
7733
|
+
lines.push(chalk15.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
|
|
7719
7734
|
return lines.join("\n");
|
|
7720
7735
|
}
|
|
7721
7736
|
function draw(initial) {
|
|
@@ -7746,16 +7761,16 @@ async function hooksCommand(options) {
|
|
|
7746
7761
|
const wantEnabled = states[i];
|
|
7747
7762
|
if (wantEnabled && !wasInstalled) {
|
|
7748
7763
|
hook.install();
|
|
7749
|
-
console.log(
|
|
7764
|
+
console.log(chalk15.green(" \u2713") + ` ${hook.label} enabled`);
|
|
7750
7765
|
changed++;
|
|
7751
7766
|
} else if (!wantEnabled && wasInstalled) {
|
|
7752
7767
|
hook.remove();
|
|
7753
|
-
console.log(
|
|
7768
|
+
console.log(chalk15.green(" \u2713") + ` ${hook.label} disabled`);
|
|
7754
7769
|
changed++;
|
|
7755
7770
|
}
|
|
7756
7771
|
}
|
|
7757
7772
|
if (changed === 0) {
|
|
7758
|
-
console.log(
|
|
7773
|
+
console.log(chalk15.dim(" No changes."));
|
|
7759
7774
|
}
|
|
7760
7775
|
console.log("");
|
|
7761
7776
|
}
|
|
@@ -7791,7 +7806,7 @@ async function hooksCommand(options) {
|
|
|
7791
7806
|
case "\x1B":
|
|
7792
7807
|
case "":
|
|
7793
7808
|
cleanup();
|
|
7794
|
-
console.log(
|
|
7809
|
+
console.log(chalk15.dim("\n Cancelled.\n"));
|
|
7795
7810
|
resolve2();
|
|
7796
7811
|
break;
|
|
7797
7812
|
}
|
|
@@ -7802,50 +7817,50 @@ async function hooksCommand(options) {
|
|
|
7802
7817
|
|
|
7803
7818
|
// src/commands/config.ts
|
|
7804
7819
|
init_config();
|
|
7805
|
-
import
|
|
7820
|
+
import chalk16 from "chalk";
|
|
7806
7821
|
async function configCommand() {
|
|
7807
7822
|
const existing = loadConfig();
|
|
7808
7823
|
if (existing) {
|
|
7809
|
-
const displayModel = existing
|
|
7824
|
+
const displayModel = getDisplayModel(existing);
|
|
7810
7825
|
const fastModel = getFastModel();
|
|
7811
|
-
console.log(
|
|
7812
|
-
console.log(` Provider: ${
|
|
7813
|
-
console.log(` Model: ${
|
|
7826
|
+
console.log(chalk16.bold("\nCurrent Configuration\n"));
|
|
7827
|
+
console.log(` Provider: ${chalk16.cyan(existing.provider)}`);
|
|
7828
|
+
console.log(` Model: ${chalk16.cyan(displayModel)}`);
|
|
7814
7829
|
if (fastModel) {
|
|
7815
|
-
console.log(` Scan: ${
|
|
7830
|
+
console.log(` Scan: ${chalk16.cyan(fastModel)}`);
|
|
7816
7831
|
}
|
|
7817
7832
|
if (existing.apiKey) {
|
|
7818
7833
|
const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
|
|
7819
|
-
console.log(` API Key: ${
|
|
7834
|
+
console.log(` API Key: ${chalk16.dim(masked)}`);
|
|
7820
7835
|
}
|
|
7821
7836
|
if (existing.provider === "cursor") {
|
|
7822
|
-
console.log(` Seat: ${
|
|
7837
|
+
console.log(` Seat: ${chalk16.dim("Cursor (agent acp)")}`);
|
|
7823
7838
|
}
|
|
7824
7839
|
if (existing.provider === "claude-cli") {
|
|
7825
|
-
console.log(` Seat: ${
|
|
7840
|
+
console.log(` Seat: ${chalk16.dim("Claude Code (claude -p)")}`);
|
|
7826
7841
|
}
|
|
7827
7842
|
if (existing.baseUrl) {
|
|
7828
|
-
console.log(` Base URL: ${
|
|
7843
|
+
console.log(` Base URL: ${chalk16.dim(existing.baseUrl)}`);
|
|
7829
7844
|
}
|
|
7830
7845
|
if (existing.vertexProjectId) {
|
|
7831
|
-
console.log(` Vertex Project: ${
|
|
7832
|
-
console.log(` Vertex Region: ${
|
|
7846
|
+
console.log(` Vertex Project: ${chalk16.dim(existing.vertexProjectId)}`);
|
|
7847
|
+
console.log(` Vertex Region: ${chalk16.dim(existing.vertexRegion || "us-east5")}`);
|
|
7833
7848
|
}
|
|
7834
|
-
console.log(` Source: ${
|
|
7849
|
+
console.log(` Source: ${chalk16.dim(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY || process.env.VERTEX_PROJECT_ID || process.env.CALIBER_USE_CURSOR_SEAT || process.env.CALIBER_USE_CLAUDE_CLI ? "environment variables" : getConfigFilePath())}`);
|
|
7835
7850
|
console.log("");
|
|
7836
7851
|
}
|
|
7837
7852
|
await runInteractiveProviderSetup();
|
|
7838
7853
|
const updated = loadConfig();
|
|
7839
7854
|
if (updated) trackConfigProviderSet(updated.provider);
|
|
7840
|
-
console.log(
|
|
7841
|
-
console.log(
|
|
7855
|
+
console.log(chalk16.green("\n\u2713 Configuration saved"));
|
|
7856
|
+
console.log(chalk16.dim(` ${getConfigFilePath()}
|
|
7842
7857
|
`));
|
|
7843
|
-
console.log(
|
|
7844
|
-
console.log(
|
|
7858
|
+
console.log(chalk16.dim(" You can also set environment variables instead:"));
|
|
7859
|
+
console.log(chalk16.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
|
|
7845
7860
|
}
|
|
7846
7861
|
|
|
7847
7862
|
// src/commands/learn.ts
|
|
7848
|
-
import
|
|
7863
|
+
import chalk17 from "chalk";
|
|
7849
7864
|
|
|
7850
7865
|
// src/learner/stdin.ts
|
|
7851
7866
|
var STDIN_TIMEOUT_MS = 5e3;
|
|
@@ -8153,46 +8168,46 @@ async function learnFinalizeCommand() {
|
|
|
8153
8168
|
async function learnInstallCommand() {
|
|
8154
8169
|
const result = installLearningHooks();
|
|
8155
8170
|
if (result.alreadyInstalled) {
|
|
8156
|
-
console.log(
|
|
8171
|
+
console.log(chalk17.dim("Learning hooks already installed."));
|
|
8157
8172
|
return;
|
|
8158
8173
|
}
|
|
8159
|
-
console.log(
|
|
8160
|
-
console.log(
|
|
8161
|
-
console.log(
|
|
8174
|
+
console.log(chalk17.green("\u2713") + " Learning hooks installed in .claude/settings.json");
|
|
8175
|
+
console.log(chalk17.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
|
|
8176
|
+
console.log(chalk17.dim(" Session learnings will be written to CLAUDE.md and skills."));
|
|
8162
8177
|
}
|
|
8163
8178
|
async function learnRemoveCommand() {
|
|
8164
8179
|
const result = removeLearningHooks();
|
|
8165
8180
|
if (result.notFound) {
|
|
8166
|
-
console.log(
|
|
8181
|
+
console.log(chalk17.dim("Learning hooks not found."));
|
|
8167
8182
|
return;
|
|
8168
8183
|
}
|
|
8169
|
-
console.log(
|
|
8184
|
+
console.log(chalk17.green("\u2713") + " Learning hooks removed from .claude/settings.json");
|
|
8170
8185
|
}
|
|
8171
8186
|
async function learnStatusCommand() {
|
|
8172
8187
|
const installed = areLearningHooksInstalled();
|
|
8173
8188
|
const state = readState2();
|
|
8174
8189
|
const eventCount = getEventCount();
|
|
8175
|
-
console.log(
|
|
8190
|
+
console.log(chalk17.bold("Session Learning Status"));
|
|
8176
8191
|
console.log();
|
|
8177
8192
|
if (installed) {
|
|
8178
|
-
console.log(
|
|
8193
|
+
console.log(chalk17.green("\u2713") + " Learning hooks are " + chalk17.green("installed"));
|
|
8179
8194
|
} else {
|
|
8180
|
-
console.log(
|
|
8181
|
-
console.log(
|
|
8195
|
+
console.log(chalk17.dim("\u2717") + " Learning hooks are " + chalk17.yellow("not installed"));
|
|
8196
|
+
console.log(chalk17.dim(" Run `caliber learn install` to enable session learning."));
|
|
8182
8197
|
}
|
|
8183
8198
|
console.log();
|
|
8184
|
-
console.log(`Events recorded: ${
|
|
8185
|
-
console.log(`Total this session: ${
|
|
8199
|
+
console.log(`Events recorded: ${chalk17.cyan(String(eventCount))}`);
|
|
8200
|
+
console.log(`Total this session: ${chalk17.cyan(String(state.eventCount))}`);
|
|
8186
8201
|
if (state.lastAnalysisTimestamp) {
|
|
8187
|
-
console.log(`Last analysis: ${
|
|
8202
|
+
console.log(`Last analysis: ${chalk17.cyan(state.lastAnalysisTimestamp)}`);
|
|
8188
8203
|
} else {
|
|
8189
|
-
console.log(`Last analysis: ${
|
|
8204
|
+
console.log(`Last analysis: ${chalk17.dim("none")}`);
|
|
8190
8205
|
}
|
|
8191
8206
|
const learnedSection = readLearnedSection();
|
|
8192
8207
|
if (learnedSection) {
|
|
8193
8208
|
const lineCount = learnedSection.split("\n").filter(Boolean).length;
|
|
8194
8209
|
console.log(`
|
|
8195
|
-
Learned items in CLAUDE.md: ${
|
|
8210
|
+
Learned items in CLAUDE.md: ${chalk17.cyan(String(lineCount))}`);
|
|
8196
8211
|
}
|
|
8197
8212
|
}
|
|
8198
8213
|
|
|
@@ -8277,7 +8292,7 @@ import fs32 from "fs";
|
|
|
8277
8292
|
import path26 from "path";
|
|
8278
8293
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8279
8294
|
import { execSync as execSync14 } from "child_process";
|
|
8280
|
-
import
|
|
8295
|
+
import chalk18 from "chalk";
|
|
8281
8296
|
import ora6 from "ora";
|
|
8282
8297
|
import confirm2 from "@inquirer/confirm";
|
|
8283
8298
|
var __dirname_vc = path26.dirname(fileURLToPath2(import.meta.url));
|
|
@@ -8311,17 +8326,17 @@ async function checkForUpdates() {
|
|
|
8311
8326
|
const isInteractive = process.stdin.isTTY === true;
|
|
8312
8327
|
if (!isInteractive) {
|
|
8313
8328
|
console.log(
|
|
8314
|
-
|
|
8329
|
+
chalk18.yellow(
|
|
8315
8330
|
`
|
|
8316
8331
|
Update available: ${current} -> ${latest}
|
|
8317
|
-
Run ${
|
|
8332
|
+
Run ${chalk18.bold("npm install -g @rely-ai/caliber")} to upgrade.
|
|
8318
8333
|
`
|
|
8319
8334
|
)
|
|
8320
8335
|
);
|
|
8321
8336
|
return;
|
|
8322
8337
|
}
|
|
8323
8338
|
console.log(
|
|
8324
|
-
|
|
8339
|
+
chalk18.yellow(`
|
|
8325
8340
|
Update available: ${current} -> ${latest}`)
|
|
8326
8341
|
);
|
|
8327
8342
|
const shouldUpdate = await confirm2({ message: "Would you like to update now? (Y/n)", default: true });
|
|
@@ -8339,13 +8354,13 @@ Update available: ${current} -> ${latest}`)
|
|
|
8339
8354
|
const installed = getInstalledVersion();
|
|
8340
8355
|
if (installed !== latest) {
|
|
8341
8356
|
spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
|
|
8342
|
-
console.log(
|
|
8357
|
+
console.log(chalk18.yellow(`Run ${chalk18.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
|
|
8343
8358
|
`));
|
|
8344
8359
|
return;
|
|
8345
8360
|
}
|
|
8346
|
-
spinner.succeed(
|
|
8361
|
+
spinner.succeed(chalk18.green(`Updated to ${latest}`));
|
|
8347
8362
|
const args = process.argv.slice(2);
|
|
8348
|
-
console.log(
|
|
8363
|
+
console.log(chalk18.dim(`
|
|
8349
8364
|
Restarting: caliber ${args.join(" ")}
|
|
8350
8365
|
`));
|
|
8351
8366
|
execSync14(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
|
|
@@ -8358,11 +8373,11 @@ Restarting: caliber ${args.join(" ")}
|
|
|
8358
8373
|
if (err instanceof Error) {
|
|
8359
8374
|
const stderr = err.stderr;
|
|
8360
8375
|
const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
|
|
8361
|
-
if (errMsg && !errMsg.includes("SIGTERM")) console.log(
|
|
8376
|
+
if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk18.dim(` ${errMsg}`));
|
|
8362
8377
|
}
|
|
8363
8378
|
console.log(
|
|
8364
|
-
|
|
8365
|
-
`Run ${
|
|
8379
|
+
chalk18.yellow(
|
|
8380
|
+
`Run ${chalk18.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
|
|
8366
8381
|
`
|
|
8367
8382
|
)
|
|
8368
8383
|
);
|