@rely-ai/caliber 1.45.0 → 1.45.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +591 -566
- package/package.json +2 -1
package/dist/bin.js
CHANGED
|
@@ -186,11 +186,19 @@ var resolve_caliber_exports = {};
|
|
|
186
186
|
__export(resolve_caliber_exports, {
|
|
187
187
|
isCaliberCommand: () => isCaliberCommand,
|
|
188
188
|
isNpxResolution: () => isNpxResolution,
|
|
189
|
+
pickExecutable: () => pickExecutable,
|
|
189
190
|
resetResolvedCaliber: () => resetResolvedCaliber,
|
|
190
191
|
resolveCaliber: () => resolveCaliber
|
|
191
192
|
});
|
|
192
193
|
import fs6 from "fs";
|
|
193
194
|
import { execSync as execSync5 } from "child_process";
|
|
195
|
+
function pickExecutable(out) {
|
|
196
|
+
const lines = out.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
197
|
+
if (process.platform === "win32") {
|
|
198
|
+
return lines.find((l) => WINDOWS_EXEC_EXT.test(l)) ?? lines[0] ?? "";
|
|
199
|
+
}
|
|
200
|
+
return lines[0] ?? "";
|
|
201
|
+
}
|
|
194
202
|
function resolveCaliber() {
|
|
195
203
|
if (_resolved) return _resolved;
|
|
196
204
|
const whichCmd = process.platform === "win32" ? "where caliber" : "which caliber";
|
|
@@ -199,7 +207,7 @@ function resolveCaliber() {
|
|
|
199
207
|
if (isNpx) {
|
|
200
208
|
try {
|
|
201
209
|
const out = execSync5(whichCmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
202
|
-
const caliberPath = out
|
|
210
|
+
const caliberPath = pickExecutable(out);
|
|
203
211
|
if (caliberPath) {
|
|
204
212
|
_resolved = caliberPath;
|
|
205
213
|
return _resolved;
|
|
@@ -211,7 +219,7 @@ function resolveCaliber() {
|
|
|
211
219
|
encoding: "utf-8",
|
|
212
220
|
stdio: ["pipe", "pipe", "pipe"]
|
|
213
221
|
}).trim();
|
|
214
|
-
const npxPath = out
|
|
222
|
+
const npxPath = pickExecutable(out);
|
|
215
223
|
if (npxPath) {
|
|
216
224
|
_resolved = `${npxPath} --yes @rely-ai/caliber`;
|
|
217
225
|
return _resolved;
|
|
@@ -226,7 +234,7 @@ function resolveCaliber() {
|
|
|
226
234
|
encoding: "utf-8",
|
|
227
235
|
stdio: ["pipe", "pipe", "pipe"]
|
|
228
236
|
}).trim();
|
|
229
|
-
const caliberPath = out
|
|
237
|
+
const caliberPath = pickExecutable(out);
|
|
230
238
|
if (caliberPath) {
|
|
231
239
|
_resolved = caliberPath;
|
|
232
240
|
return _resolved;
|
|
@@ -243,7 +251,8 @@ function resolveCaliber() {
|
|
|
243
251
|
}
|
|
244
252
|
function isNpxResolution() {
|
|
245
253
|
const r = resolveCaliber();
|
|
246
|
-
|
|
254
|
+
if (r === "npx --yes @rely-ai/caliber") return true;
|
|
255
|
+
return NPX_RESOLUTION_RE.test(r);
|
|
247
256
|
}
|
|
248
257
|
function resetResolvedCaliber() {
|
|
249
258
|
_resolved = null;
|
|
@@ -257,11 +266,13 @@ function isCaliberCommand(command, subcommandTail) {
|
|
|
257
266
|
if (command.endsWith(`/npx @rely-ai/caliber ${subcommandTail}`)) return true;
|
|
258
267
|
return false;
|
|
259
268
|
}
|
|
260
|
-
var _resolved;
|
|
269
|
+
var _resolved, WINDOWS_EXEC_EXT, NPX_RESOLUTION_RE;
|
|
261
270
|
var init_resolve_caliber = __esm({
|
|
262
271
|
"src/lib/resolve-caliber.ts"() {
|
|
263
272
|
"use strict";
|
|
264
273
|
_resolved = null;
|
|
274
|
+
WINDOWS_EXEC_EXT = /\.(cmd|exe|bat)$/i;
|
|
275
|
+
NPX_RESOLUTION_RE = /[\\/]npx(?:\.(?:cmd|exe|bat))? --yes @rely-ai\/caliber$/i;
|
|
265
276
|
}
|
|
266
277
|
});
|
|
267
278
|
|
|
@@ -969,7 +980,7 @@ __export(review_exports, {
|
|
|
969
980
|
promptReviewMethod: () => promptReviewMethod,
|
|
970
981
|
promptWantsReview: () => promptWantsReview
|
|
971
982
|
});
|
|
972
|
-
import
|
|
983
|
+
import chalk9 from "chalk";
|
|
973
984
|
import fs30 from "fs";
|
|
974
985
|
import select4 from "@inquirer/select";
|
|
975
986
|
import { createTwoFilesPatch } from "diff";
|
|
@@ -1008,7 +1019,7 @@ async function openReview(method, stagedFiles) {
|
|
|
1008
1019
|
proposedPath: f.proposedPath
|
|
1009
1020
|
}))
|
|
1010
1021
|
);
|
|
1011
|
-
console.log(
|
|
1022
|
+
console.log(chalk9.dim(" Diffs opened in your editor.\n"));
|
|
1012
1023
|
return;
|
|
1013
1024
|
}
|
|
1014
1025
|
const fileInfos = stagedFiles.map((file) => {
|
|
@@ -1039,8 +1050,8 @@ async function openReview(method, stagedFiles) {
|
|
|
1039
1050
|
async function interactiveDiffExplorer(files) {
|
|
1040
1051
|
if (!process.stdin.isTTY) {
|
|
1041
1052
|
for (const f of files) {
|
|
1042
|
-
const icon = f.isNew ?
|
|
1043
|
-
const stats = f.isNew ?
|
|
1053
|
+
const icon = f.isNew ? chalk9.green("+") : chalk9.yellow("~");
|
|
1054
|
+
const stats = f.isNew ? chalk9.dim(`${f.lines} lines`) : `${chalk9.green(`+${f.added}`)} ${chalk9.red(`-${f.removed}`)}`;
|
|
1044
1055
|
console.log(` ${icon} ${f.relativePath} ${stats}`);
|
|
1045
1056
|
}
|
|
1046
1057
|
console.log("");
|
|
@@ -1056,47 +1067,47 @@ async function interactiveDiffExplorer(files) {
|
|
|
1056
1067
|
}
|
|
1057
1068
|
function renderFileList() {
|
|
1058
1069
|
const lines = [];
|
|
1059
|
-
lines.push(
|
|
1070
|
+
lines.push(chalk9.bold(" Review changes"));
|
|
1060
1071
|
lines.push("");
|
|
1061
1072
|
for (let i = 0; i < files.length; i++) {
|
|
1062
1073
|
const f = files[i];
|
|
1063
|
-
const ptr = i === cursor ?
|
|
1064
|
-
const icon = f.isNew ?
|
|
1065
|
-
const stats = f.isNew ?
|
|
1074
|
+
const ptr = i === cursor ? chalk9.cyan(">") : " ";
|
|
1075
|
+
const icon = f.isNew ? chalk9.green("+") : chalk9.yellow("~");
|
|
1076
|
+
const stats = f.isNew ? chalk9.dim(`${f.lines} lines`) : `${chalk9.green(`+${f.added}`)} ${chalk9.red(`-${f.removed}`)}`;
|
|
1066
1077
|
lines.push(` ${ptr} ${icon} ${f.relativePath} ${stats}`);
|
|
1067
1078
|
}
|
|
1068
1079
|
lines.push("");
|
|
1069
|
-
lines.push(
|
|
1080
|
+
lines.push(chalk9.dim(" \u2191\u2193 navigate \u23CE view diff q done"));
|
|
1070
1081
|
return lines.join("\n");
|
|
1071
1082
|
}
|
|
1072
1083
|
function renderDiff(index) {
|
|
1073
1084
|
const f = files[index];
|
|
1074
1085
|
const lines = [];
|
|
1075
|
-
const header = f.isNew ? ` ${
|
|
1086
|
+
const header = f.isNew ? ` ${chalk9.green("+")} ${f.relativePath} ${chalk9.dim("(new file)")}` : ` ${chalk9.yellow("~")} ${f.relativePath} ${chalk9.green(`+${f.added}`)} ${chalk9.red(`-${f.removed}`)}`;
|
|
1076
1087
|
lines.push(header);
|
|
1077
|
-
lines.push(
|
|
1088
|
+
lines.push(chalk9.dim(" " + "\u2500".repeat(60)));
|
|
1078
1089
|
const patchLines = f.patch.split("\n");
|
|
1079
1090
|
const bodyLines = patchLines.slice(4);
|
|
1080
1091
|
const maxVisible = getTermHeight() - 4;
|
|
1081
1092
|
const visibleLines = bodyLines.slice(scrollOffset, scrollOffset + maxVisible);
|
|
1082
1093
|
for (const line of visibleLines) {
|
|
1083
1094
|
if (line.startsWith("+")) {
|
|
1084
|
-
lines.push(
|
|
1095
|
+
lines.push(chalk9.green(" " + line));
|
|
1085
1096
|
} else if (line.startsWith("-")) {
|
|
1086
|
-
lines.push(
|
|
1097
|
+
lines.push(chalk9.red(" " + line));
|
|
1087
1098
|
} else if (line.startsWith("@@")) {
|
|
1088
|
-
lines.push(
|
|
1099
|
+
lines.push(chalk9.cyan(" " + line));
|
|
1089
1100
|
} else {
|
|
1090
|
-
lines.push(
|
|
1101
|
+
lines.push(chalk9.dim(" " + line));
|
|
1091
1102
|
}
|
|
1092
1103
|
}
|
|
1093
1104
|
const totalBody = bodyLines.length;
|
|
1094
1105
|
if (totalBody > maxVisible) {
|
|
1095
1106
|
const pct = Math.round((scrollOffset + maxVisible) / totalBody * 100);
|
|
1096
|
-
lines.push(
|
|
1107
|
+
lines.push(chalk9.dim(` \u2500\u2500 ${Math.min(pct, 100)}% \u2500\u2500`));
|
|
1097
1108
|
}
|
|
1098
1109
|
lines.push("");
|
|
1099
|
-
lines.push(
|
|
1110
|
+
lines.push(chalk9.dim(" \u2191\u2193 scroll \u23B5/esc back to file list"));
|
|
1100
1111
|
return lines.join("\n");
|
|
1101
1112
|
}
|
|
1102
1113
|
function draw(initial) {
|
|
@@ -1249,7 +1260,7 @@ import { fileURLToPath } from "url";
|
|
|
1249
1260
|
|
|
1250
1261
|
// src/commands/init.ts
|
|
1251
1262
|
import path28 from "path";
|
|
1252
|
-
import
|
|
1263
|
+
import chalk13 from "chalk";
|
|
1253
1264
|
import fs35 from "fs";
|
|
1254
1265
|
|
|
1255
1266
|
// src/fingerprint/index.ts
|
|
@@ -3197,11 +3208,11 @@ function spawnOpenCode(args) {
|
|
|
3197
3208
|
});
|
|
3198
3209
|
}
|
|
3199
3210
|
}
|
|
3200
|
-
function runCommand(args,
|
|
3211
|
+
function runCommand(args, input2, timeoutMs) {
|
|
3201
3212
|
return new Promise((resolve3, reject) => {
|
|
3202
3213
|
const child = spawnOpenCode(args);
|
|
3203
3214
|
const stderrChunks = [];
|
|
3204
|
-
child.stdin.end(
|
|
3215
|
+
child.stdin.end(input2);
|
|
3205
3216
|
let stdoutData = Buffer.alloc(0);
|
|
3206
3217
|
child.stdout.on("data", (chunk) => {
|
|
3207
3218
|
stdoutData = Buffer.concat([stdoutData, chunk]);
|
|
@@ -3235,13 +3246,13 @@ function runCommand(args, input, timeoutMs) {
|
|
|
3235
3246
|
});
|
|
3236
3247
|
});
|
|
3237
3248
|
}
|
|
3238
|
-
function runCommandStream(args,
|
|
3249
|
+
function runCommandStream(args, input2, callbacks, timeoutMs) {
|
|
3239
3250
|
return new Promise((resolve3, reject) => {
|
|
3240
3251
|
const child = spawnOpenCode(args);
|
|
3241
3252
|
const stderrChunks = [];
|
|
3242
3253
|
let settled = false;
|
|
3243
3254
|
let lineBuffer = "";
|
|
3244
|
-
child.stdin.end(
|
|
3255
|
+
child.stdin.end(input2);
|
|
3245
3256
|
child.stdout.on("data", (chunk) => {
|
|
3246
3257
|
const text = chunk.toString("utf-8");
|
|
3247
3258
|
lineBuffer += text;
|
|
@@ -6909,17 +6920,15 @@ function getCurrentHeadSha() {
|
|
|
6909
6920
|
}
|
|
6910
6921
|
|
|
6911
6922
|
// src/utils/prompt.ts
|
|
6912
|
-
import
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
});
|
|
6922
|
-
});
|
|
6923
|
+
import input from "@inquirer/input";
|
|
6924
|
+
async function promptInput(question) {
|
|
6925
|
+
if (!process.stdin.isTTY) return "";
|
|
6926
|
+
try {
|
|
6927
|
+
const answer = await input({ message: question });
|
|
6928
|
+
return answer.trim();
|
|
6929
|
+
} catch {
|
|
6930
|
+
return "";
|
|
6931
|
+
}
|
|
6923
6932
|
}
|
|
6924
6933
|
|
|
6925
6934
|
// src/commands/init.ts
|
|
@@ -6927,7 +6936,7 @@ init_config();
|
|
|
6927
6936
|
|
|
6928
6937
|
// src/commands/interactive-provider-setup.ts
|
|
6929
6938
|
init_config();
|
|
6930
|
-
import
|
|
6939
|
+
import chalk2 from "chalk";
|
|
6931
6940
|
import select2 from "@inquirer/select";
|
|
6932
6941
|
import confirm from "@inquirer/confirm";
|
|
6933
6942
|
var IS_WINDOWS4 = process.platform === "win32";
|
|
@@ -6951,25 +6960,25 @@ async function runInteractiveProviderSetup(options) {
|
|
|
6951
6960
|
case "claude-cli": {
|
|
6952
6961
|
config.model = "default";
|
|
6953
6962
|
if (!isClaudeCliAvailable()) {
|
|
6954
|
-
console.log(
|
|
6963
|
+
console.log(chalk2.yellow("\n Claude Code CLI not found."));
|
|
6955
6964
|
console.log(
|
|
6956
|
-
|
|
6965
|
+
chalk2.dim(" Install it: ") + chalk2.hex("#83D1EB")("npm install -g @anthropic-ai/claude-code")
|
|
6957
6966
|
);
|
|
6958
6967
|
console.log(
|
|
6959
|
-
|
|
6968
|
+
chalk2.dim(" Then run ") + chalk2.hex("#83D1EB")("claude") + chalk2.dim(" once to log in.\n")
|
|
6960
6969
|
);
|
|
6961
6970
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6962
6971
|
if (!proceed) throw new Error("__exit__");
|
|
6963
6972
|
} else if (!isClaudeCliLoggedIn()) {
|
|
6964
|
-
console.log(
|
|
6973
|
+
console.log(chalk2.yellow("\n Claude Code CLI found but not logged in."));
|
|
6965
6974
|
console.log(
|
|
6966
|
-
|
|
6975
|
+
chalk2.dim(" Run ") + chalk2.hex("#83D1EB")("claude") + chalk2.dim(" once to log in.\n")
|
|
6967
6976
|
);
|
|
6968
6977
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6969
6978
|
if (!proceed) throw new Error("__exit__");
|
|
6970
6979
|
} else {
|
|
6971
6980
|
console.log(
|
|
6972
|
-
|
|
6981
|
+
chalk2.dim(
|
|
6973
6982
|
" Run `claude` once and log in with your Pro/Max/Team account if you haven't."
|
|
6974
6983
|
)
|
|
6975
6984
|
);
|
|
@@ -6978,10 +6987,10 @@ async function runInteractiveProviderSetup(options) {
|
|
|
6978
6987
|
}
|
|
6979
6988
|
case "opencode": {
|
|
6980
6989
|
if (!isOpenCodeAvailable()) {
|
|
6981
|
-
console.log(
|
|
6982
|
-
console.log(
|
|
6990
|
+
console.log(chalk2.yellow("\n OpenCode CLI not found."));
|
|
6991
|
+
console.log(chalk2.dim(" Install it from: ") + chalk2.hex("#83D1EB")("https://opencode.ai"));
|
|
6983
6992
|
console.log(
|
|
6984
|
-
|
|
6993
|
+
chalk2.dim(" Then run ") + chalk2.hex("#83D1EB")("opencode auth login") + chalk2.dim(" to authenticate.\n")
|
|
6985
6994
|
);
|
|
6986
6995
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
6987
6996
|
if (!proceed) throw new Error("__exit__");
|
|
@@ -6991,28 +7000,28 @@ async function runInteractiveProviderSetup(options) {
|
|
|
6991
7000
|
}
|
|
6992
7001
|
case "cursor": {
|
|
6993
7002
|
if (!isCursorAgentAvailable()) {
|
|
6994
|
-
console.log(
|
|
7003
|
+
console.log(chalk2.yellow("\n Cursor Agent CLI not found."));
|
|
6995
7004
|
if (IS_WINDOWS4) {
|
|
6996
7005
|
console.log(
|
|
6997
|
-
|
|
7006
|
+
chalk2.dim(" Install it from: ") + chalk2.hex("#83D1EB")("https://www.cursor.com/downloads")
|
|
6998
7007
|
);
|
|
6999
7008
|
console.log(
|
|
7000
|
-
|
|
7009
|
+
chalk2.dim(" Then run ") + chalk2.hex("#83D1EB")("agent login") + chalk2.dim(" in PowerShell to authenticate.\n")
|
|
7001
7010
|
);
|
|
7002
7011
|
} else {
|
|
7003
7012
|
console.log(
|
|
7004
|
-
|
|
7013
|
+
chalk2.dim(" Install it: ") + chalk2.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash")
|
|
7005
7014
|
);
|
|
7006
7015
|
console.log(
|
|
7007
|
-
|
|
7016
|
+
chalk2.dim(" Then run ") + chalk2.hex("#83D1EB")("agent login") + chalk2.dim(" to authenticate.\n")
|
|
7008
7017
|
);
|
|
7009
7018
|
}
|
|
7010
7019
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
7011
7020
|
if (!proceed) throw new Error("__exit__");
|
|
7012
7021
|
} else if (!isCursorLoggedIn()) {
|
|
7013
|
-
console.log(
|
|
7022
|
+
console.log(chalk2.yellow("\n Cursor Agent CLI found but not logged in."));
|
|
7014
7023
|
console.log(
|
|
7015
|
-
|
|
7024
|
+
chalk2.dim(" Run ") + chalk2.hex("#83D1EB")("agent login") + chalk2.dim(" to authenticate.\n")
|
|
7016
7025
|
);
|
|
7017
7026
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
7018
7027
|
if (!proceed) throw new Error("__exit__");
|
|
@@ -7022,13 +7031,13 @@ async function runInteractiveProviderSetup(options) {
|
|
|
7022
7031
|
}
|
|
7023
7032
|
case "anthropic": {
|
|
7024
7033
|
console.log(
|
|
7025
|
-
|
|
7034
|
+
chalk2.dim(
|
|
7026
7035
|
" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."
|
|
7027
7036
|
)
|
|
7028
7037
|
);
|
|
7029
7038
|
config.apiKey = await promptInput("Anthropic API key:");
|
|
7030
7039
|
if (!config.apiKey) {
|
|
7031
|
-
console.log(
|
|
7040
|
+
console.log(chalk2.red("API key is required."));
|
|
7032
7041
|
throw new Error("__exit__");
|
|
7033
7042
|
}
|
|
7034
7043
|
config.model = await promptInput(`Model (default: ${DEFAULT_MODELS.anthropic}):`) || DEFAULT_MODELS.anthropic;
|
|
@@ -7037,7 +7046,7 @@ async function runInteractiveProviderSetup(options) {
|
|
|
7037
7046
|
case "vertex": {
|
|
7038
7047
|
config.vertexProjectId = await promptInput("GCP Project ID:");
|
|
7039
7048
|
if (!config.vertexProjectId) {
|
|
7040
|
-
console.log(
|
|
7049
|
+
console.log(chalk2.red("Project ID is required."));
|
|
7041
7050
|
throw new Error("__exit__");
|
|
7042
7051
|
}
|
|
7043
7052
|
config.vertexRegion = await promptInput("Region (default: us-east5):") || "us-east5";
|
|
@@ -7048,7 +7057,7 @@ async function runInteractiveProviderSetup(options) {
|
|
|
7048
7057
|
case "openai": {
|
|
7049
7058
|
config.apiKey = await promptInput("API key:");
|
|
7050
7059
|
if (!config.apiKey) {
|
|
7051
|
-
console.log(
|
|
7060
|
+
console.log(chalk2.red("API key is required."));
|
|
7052
7061
|
throw new Error("__exit__");
|
|
7053
7062
|
}
|
|
7054
7063
|
config.baseUrl = await promptInput("Base URL (leave empty for OpenAI, or enter custom endpoint):") || void 0;
|
|
@@ -7056,10 +7065,10 @@ async function runInteractiveProviderSetup(options) {
|
|
|
7056
7065
|
break;
|
|
7057
7066
|
}
|
|
7058
7067
|
case "minimax": {
|
|
7059
|
-
console.log(
|
|
7068
|
+
console.log(chalk2.dim(" Get a key at https://platform.minimax.io"));
|
|
7060
7069
|
config.apiKey = await promptInput("MiniMax API key:");
|
|
7061
7070
|
if (!config.apiKey) {
|
|
7062
|
-
console.log(
|
|
7071
|
+
console.log(chalk2.red("API key is required."));
|
|
7063
7072
|
throw new Error("__exit__");
|
|
7064
7073
|
}
|
|
7065
7074
|
config.model = await promptInput(`Model (default: ${DEFAULT_MODELS.minimax}):`) || DEFAULT_MODELS.minimax;
|
|
@@ -8183,7 +8192,7 @@ function computeLocalScore(dir, targetAgent) {
|
|
|
8183
8192
|
|
|
8184
8193
|
// src/scoring/display.ts
|
|
8185
8194
|
init_resolve_caliber();
|
|
8186
|
-
import
|
|
8195
|
+
import chalk3 from "chalk";
|
|
8187
8196
|
var AGENT_DISPLAY_NAMES = {
|
|
8188
8197
|
claude: "Claude Code",
|
|
8189
8198
|
cursor: "Cursor",
|
|
@@ -8201,17 +8210,17 @@ var CATEGORY_ORDER = ["existence", "quality", "grounding", "accuracy", "freshnes
|
|
|
8201
8210
|
function gradeColor(grade) {
|
|
8202
8211
|
switch (grade) {
|
|
8203
8212
|
case "A":
|
|
8204
|
-
return
|
|
8213
|
+
return chalk3.green;
|
|
8205
8214
|
case "B":
|
|
8206
|
-
return
|
|
8215
|
+
return chalk3.greenBright;
|
|
8207
8216
|
case "C":
|
|
8208
|
-
return
|
|
8217
|
+
return chalk3.yellow;
|
|
8209
8218
|
case "D":
|
|
8210
|
-
return
|
|
8219
|
+
return chalk3.hex("#f97316");
|
|
8211
8220
|
case "F":
|
|
8212
|
-
return
|
|
8221
|
+
return chalk3.red;
|
|
8213
8222
|
default:
|
|
8214
|
-
return
|
|
8223
|
+
return chalk3.white;
|
|
8215
8224
|
}
|
|
8216
8225
|
}
|
|
8217
8226
|
var GRADIENT_COLORS = ["#ef4444", "#f97316", "#eab308", "#22c55e"];
|
|
@@ -8225,37 +8234,37 @@ function progressBar(score, max, width = 40) {
|
|
|
8225
8234
|
GRADIENT_COLORS.length - 1,
|
|
8226
8235
|
Math.floor(position * GRADIENT_COLORS.length)
|
|
8227
8236
|
);
|
|
8228
|
-
bar +=
|
|
8237
|
+
bar += chalk3.hex(GRADIENT_COLORS[colorIndex])("\u2593");
|
|
8229
8238
|
}
|
|
8230
|
-
bar +=
|
|
8239
|
+
bar += chalk3.gray("\u2591".repeat(empty));
|
|
8231
8240
|
return bar;
|
|
8232
8241
|
}
|
|
8233
8242
|
function formatCheck(check) {
|
|
8234
8243
|
const isPartial = !check.passed && check.earnedPoints > 0;
|
|
8235
8244
|
const isNegative = check.earnedPoints < 0;
|
|
8236
8245
|
const lostPoints = check.maxPoints - check.earnedPoints;
|
|
8237
|
-
const icon = check.passed ?
|
|
8246
|
+
const icon = check.passed ? chalk3.green("\u2713") : isPartial ? chalk3.yellow("~") : isNegative ? chalk3.red("\u2717") : chalk3.gray("\u2717");
|
|
8238
8247
|
let points;
|
|
8239
8248
|
if (check.passed) {
|
|
8240
|
-
points =
|
|
8249
|
+
points = chalk3.green(`+${check.earnedPoints}`.padStart(4));
|
|
8241
8250
|
} else if (isNegative) {
|
|
8242
|
-
points =
|
|
8251
|
+
points = chalk3.red(`${check.earnedPoints}`.padStart(4));
|
|
8243
8252
|
} else if (isPartial) {
|
|
8244
|
-
points =
|
|
8253
|
+
points = chalk3.yellow(`${check.earnedPoints}/${check.maxPoints}`.padStart(5));
|
|
8245
8254
|
} else {
|
|
8246
|
-
points =
|
|
8255
|
+
points = chalk3.gray(`0/${check.maxPoints}`.padStart(5));
|
|
8247
8256
|
}
|
|
8248
|
-
const name = check.passed ?
|
|
8249
|
-
const detail = check.detail ?
|
|
8257
|
+
const name = check.passed ? chalk3.white(check.name) : isNegative ? chalk3.red(check.name) : isPartial ? chalk3.white(check.name) : chalk3.gray(check.name);
|
|
8258
|
+
const detail = check.detail ? chalk3.gray(` (${check.detail})`) : "";
|
|
8250
8259
|
let suggestion = "";
|
|
8251
8260
|
if (!check.passed && check.suggestion) {
|
|
8252
|
-
const suggColor = isNegative ?
|
|
8261
|
+
const suggColor = isNegative ? chalk3.red : chalk3.yellow;
|
|
8253
8262
|
suggestion = suggColor(`
|
|
8254
8263
|
\u2192 ${check.suggestion}`);
|
|
8255
8264
|
}
|
|
8256
8265
|
let recovery = "";
|
|
8257
8266
|
if (isPartial && lostPoints > 0) {
|
|
8258
|
-
recovery =
|
|
8267
|
+
recovery = chalk3.yellow(`
|
|
8259
8268
|
\u2191 Fix this for +${lostPoints} more points`);
|
|
8260
8269
|
}
|
|
8261
8270
|
return ` ${icon} ${name.padEnd(38)}${points}${detail}${suggestion}${recovery}`;
|
|
@@ -8264,22 +8273,22 @@ function displayScore(result) {
|
|
|
8264
8273
|
const gc = gradeColor(result.grade);
|
|
8265
8274
|
const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
|
|
8266
8275
|
console.log("");
|
|
8267
|
-
console.log(
|
|
8276
|
+
console.log(chalk3.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"));
|
|
8268
8277
|
console.log("");
|
|
8269
|
-
console.log(` ${
|
|
8278
|
+
console.log(` ${chalk3.bold("Agent Config Score")} ${gc(chalk3.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk3.bold(result.grade))}`);
|
|
8270
8279
|
console.log(` ${progressBar(result.score, result.maxScore)}`);
|
|
8271
|
-
console.log(
|
|
8280
|
+
console.log(chalk3.dim(` Target: ${agentLabel}`));
|
|
8272
8281
|
console.log("");
|
|
8273
|
-
console.log(
|
|
8282
|
+
console.log(chalk3.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"));
|
|
8274
8283
|
console.log("");
|
|
8275
8284
|
for (const category of CATEGORY_ORDER) {
|
|
8276
8285
|
const summary = result.categories[category];
|
|
8277
8286
|
const categoryChecks = result.checks.filter((c) => c.category === category);
|
|
8278
8287
|
const { icon, label } = CATEGORY_LABELS[category];
|
|
8279
8288
|
const gap = summary.max - summary.earned;
|
|
8280
|
-
const gapLabel = gap > 0 ?
|
|
8289
|
+
const gapLabel = gap > 0 ? chalk3.yellow(` (-${gap} available)`) : "";
|
|
8281
8290
|
console.log(
|
|
8282
|
-
|
|
8291
|
+
chalk3.gray(` ${icon} ${label}`) + chalk3.gray(" ".repeat(Math.max(1, 43 - label.length))) + chalk3.white(`${summary.earned}`) + chalk3.gray(` / ${summary.max}`) + gapLabel
|
|
8283
8292
|
);
|
|
8284
8293
|
for (const check of categoryChecks) {
|
|
8285
8294
|
console.log(formatCheck(check));
|
|
@@ -8291,16 +8300,16 @@ function displayScore(result) {
|
|
|
8291
8300
|
function formatTopImprovements(checks) {
|
|
8292
8301
|
const improvable = checks.filter((c) => c.earnedPoints < c.maxPoints).map((c) => ({ name: c.name, potential: c.maxPoints - c.earnedPoints, suggestion: c.suggestion })).sort((a, b) => b.potential - a.potential).slice(0, 5);
|
|
8293
8302
|
if (improvable.length === 0) return;
|
|
8294
|
-
console.log(
|
|
8303
|
+
console.log(chalk3.gray(" \u2500 TOP IMPROVEMENTS \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"));
|
|
8295
8304
|
console.log("");
|
|
8296
8305
|
for (let i = 0; i < improvable.length; i++) {
|
|
8297
8306
|
const item = improvable[i];
|
|
8298
|
-
const num =
|
|
8299
|
-
const label =
|
|
8300
|
-
const pts =
|
|
8307
|
+
const num = chalk3.gray(`${i + 1}.`);
|
|
8308
|
+
const label = chalk3.white(item.name.padEnd(42));
|
|
8309
|
+
const pts = chalk3.yellow(`+${item.potential} pts`);
|
|
8301
8310
|
console.log(` ${num} ${label}${pts}`);
|
|
8302
8311
|
if (item.suggestion) {
|
|
8303
|
-
console.log(
|
|
8312
|
+
console.log(chalk3.gray(` ${item.suggestion}`));
|
|
8304
8313
|
}
|
|
8305
8314
|
}
|
|
8306
8315
|
console.log("");
|
|
@@ -8310,48 +8319,48 @@ function displayScoreSummary(result) {
|
|
|
8310
8319
|
const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
|
|
8311
8320
|
console.log("");
|
|
8312
8321
|
console.log(
|
|
8313
|
-
|
|
8322
|
+
chalk3.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk3.gray(` (Grade ${result.grade})`) + chalk3.gray(` \xB7 ${agentLabel}`) + chalk3.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
|
|
8314
8323
|
);
|
|
8315
8324
|
const failing = result.checks.filter((c) => !c.passed);
|
|
8316
8325
|
if (failing.length > 0) {
|
|
8317
8326
|
const shown = failing.slice(0, 5);
|
|
8318
8327
|
for (const check of shown) {
|
|
8319
|
-
console.log(
|
|
8328
|
+
console.log(chalk3.gray(` \u2717 ${check.name}`));
|
|
8320
8329
|
}
|
|
8321
8330
|
const remaining = failing.length - shown.length;
|
|
8322
8331
|
const moreText = remaining > 0 ? ` (+${remaining} more)` : "";
|
|
8323
|
-
console.log(
|
|
8324
|
-
Run ${
|
|
8332
|
+
console.log(chalk3.dim(`
|
|
8333
|
+
Run ${chalk3.hex("#83D1EB")(`${resolveCaliber()} score`)} for details.${moreText}`));
|
|
8325
8334
|
}
|
|
8326
8335
|
console.log("");
|
|
8327
8336
|
}
|
|
8328
8337
|
function displayScoreDelta(before, after) {
|
|
8329
8338
|
const delta = after.score - before.score;
|
|
8330
8339
|
const deltaStr = delta >= 0 ? `+${delta}` : `${delta}`;
|
|
8331
|
-
const deltaColor = delta >= 0 ?
|
|
8340
|
+
const deltaColor = delta >= 0 ? chalk3.green : chalk3.red;
|
|
8332
8341
|
const beforeGc = gradeColor(before.grade);
|
|
8333
8342
|
const afterGc = gradeColor(after.grade);
|
|
8334
8343
|
console.log("");
|
|
8335
|
-
console.log(
|
|
8344
|
+
console.log(chalk3.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"));
|
|
8336
8345
|
console.log("");
|
|
8337
8346
|
console.log(
|
|
8338
|
-
` Score: ${beforeGc(`${before.score}`)} ${
|
|
8347
|
+
` Score: ${beforeGc(`${before.score}`)} ${chalk3.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk3.gray("\u2192")} ${afterGc(after.grade)}`
|
|
8339
8348
|
);
|
|
8340
|
-
console.log(` ${progressBar(before.score, before.maxScore, 19)} ${
|
|
8349
|
+
console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk3.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
|
|
8341
8350
|
console.log("");
|
|
8342
|
-
console.log(
|
|
8351
|
+
console.log(chalk3.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"));
|
|
8343
8352
|
console.log("");
|
|
8344
8353
|
const improved = after.checks.filter((ac) => {
|
|
8345
8354
|
const bc = before.checks.find((b) => b.id === ac.id);
|
|
8346
8355
|
return bc && ac.earnedPoints > bc.earnedPoints;
|
|
8347
8356
|
});
|
|
8348
8357
|
if (improved.length > 0) {
|
|
8349
|
-
console.log(
|
|
8358
|
+
console.log(chalk3.gray(" What improved:"));
|
|
8350
8359
|
for (const check of improved) {
|
|
8351
8360
|
const bc = before.checks.find((b) => b.id === check.id);
|
|
8352
8361
|
const gain = check.earnedPoints - bc.earnedPoints;
|
|
8353
8362
|
console.log(
|
|
8354
|
-
|
|
8363
|
+
chalk3.green(" +") + chalk3.white(` ${check.name.padEnd(50)}`) + chalk3.green(`+${gain}`)
|
|
8355
8364
|
);
|
|
8356
8365
|
}
|
|
8357
8366
|
console.log("");
|
|
@@ -8359,7 +8368,7 @@ function displayScoreDelta(before, after) {
|
|
|
8359
8368
|
}
|
|
8360
8369
|
|
|
8361
8370
|
// src/commands/recommend.ts
|
|
8362
|
-
import
|
|
8371
|
+
import chalk5 from "chalk";
|
|
8363
8372
|
import ora from "ora";
|
|
8364
8373
|
import select3 from "@inquirer/select";
|
|
8365
8374
|
import { mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync4, existsSync as existsSync8, writeFileSync } from "fs";
|
|
@@ -8368,7 +8377,7 @@ init_config();
|
|
|
8368
8377
|
|
|
8369
8378
|
// src/telemetry/index.ts
|
|
8370
8379
|
import { PostHog } from "posthog-node";
|
|
8371
|
-
import
|
|
8380
|
+
import chalk4 from "chalk";
|
|
8372
8381
|
|
|
8373
8382
|
// src/telemetry/config.ts
|
|
8374
8383
|
import fs27 from "fs";
|
|
@@ -8488,7 +8497,7 @@ function initTelemetry() {
|
|
|
8488
8497
|
});
|
|
8489
8498
|
if (!wasNoticeShown()) {
|
|
8490
8499
|
console.log(
|
|
8491
|
-
|
|
8500
|
+
chalk4.dim(" Caliber collects anonymous usage data to improve the product.") + "\n" + chalk4.dim(" Disable with --no-traces or CALIBER_TELEMETRY_DISABLED=1\n")
|
|
8492
8501
|
);
|
|
8493
8502
|
markNoticeShown();
|
|
8494
8503
|
}
|
|
@@ -8956,7 +8965,7 @@ async function searchSkills(fingerprint, targetPlatforms, onStatus) {
|
|
|
8956
8965
|
async function querySkills(query) {
|
|
8957
8966
|
const terms = query.split(/[\s,]+/).filter(Boolean);
|
|
8958
8967
|
if (terms.length === 0) {
|
|
8959
|
-
console.log(
|
|
8968
|
+
console.log(chalk5.yellow("Please provide search terms."));
|
|
8960
8969
|
throw new Error("__exit__");
|
|
8961
8970
|
}
|
|
8962
8971
|
const platforms = detectLocalPlatforms();
|
|
@@ -9004,7 +9013,7 @@ async function querySkills(query) {
|
|
|
9004
9013
|
const available = top.filter((r) => contentMap.has(r.slug));
|
|
9005
9014
|
fetchSpinner.succeed(`${available.length} available`);
|
|
9006
9015
|
if (!available.length) {
|
|
9007
|
-
console.log(
|
|
9016
|
+
console.log(chalk5.dim(" No installable skills found.\n"));
|
|
9008
9017
|
return;
|
|
9009
9018
|
}
|
|
9010
9019
|
console.log("");
|
|
@@ -9016,7 +9025,7 @@ async function querySkills(query) {
|
|
|
9016
9025
|
}
|
|
9017
9026
|
console.log("");
|
|
9018
9027
|
console.log(
|
|
9019
|
-
|
|
9028
|
+
chalk5.dim(
|
|
9020
9029
|
` Install with: ${resolveCaliber()} skills --install ${available.map((r) => r.slug).join(",")}`
|
|
9021
9030
|
)
|
|
9022
9031
|
);
|
|
@@ -9025,7 +9034,7 @@ async function querySkills(query) {
|
|
|
9025
9034
|
async function installBySlug(slugStr) {
|
|
9026
9035
|
const slugs = slugStr.split(",").map((s) => s.trim()).filter(Boolean);
|
|
9027
9036
|
if (slugs.length === 0) {
|
|
9028
|
-
console.log(
|
|
9037
|
+
console.log(chalk5.yellow("Please provide skill slugs to install."));
|
|
9029
9038
|
throw new Error("__exit__");
|
|
9030
9039
|
}
|
|
9031
9040
|
const platforms = detectLocalPlatforms();
|
|
@@ -9065,7 +9074,7 @@ async function recommendCommand(options) {
|
|
|
9065
9074
|
return;
|
|
9066
9075
|
}
|
|
9067
9076
|
if (!process.stdin.isTTY) {
|
|
9068
|
-
console.log(
|
|
9077
|
+
console.log(chalk5.dim(" Skills search requires an interactive terminal."));
|
|
9069
9078
|
return;
|
|
9070
9079
|
}
|
|
9071
9080
|
const proceed = await select3({
|
|
@@ -9076,7 +9085,7 @@ async function recommendCommand(options) {
|
|
|
9076
9085
|
]
|
|
9077
9086
|
});
|
|
9078
9087
|
if (!proceed) {
|
|
9079
|
-
console.log(
|
|
9088
|
+
console.log(chalk5.dim(" Cancelled.\n"));
|
|
9080
9089
|
return;
|
|
9081
9090
|
}
|
|
9082
9091
|
const state = readState();
|
|
@@ -9094,7 +9103,7 @@ async function searchAndInstallSkills(targetPlatforms) {
|
|
|
9094
9103
|
];
|
|
9095
9104
|
if (technologies.length === 0) {
|
|
9096
9105
|
console.log(
|
|
9097
|
-
|
|
9106
|
+
chalk5.yellow(
|
|
9098
9107
|
"Could not detect any languages or dependencies. Try running from a project root."
|
|
9099
9108
|
)
|
|
9100
9109
|
);
|
|
@@ -9114,7 +9123,7 @@ async function searchAndInstallSkills(targetPlatforms) {
|
|
|
9114
9123
|
return;
|
|
9115
9124
|
}
|
|
9116
9125
|
searchSpinner.succeed(
|
|
9117
|
-
`Found ${allCandidates.length} skills` + (filteredCount > 0 ?
|
|
9126
|
+
`Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk5.dim(` (${filteredCount} already installed)`) : "")
|
|
9118
9127
|
);
|
|
9119
9128
|
let results;
|
|
9120
9129
|
const config = loadConfig();
|
|
@@ -9152,7 +9161,7 @@ async function searchAndInstallSkills(targetPlatforms) {
|
|
|
9152
9161
|
}
|
|
9153
9162
|
const unavailableCount = results.length - available.length;
|
|
9154
9163
|
fetchSpinner.succeed(
|
|
9155
|
-
`${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ?
|
|
9164
|
+
`${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk5.dim(` (${unavailableCount} unavailable)`) : "")
|
|
9156
9165
|
);
|
|
9157
9166
|
const selected = await interactiveSelect(available);
|
|
9158
9167
|
if (selected?.length) {
|
|
@@ -9175,34 +9184,34 @@ async function interactiveSelect(recs) {
|
|
|
9175
9184
|
const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
|
|
9176
9185
|
const prefixWidth = 8;
|
|
9177
9186
|
const scoreWidth = 6;
|
|
9178
|
-
lines.push(
|
|
9187
|
+
lines.push(chalk5.bold(" Skills"));
|
|
9179
9188
|
lines.push("");
|
|
9180
9189
|
if (hasScores) {
|
|
9181
|
-
const header = " ".repeat(prefixWidth) +
|
|
9190
|
+
const header = " ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why");
|
|
9182
9191
|
lines.push(header);
|
|
9183
9192
|
} else {
|
|
9184
|
-
const header = " ".repeat(prefixWidth) +
|
|
9193
|
+
const header = " ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source");
|
|
9185
9194
|
lines.push(header);
|
|
9186
9195
|
}
|
|
9187
|
-
lines.push(
|
|
9196
|
+
lines.push(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
|
|
9188
9197
|
for (let i = 0; i < recs.length; i++) {
|
|
9189
9198
|
const rec = recs[i];
|
|
9190
|
-
const check = selected.has(i) ?
|
|
9191
|
-
const ptr = i === cursor ?
|
|
9199
|
+
const check = selected.has(i) ? chalk5.green("[x]") : "[ ]";
|
|
9200
|
+
const ptr = i === cursor ? chalk5.cyan(">") : " ";
|
|
9192
9201
|
if (hasScores) {
|
|
9193
|
-
const scoreColor = rec.score >= 90 ?
|
|
9202
|
+
const scoreColor = rec.score >= 90 ? chalk5.green : rec.score >= 70 ? chalk5.yellow : chalk5.dim;
|
|
9194
9203
|
const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
|
|
9195
9204
|
lines.push(
|
|
9196
|
-
` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${
|
|
9205
|
+
` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`
|
|
9197
9206
|
);
|
|
9198
9207
|
} else {
|
|
9199
9208
|
lines.push(
|
|
9200
|
-
` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${
|
|
9209
|
+
` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`
|
|
9201
9210
|
);
|
|
9202
9211
|
}
|
|
9203
9212
|
}
|
|
9204
9213
|
lines.push("");
|
|
9205
|
-
lines.push(
|
|
9214
|
+
lines.push(chalk5.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
|
|
9206
9215
|
return lines.join("\n");
|
|
9207
9216
|
}
|
|
9208
9217
|
function draw(initial) {
|
|
@@ -9251,7 +9260,7 @@ async function interactiveSelect(recs) {
|
|
|
9251
9260
|
case "\n":
|
|
9252
9261
|
cleanup();
|
|
9253
9262
|
if (selected.size === 0) {
|
|
9254
|
-
console.log(
|
|
9263
|
+
console.log(chalk5.dim("\n No skills selected.\n"));
|
|
9255
9264
|
resolve3(null);
|
|
9256
9265
|
} else {
|
|
9257
9266
|
resolve3(
|
|
@@ -9263,7 +9272,7 @@ async function interactiveSelect(recs) {
|
|
|
9263
9272
|
case "\x1B":
|
|
9264
9273
|
case "":
|
|
9265
9274
|
cleanup();
|
|
9266
|
-
console.log(
|
|
9275
|
+
console.log(chalk5.dim("\n Cancelled.\n"));
|
|
9267
9276
|
resolve3(null);
|
|
9268
9277
|
break;
|
|
9269
9278
|
}
|
|
@@ -9310,7 +9319,7 @@ async function installSkills(recs, platforms, contentMap) {
|
|
|
9310
9319
|
trackSkillsInstalled(installed.length);
|
|
9311
9320
|
spinner.succeed(`Installed ${installed.length} file${installed.length > 1 ? "s" : ""}`);
|
|
9312
9321
|
for (const p of installed) {
|
|
9313
|
-
console.log(
|
|
9322
|
+
console.log(chalk5.green(` \u2713 ${p}`));
|
|
9314
9323
|
}
|
|
9315
9324
|
} else {
|
|
9316
9325
|
spinner.fail("No skills were installed");
|
|
@@ -9323,26 +9332,26 @@ function printSkills(recs) {
|
|
|
9323
9332
|
const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
|
|
9324
9333
|
const scoreWidth = 6;
|
|
9325
9334
|
const prefixWidth = 2;
|
|
9326
|
-
console.log(
|
|
9335
|
+
console.log(chalk5.bold("\n Skills\n"));
|
|
9327
9336
|
if (hasScores) {
|
|
9328
9337
|
console.log(
|
|
9329
|
-
" ".repeat(prefixWidth) +
|
|
9338
|
+
" ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why")
|
|
9330
9339
|
);
|
|
9331
9340
|
} else {
|
|
9332
9341
|
console.log(
|
|
9333
|
-
" ".repeat(prefixWidth) +
|
|
9342
|
+
" ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source")
|
|
9334
9343
|
);
|
|
9335
9344
|
}
|
|
9336
|
-
console.log(
|
|
9345
|
+
console.log(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
|
|
9337
9346
|
for (const rec of recs) {
|
|
9338
9347
|
if (hasScores) {
|
|
9339
9348
|
const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
|
|
9340
9349
|
console.log(
|
|
9341
|
-
` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${
|
|
9350
|
+
` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`
|
|
9342
9351
|
);
|
|
9343
9352
|
} else {
|
|
9344
9353
|
console.log(
|
|
9345
|
-
` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${
|
|
9354
|
+
` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`
|
|
9346
9355
|
);
|
|
9347
9356
|
}
|
|
9348
9357
|
}
|
|
@@ -9822,10 +9831,10 @@ function formatMs(ms) {
|
|
|
9822
9831
|
}
|
|
9823
9832
|
|
|
9824
9833
|
// src/utils/parallel-tasks.ts
|
|
9825
|
-
import
|
|
9834
|
+
import chalk7 from "chalk";
|
|
9826
9835
|
|
|
9827
9836
|
// src/utils/waiting-content.ts
|
|
9828
|
-
import
|
|
9837
|
+
import chalk6 from "chalk";
|
|
9829
9838
|
|
|
9830
9839
|
// src/utils/waiting-cards.json
|
|
9831
9840
|
var waiting_cards_default = [
|
|
@@ -9913,8 +9922,8 @@ var waiting_cards_default = [
|
|
|
9913
9922
|
];
|
|
9914
9923
|
|
|
9915
9924
|
// src/utils/waiting-content.ts
|
|
9916
|
-
var ACCENT =
|
|
9917
|
-
var BRAND =
|
|
9925
|
+
var ACCENT = chalk6.hex("#83D1EB");
|
|
9926
|
+
var BRAND = chalk6.hex("#EB9D83");
|
|
9918
9927
|
var WAITING_CARDS = waiting_cards_default;
|
|
9919
9928
|
function highlightCommands(text) {
|
|
9920
9929
|
return text.replace(/`([^`]+)`/g, (_, cmd) => ACCENT(cmd));
|
|
@@ -9923,20 +9932,20 @@ function renderCard(card, index, total, cols) {
|
|
|
9923
9932
|
const prefix = " ";
|
|
9924
9933
|
const maxWidth = Math.min(cols - 8, 65);
|
|
9925
9934
|
const lines = [];
|
|
9926
|
-
lines.push(
|
|
9935
|
+
lines.push(chalk6.dim(`${prefix}${"\u2500".repeat(maxWidth)}`));
|
|
9927
9936
|
lines.push("");
|
|
9928
9937
|
const dots = Array.from(
|
|
9929
9938
|
{ length: total },
|
|
9930
|
-
(_, i) => i === index ? ACCENT("\u25CF") :
|
|
9939
|
+
(_, i) => i === index ? ACCENT("\u25CF") : chalk6.dim("\u25CB")
|
|
9931
9940
|
).join(" ");
|
|
9932
|
-
lines.push(`${prefix}${
|
|
9941
|
+
lines.push(`${prefix}${chalk6.dim("While you wait...")} ${dots}`);
|
|
9933
9942
|
lines.push("");
|
|
9934
|
-
lines.push(`${prefix}${BRAND(card.icon)} ${
|
|
9943
|
+
lines.push(`${prefix}${BRAND(card.icon)} ${chalk6.bold(card.title)}`);
|
|
9935
9944
|
for (const line of card.lines) {
|
|
9936
|
-
lines.push(`${prefix} ${
|
|
9945
|
+
lines.push(`${prefix} ${chalk6.dim(highlightCommands(line))}`);
|
|
9937
9946
|
}
|
|
9938
9947
|
lines.push("");
|
|
9939
|
-
lines.push(`${prefix}${
|
|
9948
|
+
lines.push(`${prefix}${chalk6.dim("\u2190 \u2192 navigate auto-advances every 15s")}`);
|
|
9940
9949
|
return lines;
|
|
9941
9950
|
}
|
|
9942
9951
|
|
|
@@ -10087,15 +10096,15 @@ var ParallelTaskDisplay = class {
|
|
|
10087
10096
|
statusIcon(task) {
|
|
10088
10097
|
switch (task.status) {
|
|
10089
10098
|
case "pending":
|
|
10090
|
-
return { char: "\u25CB", styled:
|
|
10099
|
+
return { char: "\u25CB", styled: chalk7.dim("\u25CB") };
|
|
10091
10100
|
case "running": {
|
|
10092
10101
|
const frame = SPINNER_FRAMES[this.spinnerFrame];
|
|
10093
|
-
return { char: frame, styled:
|
|
10102
|
+
return { char: frame, styled: chalk7.cyan(frame) };
|
|
10094
10103
|
}
|
|
10095
10104
|
case "done":
|
|
10096
|
-
return { char: "\u2713", styled:
|
|
10105
|
+
return { char: "\u2713", styled: chalk7.green("\u2713") };
|
|
10097
10106
|
case "failed":
|
|
10098
|
-
return { char: "\u2717", styled:
|
|
10107
|
+
return { char: "\u2717", styled: chalk7.red("\u2717") };
|
|
10099
10108
|
}
|
|
10100
10109
|
}
|
|
10101
10110
|
renderPipelineHeader() {
|
|
@@ -10103,14 +10112,14 @@ var ParallelTaskDisplay = class {
|
|
|
10103
10112
|
const branchTasks = this.tasks.filter((t) => t.pipelineLabel && t.pipelineRow === 1);
|
|
10104
10113
|
if (mainTasks.length === 0) return [];
|
|
10105
10114
|
const arrow = " \u2192 ";
|
|
10106
|
-
const styledArrow =
|
|
10115
|
+
const styledArrow = chalk7.dim(arrow);
|
|
10107
10116
|
const renderNode = (t) => {
|
|
10108
10117
|
const { char, styled: icon } = this.statusIcon(t);
|
|
10109
10118
|
const label = t.pipelineLabel;
|
|
10110
|
-
const styledLabel = t.status === "pending" ?
|
|
10119
|
+
const styledLabel = t.status === "pending" ? chalk7.dim(label) : label;
|
|
10111
10120
|
return {
|
|
10112
10121
|
plain: `[${char} ${label}]`,
|
|
10113
|
-
styled:
|
|
10122
|
+
styled: chalk7.dim("[") + icon + " " + styledLabel + chalk7.dim("]")
|
|
10114
10123
|
};
|
|
10115
10124
|
};
|
|
10116
10125
|
const mainNodes = mainTasks.map(renderNode);
|
|
@@ -10120,7 +10129,7 @@ var ParallelTaskDisplay = class {
|
|
|
10120
10129
|
const firstNodePlainWidth = mainNodes[0].plain.length;
|
|
10121
10130
|
const indent = " ".repeat(PREFIX.length + firstNodePlainWidth + arrow.length);
|
|
10122
10131
|
const branchNodes = branchTasks.map(renderNode);
|
|
10123
|
-
const branchLine = indent +
|
|
10132
|
+
const branchLine = indent + chalk7.dim("\u2198 ") + branchNodes.map((n) => n.styled).join(styledArrow) + chalk7.dim(" \u2197");
|
|
10124
10133
|
lines.push(branchLine);
|
|
10125
10134
|
}
|
|
10126
10135
|
return lines;
|
|
@@ -10147,16 +10156,16 @@ var ParallelTaskDisplay = class {
|
|
|
10147
10156
|
renderLine(task, index) {
|
|
10148
10157
|
const cols = process.stdout.columns || 80;
|
|
10149
10158
|
const elapsed = task.startTime ? this.formatTime((task.endTime ?? Date.now()) - task.startTime) : "";
|
|
10150
|
-
const timeStr = elapsed ? ` ${
|
|
10159
|
+
const timeStr = elapsed ? ` ${chalk7.dim(elapsed)}` : "";
|
|
10151
10160
|
const timePlain = elapsed ? ` ${elapsed}` : "";
|
|
10152
10161
|
const { styled: icon } = this.statusIcon(task);
|
|
10153
|
-
const nameStyle = task.status === "pending" ?
|
|
10154
|
-
const msgStyle = task.status === "failed" ?
|
|
10162
|
+
const nameStyle = task.status === "pending" ? chalk7.dim : chalk7.white;
|
|
10163
|
+
const msgStyle = task.status === "failed" ? chalk7.red : chalk7.dim;
|
|
10155
10164
|
if (!this.cachedConnectors) {
|
|
10156
10165
|
this.cachedConnectors = this.tasks.map((_, i) => this.getTreeConnector(i));
|
|
10157
10166
|
}
|
|
10158
10167
|
const connector = this.cachedConnectors[index];
|
|
10159
|
-
const connectorStyled = connector ?
|
|
10168
|
+
const connectorStyled = connector ? chalk7.dim(connector) : "";
|
|
10160
10169
|
const paddedName = task.name.padEnd(Math.max(0, NAME_COL_WIDTH - connector.length));
|
|
10161
10170
|
const usedByFixed = PREFIX.length + connector.length + 2 + NAME_COL_WIDTH + timePlain.length;
|
|
10162
10171
|
const msgMax = Math.max(cols - usedByFixed - 2, 10);
|
|
@@ -10175,7 +10184,7 @@ var ParallelTaskDisplay = class {
|
|
|
10175
10184
|
if (pipelineHeader.length > 0) {
|
|
10176
10185
|
lines.push(...pipelineHeader);
|
|
10177
10186
|
const cols = stdout.columns || 80;
|
|
10178
|
-
lines.push(PREFIX +
|
|
10187
|
+
lines.push(PREFIX + chalk7.dim("\u2500".repeat(Math.min(cols - PREFIX.length * 2, 55))));
|
|
10179
10188
|
}
|
|
10180
10189
|
lines.push(...taskLines);
|
|
10181
10190
|
const PREVIEW_STALE_MS = 3e3;
|
|
@@ -10184,7 +10193,7 @@ var ParallelTaskDisplay = class {
|
|
|
10184
10193
|
const cols = stdout.columns || 80;
|
|
10185
10194
|
const maxHeight = Math.min(Math.floor((stdout.rows || 24) / 3), 10);
|
|
10186
10195
|
const visibleLines = this.previewLines.slice(-maxHeight);
|
|
10187
|
-
lines.push(PREFIX +
|
|
10196
|
+
lines.push(PREFIX + chalk7.dim("\u2500".repeat(Math.min(cols - PREFIX.length * 2, 55))));
|
|
10188
10197
|
for (const line of visibleLines) {
|
|
10189
10198
|
lines.push(PREFIX + line.slice(0, cols - PREFIX.length));
|
|
10190
10199
|
}
|
|
@@ -10206,7 +10215,7 @@ var ParallelTaskDisplay = class {
|
|
|
10206
10215
|
};
|
|
10207
10216
|
|
|
10208
10217
|
// src/commands/init-prompts.ts
|
|
10209
|
-
import
|
|
10218
|
+
import chalk10 from "chalk";
|
|
10210
10219
|
import ora3 from "ora";
|
|
10211
10220
|
import select5 from "@inquirer/select";
|
|
10212
10221
|
import checkbox from "@inquirer/checkbox";
|
|
@@ -10295,7 +10304,7 @@ Return the complete updated AgentSetup JSON incorporating the user's changes. Re
|
|
|
10295
10304
|
}
|
|
10296
10305
|
|
|
10297
10306
|
// src/utils/spinner-messages.ts
|
|
10298
|
-
import
|
|
10307
|
+
import chalk8 from "chalk";
|
|
10299
10308
|
var GENERATION_MESSAGES = [
|
|
10300
10309
|
"Analyzing your project structure and dependencies...",
|
|
10301
10310
|
"Mapping out build commands and test workflows...",
|
|
@@ -10345,9 +10354,9 @@ var SpinnerMessages = class {
|
|
|
10345
10354
|
this.currentBaseMessage = this.messages[0];
|
|
10346
10355
|
this.updateSpinnerText();
|
|
10347
10356
|
if (this.showElapsedTime) {
|
|
10348
|
-
this.spinner.suffixText =
|
|
10357
|
+
this.spinner.suffixText = chalk8.dim(`(${this.formatElapsed()})`);
|
|
10349
10358
|
this.elapsedTimer = setInterval(() => {
|
|
10350
|
-
this.spinner.suffixText =
|
|
10359
|
+
this.spinner.suffixText = chalk8.dim(`(${this.formatElapsed()})`);
|
|
10351
10360
|
}, 1e3);
|
|
10352
10361
|
}
|
|
10353
10362
|
this.timer = setInterval(() => {
|
|
@@ -10465,9 +10474,9 @@ async function refineLoop(currentSetup, sessionHistory, summarizeSetup2, printSu
|
|
|
10465
10474
|
}
|
|
10466
10475
|
const isValid = await classifyRefineIntent(message);
|
|
10467
10476
|
if (!isValid) {
|
|
10468
|
-
console.log(
|
|
10469
|
-
console.log(
|
|
10470
|
-
console.log(
|
|
10477
|
+
console.log(chalk10.dim(" This doesn't look like a config change request."));
|
|
10478
|
+
console.log(chalk10.dim(" Describe what to add, remove, or modify in your configs."));
|
|
10479
|
+
console.log(chalk10.dim(' Type "done" to accept the current config.\n'));
|
|
10471
10480
|
continue;
|
|
10472
10481
|
}
|
|
10473
10482
|
const refineSpinner = ora3("Refining config...").start();
|
|
@@ -10484,16 +10493,16 @@ async function refineLoop(currentSetup, sessionHistory, summarizeSetup2, printSu
|
|
|
10484
10493
|
});
|
|
10485
10494
|
refineSpinner.succeed("Config updated");
|
|
10486
10495
|
printSummary(refined);
|
|
10487
|
-
console.log(
|
|
10496
|
+
console.log(chalk10.dim('Type "done" to accept, or describe more changes.'));
|
|
10488
10497
|
} else {
|
|
10489
10498
|
refineSpinner.fail("Refinement failed \u2014 could not parse AI response.");
|
|
10490
|
-
console.log(
|
|
10499
|
+
console.log(chalk10.dim('Try rephrasing your request, or type "done" to keep the current config.'));
|
|
10491
10500
|
}
|
|
10492
10501
|
}
|
|
10493
10502
|
}
|
|
10494
10503
|
|
|
10495
10504
|
// src/commands/init-display.ts
|
|
10496
|
-
import
|
|
10505
|
+
import chalk11 from "chalk";
|
|
10497
10506
|
import fs32 from "fs";
|
|
10498
10507
|
init_types();
|
|
10499
10508
|
function formatWhatChanged(setup) {
|
|
@@ -10545,26 +10554,26 @@ function printSetupSummary(setup) {
|
|
|
10545
10554
|
const fileDescriptions = setup.fileDescriptions;
|
|
10546
10555
|
const deletions = setup.deletions;
|
|
10547
10556
|
console.log("");
|
|
10548
|
-
console.log(
|
|
10557
|
+
console.log(chalk11.bold(" Your tailored config:\n"));
|
|
10549
10558
|
const getDescription = (filePath) => {
|
|
10550
10559
|
return fileDescriptions?.[filePath];
|
|
10551
10560
|
};
|
|
10552
10561
|
if (claude) {
|
|
10553
10562
|
if (claude.claudeMd) {
|
|
10554
|
-
const icon = fs32.existsSync("CLAUDE.md") ?
|
|
10563
|
+
const icon = fs32.existsSync("CLAUDE.md") ? chalk11.yellow("~") : chalk11.green("+");
|
|
10555
10564
|
const desc = getDescription("CLAUDE.md");
|
|
10556
|
-
console.log(` ${icon} ${
|
|
10557
|
-
if (desc) console.log(
|
|
10565
|
+
console.log(` ${icon} ${chalk11.bold("CLAUDE.md")}`);
|
|
10566
|
+
if (desc) console.log(chalk11.dim(` ${desc}`));
|
|
10558
10567
|
console.log("");
|
|
10559
10568
|
}
|
|
10560
10569
|
const skills = claude.skills;
|
|
10561
10570
|
if (Array.isArray(skills) && skills.length > 0) {
|
|
10562
10571
|
for (const skill of skills) {
|
|
10563
10572
|
const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
|
|
10564
|
-
const icon = fs32.existsSync(skillPath) ?
|
|
10573
|
+
const icon = fs32.existsSync(skillPath) ? chalk11.yellow("~") : chalk11.green("+");
|
|
10565
10574
|
const desc = getDescription(skillPath);
|
|
10566
|
-
console.log(` ${icon} ${
|
|
10567
|
-
console.log(
|
|
10575
|
+
console.log(` ${icon} ${chalk11.bold(skillPath)}`);
|
|
10576
|
+
console.log(chalk11.dim(` ${desc || skill.description || skill.name}`));
|
|
10568
10577
|
console.log("");
|
|
10569
10578
|
}
|
|
10570
10579
|
}
|
|
@@ -10572,20 +10581,20 @@ function printSetupSummary(setup) {
|
|
|
10572
10581
|
const codex = setup.codex;
|
|
10573
10582
|
if (codex) {
|
|
10574
10583
|
if (codex.agentsMd) {
|
|
10575
|
-
const icon = fs32.existsSync("AGENTS.md") ?
|
|
10584
|
+
const icon = fs32.existsSync("AGENTS.md") ? chalk11.yellow("~") : chalk11.green("+");
|
|
10576
10585
|
const desc = getDescription("AGENTS.md");
|
|
10577
|
-
console.log(` ${icon} ${
|
|
10578
|
-
if (desc) console.log(
|
|
10586
|
+
console.log(` ${icon} ${chalk11.bold("AGENTS.md")}`);
|
|
10587
|
+
if (desc) console.log(chalk11.dim(` ${desc}`));
|
|
10579
10588
|
console.log("");
|
|
10580
10589
|
}
|
|
10581
10590
|
const codexSkills = codex.skills;
|
|
10582
10591
|
if (Array.isArray(codexSkills) && codexSkills.length > 0) {
|
|
10583
10592
|
for (const skill of codexSkills) {
|
|
10584
10593
|
const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
|
|
10585
|
-
const icon = fs32.existsSync(skillPath) ?
|
|
10594
|
+
const icon = fs32.existsSync(skillPath) ? chalk11.yellow("~") : chalk11.green("+");
|
|
10586
10595
|
const desc = getDescription(skillPath);
|
|
10587
|
-
console.log(` ${icon} ${
|
|
10588
|
-
console.log(
|
|
10596
|
+
console.log(` ${icon} ${chalk11.bold(skillPath)}`);
|
|
10597
|
+
console.log(chalk11.dim(` ${desc || skill.description || skill.name}`));
|
|
10589
10598
|
console.log("");
|
|
10590
10599
|
}
|
|
10591
10600
|
}
|
|
@@ -10593,40 +10602,40 @@ function printSetupSummary(setup) {
|
|
|
10593
10602
|
const opencode = setup.opencode;
|
|
10594
10603
|
if (opencode) {
|
|
10595
10604
|
if (opencode.agentsMd && !codex?.agentsMd) {
|
|
10596
|
-
const icon = fs32.existsSync("AGENTS.md") ?
|
|
10605
|
+
const icon = fs32.existsSync("AGENTS.md") ? chalk11.yellow("~") : chalk11.green("+");
|
|
10597
10606
|
const desc = getDescription("AGENTS.md");
|
|
10598
|
-
console.log(` ${icon} ${
|
|
10599
|
-
if (desc) console.log(
|
|
10607
|
+
console.log(` ${icon} ${chalk11.bold("AGENTS.md")} ${chalk11.dim("(OpenCode)")}`);
|
|
10608
|
+
if (desc) console.log(chalk11.dim(` ${desc}`));
|
|
10600
10609
|
console.log("");
|
|
10601
10610
|
}
|
|
10602
10611
|
const opencodeSkills = opencode.skills;
|
|
10603
10612
|
if (Array.isArray(opencodeSkills) && opencodeSkills.length > 0) {
|
|
10604
10613
|
for (const skill of opencodeSkills) {
|
|
10605
10614
|
const skillPath = `.opencode/skills/${skill.name}/SKILL.md`;
|
|
10606
|
-
const icon = fs32.existsSync(skillPath) ?
|
|
10615
|
+
const icon = fs32.existsSync(skillPath) ? chalk11.yellow("~") : chalk11.green("+");
|
|
10607
10616
|
const desc = getDescription(skillPath);
|
|
10608
|
-
console.log(` ${icon} ${
|
|
10609
|
-
console.log(
|
|
10617
|
+
console.log(` ${icon} ${chalk11.bold(skillPath)}`);
|
|
10618
|
+
console.log(chalk11.dim(` ${desc || skill.description || skill.name}`));
|
|
10610
10619
|
console.log("");
|
|
10611
10620
|
}
|
|
10612
10621
|
}
|
|
10613
10622
|
}
|
|
10614
10623
|
if (cursor) {
|
|
10615
10624
|
if (cursor.cursorrules) {
|
|
10616
|
-
const icon = fs32.existsSync(".cursorrules") ?
|
|
10625
|
+
const icon = fs32.existsSync(".cursorrules") ? chalk11.yellow("~") : chalk11.green("+");
|
|
10617
10626
|
const desc = getDescription(".cursorrules");
|
|
10618
|
-
console.log(` ${icon} ${
|
|
10619
|
-
if (desc) console.log(
|
|
10627
|
+
console.log(` ${icon} ${chalk11.bold(".cursorrules")}`);
|
|
10628
|
+
if (desc) console.log(chalk11.dim(` ${desc}`));
|
|
10620
10629
|
console.log("");
|
|
10621
10630
|
}
|
|
10622
10631
|
const cursorSkills = cursor.skills;
|
|
10623
10632
|
if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
|
|
10624
10633
|
for (const skill of cursorSkills) {
|
|
10625
10634
|
const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
|
|
10626
|
-
const icon = fs32.existsSync(skillPath) ?
|
|
10635
|
+
const icon = fs32.existsSync(skillPath) ? chalk11.yellow("~") : chalk11.green("+");
|
|
10627
10636
|
const desc = getDescription(skillPath);
|
|
10628
|
-
console.log(` ${icon} ${
|
|
10629
|
-
console.log(
|
|
10637
|
+
console.log(` ${icon} ${chalk11.bold(skillPath)}`);
|
|
10638
|
+
console.log(chalk11.dim(` ${desc || skill.description || skill.name}`));
|
|
10630
10639
|
console.log("");
|
|
10631
10640
|
}
|
|
10632
10641
|
}
|
|
@@ -10634,14 +10643,14 @@ function printSetupSummary(setup) {
|
|
|
10634
10643
|
if (Array.isArray(rulesArr) && rulesArr.length > 0) {
|
|
10635
10644
|
for (const rule of rulesArr) {
|
|
10636
10645
|
const rulePath = `.cursor/rules/${rule.filename}`;
|
|
10637
|
-
const icon = fs32.existsSync(rulePath) ?
|
|
10646
|
+
const icon = fs32.existsSync(rulePath) ? chalk11.yellow("~") : chalk11.green("+");
|
|
10638
10647
|
const desc = getDescription(rulePath);
|
|
10639
|
-
console.log(` ${icon} ${
|
|
10648
|
+
console.log(` ${icon} ${chalk11.bold(rulePath)}`);
|
|
10640
10649
|
if (desc) {
|
|
10641
|
-
console.log(
|
|
10650
|
+
console.log(chalk11.dim(` ${desc}`));
|
|
10642
10651
|
} else {
|
|
10643
10652
|
const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
|
|
10644
|
-
if (firstLine) console.log(
|
|
10653
|
+
if (firstLine) console.log(chalk11.dim(` ${firstLine.trim().slice(0, 80)}`));
|
|
10645
10654
|
}
|
|
10646
10655
|
console.log("");
|
|
10647
10656
|
}
|
|
@@ -10649,53 +10658,53 @@ function printSetupSummary(setup) {
|
|
|
10649
10658
|
}
|
|
10650
10659
|
if (Array.isArray(deletions) && deletions.length > 0) {
|
|
10651
10660
|
for (const del of deletions) {
|
|
10652
|
-
console.log(` ${
|
|
10653
|
-
console.log(
|
|
10661
|
+
console.log(` ${chalk11.red("-")} ${chalk11.bold(del.filePath)}`);
|
|
10662
|
+
console.log(chalk11.dim(` ${del.reason}`));
|
|
10654
10663
|
console.log("");
|
|
10655
10664
|
}
|
|
10656
10665
|
}
|
|
10657
10666
|
console.log(
|
|
10658
|
-
` ${
|
|
10667
|
+
` ${chalk11.green("+")} ${chalk11.dim("new")} ${chalk11.yellow("~")} ${chalk11.dim("modified")} ${chalk11.red("-")} ${chalk11.dim("removed")}`
|
|
10659
10668
|
);
|
|
10660
10669
|
console.log("");
|
|
10661
10670
|
}
|
|
10662
10671
|
function displayTokenUsage() {
|
|
10663
10672
|
const summary = getUsageSummary();
|
|
10664
10673
|
if (summary.length === 0) {
|
|
10665
|
-
console.log(
|
|
10674
|
+
console.log(chalk11.dim(" Token tracking not available for this provider.\n"));
|
|
10666
10675
|
return;
|
|
10667
10676
|
}
|
|
10668
10677
|
const config = loadConfig();
|
|
10669
10678
|
const isEstimated = config != null && isSeatBased(config.provider);
|
|
10670
10679
|
const label = isEstimated ? "Estimated token usage:" : "Token usage:";
|
|
10671
|
-
console.log(
|
|
10680
|
+
console.log(chalk11.bold(` ${label}
|
|
10672
10681
|
`));
|
|
10673
10682
|
let totalIn = 0;
|
|
10674
10683
|
let totalOut = 0;
|
|
10675
10684
|
for (const m of summary) {
|
|
10676
10685
|
totalIn += m.inputTokens;
|
|
10677
10686
|
totalOut += m.outputTokens;
|
|
10678
|
-
const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ?
|
|
10687
|
+
const cacheInfo = m.cacheReadTokens > 0 || m.cacheWriteTokens > 0 ? chalk11.dim(
|
|
10679
10688
|
` (cache: ${m.cacheReadTokens.toLocaleString()} read, ${m.cacheWriteTokens.toLocaleString()} write)`
|
|
10680
10689
|
) : "";
|
|
10681
10690
|
console.log(
|
|
10682
|
-
` ${
|
|
10691
|
+
` ${chalk11.dim(m.model)}: ${m.inputTokens.toLocaleString()} in / ${m.outputTokens.toLocaleString()} out (${m.calls} call${m.calls === 1 ? "" : "s"})${cacheInfo}`
|
|
10683
10692
|
);
|
|
10684
10693
|
}
|
|
10685
10694
|
if (summary.length > 1) {
|
|
10686
10695
|
console.log(
|
|
10687
|
-
` ${
|
|
10696
|
+
` ${chalk11.dim("Total")}: ${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out`
|
|
10688
10697
|
);
|
|
10689
10698
|
}
|
|
10690
10699
|
if (isEstimated) {
|
|
10691
|
-
console.log(
|
|
10700
|
+
console.log(chalk11.dim(" (Estimated from character count)"));
|
|
10692
10701
|
}
|
|
10693
10702
|
console.log("");
|
|
10694
10703
|
}
|
|
10695
10704
|
|
|
10696
10705
|
// src/commands/init-helpers.ts
|
|
10697
10706
|
init_config();
|
|
10698
|
-
import
|
|
10707
|
+
import chalk12 from "chalk";
|
|
10699
10708
|
import fs33 from "fs";
|
|
10700
10709
|
import path26 from "path";
|
|
10701
10710
|
function isFirstRun(dir) {
|
|
@@ -10796,7 +10805,7 @@ function writeErrorLog(config, rawOutput, error, stopReason) {
|
|
|
10796
10805
|
}
|
|
10797
10806
|
fs33.mkdirSync(path26.join(process.cwd(), ".caliber"), { recursive: true });
|
|
10798
10807
|
fs33.writeFileSync(logPath, lines.join("\n"));
|
|
10799
|
-
console.log(
|
|
10808
|
+
console.log(chalk12.dim(`
|
|
10800
10809
|
Error log written to .caliber/error-log.md`));
|
|
10801
10810
|
} catch {
|
|
10802
10811
|
}
|
|
@@ -10912,11 +10921,11 @@ function getScoreTrend(entries) {
|
|
|
10912
10921
|
// src/commands/init.ts
|
|
10913
10922
|
var IS_WINDOWS6 = process.platform === "win32";
|
|
10914
10923
|
function log(verbose, ...args) {
|
|
10915
|
-
if (verbose) console.log(
|
|
10924
|
+
if (verbose) console.log(chalk13.dim(` [verbose] ${args.map(String).join(" ")}`));
|
|
10916
10925
|
}
|
|
10917
10926
|
async function initCommand(options) {
|
|
10918
|
-
const brand =
|
|
10919
|
-
const title =
|
|
10927
|
+
const brand = chalk13.hex("#EB9D83");
|
|
10928
|
+
const title = chalk13.hex("#83D1EB");
|
|
10920
10929
|
const bin = resolveCaliber();
|
|
10921
10930
|
const firstRun = isFirstRun(process.cwd());
|
|
10922
10931
|
if (firstRun) {
|
|
@@ -10930,23 +10939,23 @@ async function initCommand(options) {
|
|
|
10930
10939
|
\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
|
|
10931
10940
|
`)
|
|
10932
10941
|
);
|
|
10933
|
-
console.log(
|
|
10934
|
-
console.log(
|
|
10942
|
+
console.log(chalk13.dim(" Keep your AI agent configs in sync \u2014 automatically."));
|
|
10943
|
+
console.log(chalk13.dim(" Works across Claude Code, Cursor, Codex, and GitHub Copilot.\n"));
|
|
10935
10944
|
console.log(title.bold(" How it works:\n"));
|
|
10936
|
-
console.log(
|
|
10937
|
-
console.log(
|
|
10938
|
-
console.log(
|
|
10939
|
-
console.log(
|
|
10945
|
+
console.log(chalk13.dim(" 1. Connect Link your LLM provider and select your agents"));
|
|
10946
|
+
console.log(chalk13.dim(" 2. Setup Detect stack, install sync hooks & skills"));
|
|
10947
|
+
console.log(chalk13.dim(" 3. Generate Audit existing config or generate from scratch"));
|
|
10948
|
+
console.log(chalk13.dim(" 4. Finalize Review changes and score your setup\n"));
|
|
10940
10949
|
} else {
|
|
10941
|
-
console.log(brand.bold("\n CALIBER") +
|
|
10950
|
+
console.log(brand.bold("\n CALIBER") + chalk13.dim(" \u2014 setting up continuous sync\n"));
|
|
10942
10951
|
}
|
|
10943
10952
|
const platforms = detectPlatforms();
|
|
10944
10953
|
if (!platforms.claude && !platforms.cursor && !platforms.codex && !platforms.opencode) {
|
|
10945
10954
|
console.log(
|
|
10946
|
-
|
|
10955
|
+
chalk13.yellow(" \u26A0 No supported AI platforms detected (Claude, Cursor, Codex, OpenCode).")
|
|
10947
10956
|
);
|
|
10948
10957
|
console.log(
|
|
10949
|
-
|
|
10958
|
+
chalk13.yellow(
|
|
10950
10959
|
" Caliber will still generate config files, but they won't be auto-installed.\n"
|
|
10951
10960
|
)
|
|
10952
10961
|
);
|
|
@@ -10956,7 +10965,7 @@ async function initCommand(options) {
|
|
|
10956
10965
|
let config = loadConfig();
|
|
10957
10966
|
if (!config && options.agent?.includes("opencode")) {
|
|
10958
10967
|
if (isOpenCodeAvailable()) {
|
|
10959
|
-
console.log(
|
|
10968
|
+
console.log(chalk13.dim(" Detected: OpenCode (uses your existing subscription)\n"));
|
|
10960
10969
|
const autoConfig = { provider: "opencode", model: DEFAULT_MODELS.opencode };
|
|
10961
10970
|
writeConfigFile(autoConfig);
|
|
10962
10971
|
config = autoConfig;
|
|
@@ -10964,7 +10973,7 @@ async function initCommand(options) {
|
|
|
10964
10973
|
}
|
|
10965
10974
|
if (!config && !options.autoApprove) {
|
|
10966
10975
|
if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
|
|
10967
|
-
console.log(
|
|
10976
|
+
console.log(chalk13.dim(" Detected: Claude Code CLI (uses your Pro/Max/Team subscription)\n"));
|
|
10968
10977
|
const useIt = await confirm2({ message: "Use Claude Code as your LLM provider?" });
|
|
10969
10978
|
if (useIt) {
|
|
10970
10979
|
const autoConfig = { provider: "claude-cli", model: "default" };
|
|
@@ -10972,7 +10981,7 @@ async function initCommand(options) {
|
|
|
10972
10981
|
config = autoConfig;
|
|
10973
10982
|
}
|
|
10974
10983
|
} else if (isCursorAgentAvailable() && isCursorLoggedIn()) {
|
|
10975
|
-
console.log(
|
|
10984
|
+
console.log(chalk13.dim(" Detected: Cursor (uses your existing subscription)\n"));
|
|
10976
10985
|
const useIt = await confirm2({ message: "Use Cursor as your LLM provider?" });
|
|
10977
10986
|
if (useIt) {
|
|
10978
10987
|
const autoConfig = { provider: "cursor", model: "sonnet-4.6" };
|
|
@@ -10998,13 +11007,13 @@ async function initCommand(options) {
|
|
|
10998
11007
|
}
|
|
10999
11008
|
}
|
|
11000
11009
|
if (!config) {
|
|
11001
|
-
console.log(
|
|
11010
|
+
console.log(chalk13.dim(" No LLM provider detected.\n"));
|
|
11002
11011
|
await runInteractiveProviderSetup({
|
|
11003
11012
|
selectMessage: "How do you want to use Caliber? (choose LLM provider)"
|
|
11004
11013
|
});
|
|
11005
11014
|
config = loadConfig();
|
|
11006
11015
|
if (!config) {
|
|
11007
|
-
console.log(
|
|
11016
|
+
console.log(chalk13.red(" Configuration cancelled or failed.\n"));
|
|
11008
11017
|
throw new Error("__exit__");
|
|
11009
11018
|
}
|
|
11010
11019
|
}
|
|
@@ -11013,7 +11022,7 @@ async function initCommand(options) {
|
|
|
11013
11022
|
const displayModel = getDisplayModel(config);
|
|
11014
11023
|
const fastModel = getFastModel();
|
|
11015
11024
|
const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
|
|
11016
|
-
console.log(
|
|
11025
|
+
console.log(chalk13.dim(modelLine + "\n"));
|
|
11017
11026
|
if (report) {
|
|
11018
11027
|
report.markStep("Provider connection");
|
|
11019
11028
|
report.addSection(
|
|
@@ -11032,10 +11041,10 @@ async function initCommand(options) {
|
|
|
11032
11041
|
const detected = detectAgents(process.cwd());
|
|
11033
11042
|
if (detected.length > 0 && (options.autoApprove || firstRun)) {
|
|
11034
11043
|
targetAgent = detected;
|
|
11035
|
-
console.log(
|
|
11044
|
+
console.log(chalk13.dim(` Coding agents in this repo: ${detected.join(", ")}
|
|
11036
11045
|
`));
|
|
11037
11046
|
} else if (detected.length > 0) {
|
|
11038
|
-
console.log(
|
|
11047
|
+
console.log(chalk13.dim(` Coding agents in this repo: ${detected.join(", ")}
|
|
11039
11048
|
`));
|
|
11040
11049
|
const useDetected = await confirm2({ message: "Generate configs for these agents?" });
|
|
11041
11050
|
targetAgent = useDetected ? detected : await promptAgent();
|
|
@@ -11043,29 +11052,29 @@ async function initCommand(options) {
|
|
|
11043
11052
|
targetAgent = options.autoApprove ? ["claude"] : await promptAgent();
|
|
11044
11053
|
}
|
|
11045
11054
|
}
|
|
11046
|
-
console.log(
|
|
11055
|
+
console.log(chalk13.dim(` Target: ${targetAgent.join(", ")}
|
|
11047
11056
|
`));
|
|
11048
11057
|
trackInitAgentSelected(targetAgent, agentAutoDetected);
|
|
11049
11058
|
console.log(title.bold(" Step 2/4 \u2014 Setup\n"));
|
|
11050
|
-
console.log(
|
|
11059
|
+
console.log(chalk13.dim(" Installing sync infrastructure...\n"));
|
|
11051
11060
|
const hookResult = installPreCommitHook();
|
|
11052
11061
|
if (hookResult.installed) {
|
|
11053
|
-
console.log(` ${
|
|
11062
|
+
console.log(` ${chalk13.green("\u2713")} Pre-commit hook installed \u2014 configs sync on every commit`);
|
|
11054
11063
|
} else if (hookResult.alreadyInstalled) {
|
|
11055
|
-
console.log(` ${
|
|
11064
|
+
console.log(` ${chalk13.green("\u2713")} Pre-commit hook \u2014 active`);
|
|
11056
11065
|
}
|
|
11057
11066
|
installStopHook();
|
|
11058
|
-
console.log(` ${
|
|
11067
|
+
console.log(` ${chalk13.green("\u2713")} Onboarding hook \u2014 nudges new team members to set up`);
|
|
11059
11068
|
installSessionStartHook();
|
|
11060
|
-
console.log(` ${
|
|
11069
|
+
console.log(` ${chalk13.green("\u2713")} Freshness hook \u2014 warns when configs are stale`);
|
|
11061
11070
|
if (IS_WINDOWS6) {
|
|
11062
11071
|
console.log(
|
|
11063
|
-
|
|
11072
|
+
chalk13.yellow(
|
|
11064
11073
|
"\n Note: hooks use shell syntax and require Git Bash (included with Git for Windows)."
|
|
11065
11074
|
)
|
|
11066
11075
|
);
|
|
11067
11076
|
console.log(
|
|
11068
|
-
|
|
11077
|
+
chalk13.dim(
|
|
11069
11078
|
" If hooks don't run, ensure Git for Windows is installed and git is using its bundled sh."
|
|
11070
11079
|
)
|
|
11071
11080
|
);
|
|
@@ -11082,23 +11091,23 @@ async function initCommand(options) {
|
|
|
11082
11091
|
const skillsWritten = ensureBuiltinSkills2();
|
|
11083
11092
|
if (skillsWritten.length > 0) {
|
|
11084
11093
|
console.log(
|
|
11085
|
-
` ${
|
|
11094
|
+
` ${chalk13.green("\u2713")} Agent skills installed \u2014 /setup-caliber, /find-skills, /save-learning`
|
|
11086
11095
|
);
|
|
11087
11096
|
} else {
|
|
11088
|
-
console.log(` ${
|
|
11097
|
+
console.log(` ${chalk13.green("\u2713")} Agent skills \u2014 already installed`);
|
|
11089
11098
|
}
|
|
11090
11099
|
const hasLearnableAgent = targetAgent.includes("claude") || targetAgent.includes("cursor");
|
|
11091
11100
|
if (hasLearnableAgent) {
|
|
11092
11101
|
if (targetAgent.includes("claude")) installLearningHooks();
|
|
11093
11102
|
if (targetAgent.includes("cursor")) installCursorLearningHooks();
|
|
11094
|
-
console.log(` ${
|
|
11103
|
+
console.log(` ${chalk13.green("\u2713")} Session learning enabled`);
|
|
11095
11104
|
trackInitLearnEnabled(true);
|
|
11096
11105
|
}
|
|
11097
11106
|
console.log("");
|
|
11098
|
-
console.log(
|
|
11099
|
-
console.log(
|
|
11107
|
+
console.log(chalk13.dim(" New team members can run /setup-caliber inside their coding agent"));
|
|
11108
|
+
console.log(chalk13.dim(" (Claude Code or Cursor) to get set up automatically.\n"));
|
|
11100
11109
|
const baselineScore = computeLocalScore(process.cwd(), targetAgent);
|
|
11101
|
-
console.log(
|
|
11110
|
+
console.log(chalk13.dim(" Current config score:"));
|
|
11102
11111
|
displayScoreSummary(baselineScore);
|
|
11103
11112
|
if (options.verbose) {
|
|
11104
11113
|
for (const c of baselineScore.checks) {
|
|
@@ -11136,20 +11145,20 @@ async function initCommand(options) {
|
|
|
11136
11145
|
let skipGeneration = false;
|
|
11137
11146
|
if (hasExistingConfig && baselineScore.score === 100) {
|
|
11138
11147
|
trackInitScoreComputed(baselineScore.score, passingCount, failingCount, true);
|
|
11139
|
-
console.log(
|
|
11148
|
+
console.log(chalk13.bold.green("\n Your config is already optimal.\n"));
|
|
11140
11149
|
skipGeneration = !options.force;
|
|
11141
11150
|
} else if (hasExistingConfig && !options.force && !options.autoApprove) {
|
|
11142
11151
|
trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
|
|
11143
11152
|
console.log(
|
|
11144
|
-
|
|
11153
|
+
chalk13.dim("\n Sync infrastructure is ready. Caliber can also audit your existing")
|
|
11145
11154
|
);
|
|
11146
|
-
console.log(
|
|
11155
|
+
console.log(chalk13.dim(" configs and improve them using AI.\n"));
|
|
11147
11156
|
const auditAnswer = await promptInput(" Audit and improve your existing config? (Y/n) ");
|
|
11148
11157
|
skipGeneration = auditAnswer.toLowerCase() === "n";
|
|
11149
11158
|
} else if (!hasExistingConfig && !options.force && !options.autoApprove) {
|
|
11150
11159
|
trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
|
|
11151
|
-
console.log(
|
|
11152
|
-
console.log(
|
|
11160
|
+
console.log(chalk13.dim("\n Sync infrastructure is ready. Caliber can also generate tailored"));
|
|
11161
|
+
console.log(chalk13.dim(" CLAUDE.md, Cursor rules, and Codex configs for your project.\n"));
|
|
11153
11162
|
const generateAnswer = await promptInput(" Generate agent configs? (Y/n) ");
|
|
11154
11163
|
skipGeneration = generateAnswer.toLowerCase() === "n";
|
|
11155
11164
|
} else {
|
|
@@ -11176,7 +11185,7 @@ async function initCommand(options) {
|
|
|
11176
11185
|
const updatedClaude = appendManagedBlocks2(claudeContent, "claude");
|
|
11177
11186
|
if (updatedClaude !== claudeContent || !fs35.existsSync(claudeMdPath)) {
|
|
11178
11187
|
fs35.writeFileSync(claudeMdPath, updatedClaude);
|
|
11179
|
-
console.log(` ${
|
|
11188
|
+
console.log(` ${chalk13.green("\u2713")} CLAUDE.md \u2014 added Caliber sync instructions`);
|
|
11180
11189
|
}
|
|
11181
11190
|
if (targetAgent.includes("cursor")) {
|
|
11182
11191
|
const rulesDir = path28.join(".cursor", "rules");
|
|
@@ -11189,7 +11198,7 @@ async function initCommand(options) {
|
|
|
11189
11198
|
]) {
|
|
11190
11199
|
fs35.writeFileSync(path28.join(rulesDir, rule.filename), rule.content);
|
|
11191
11200
|
}
|
|
11192
|
-
console.log(` ${
|
|
11201
|
+
console.log(` ${chalk13.green("\u2713")} Cursor rules \u2014 added Caliber sync rules`);
|
|
11193
11202
|
}
|
|
11194
11203
|
if (targetAgent.includes("github-copilot")) {
|
|
11195
11204
|
const copilotPath = path28.join(".github", "copilot-instructions.md");
|
|
@@ -11206,7 +11215,7 @@ async function initCommand(options) {
|
|
|
11206
11215
|
const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot");
|
|
11207
11216
|
if (updatedCopilot !== copilotContent) {
|
|
11208
11217
|
fs35.writeFileSync(copilotPath, updatedCopilot);
|
|
11209
|
-
console.log(` ${
|
|
11218
|
+
console.log(` ${chalk13.green("\u2713")} Copilot instructions \u2014 added Caliber sync instructions`);
|
|
11210
11219
|
}
|
|
11211
11220
|
}
|
|
11212
11221
|
const sha2 = getCurrentHeadSha();
|
|
@@ -11216,16 +11225,16 @@ async function initCommand(options) {
|
|
|
11216
11225
|
targetAgent
|
|
11217
11226
|
});
|
|
11218
11227
|
trackInitCompleted("sync-only", baselineScore.score);
|
|
11219
|
-
console.log(
|
|
11220
|
-
console.log(
|
|
11228
|
+
console.log(chalk13.bold.green("\n Caliber sync is set up!\n"));
|
|
11229
|
+
console.log(chalk13.dim(" Your agent configs will sync automatically on every commit."));
|
|
11221
11230
|
console.log(
|
|
11222
|
-
|
|
11231
|
+
chalk13.dim(" Run ") + title(`${bin} init --force`) + chalk13.dim(" anytime to generate or improve configs.\n")
|
|
11223
11232
|
);
|
|
11224
11233
|
return;
|
|
11225
11234
|
}
|
|
11226
11235
|
console.log(title.bold("\n Step 3/4 \u2014 Generate\n"));
|
|
11227
11236
|
const genModelInfo = fastModel ? ` Using ${displayModel} for docs, ${fastModel} for skills` : ` Using ${displayModel}`;
|
|
11228
|
-
console.log(
|
|
11237
|
+
console.log(chalk13.dim(genModelInfo + "\n"));
|
|
11229
11238
|
if (report) report.markStep("Generation");
|
|
11230
11239
|
trackInitGenerationStarted(false);
|
|
11231
11240
|
const genStartTime = Date.now();
|
|
@@ -11354,7 +11363,7 @@ async function initCommand(options) {
|
|
|
11354
11363
|
onContent: (text) => {
|
|
11355
11364
|
const lines = text.split("\n").filter((l) => l.trim()).slice(-8);
|
|
11356
11365
|
if (lines.length > 0) {
|
|
11357
|
-
display.setPreviewContent(lines.map((l) => ` ${
|
|
11366
|
+
display.setPreviewContent(lines.map((l) => ` ${chalk13.dim(l.slice(0, 80))}`));
|
|
11358
11367
|
}
|
|
11359
11368
|
}
|
|
11360
11369
|
},
|
|
@@ -11437,7 +11446,7 @@ async function initCommand(options) {
|
|
|
11437
11446
|
} catch (err) {
|
|
11438
11447
|
display.stop();
|
|
11439
11448
|
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
11440
|
-
console.log(
|
|
11449
|
+
console.log(chalk13.red(`
|
|
11441
11450
|
Engine failed: ${msg}
|
|
11442
11451
|
`));
|
|
11443
11452
|
writeErrorLog(config, void 0, msg, "exception");
|
|
@@ -11449,15 +11458,15 @@ async function initCommand(options) {
|
|
|
11449
11458
|
const mins = Math.floor(elapsedMs / 6e4);
|
|
11450
11459
|
const secs = Math.floor(elapsedMs % 6e4 / 1e3);
|
|
11451
11460
|
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
11452
|
-
console.log(
|
|
11461
|
+
console.log(chalk13.dim(`
|
|
11453
11462
|
Done in ${timeStr}
|
|
11454
11463
|
`));
|
|
11455
11464
|
if (!generatedSetup) {
|
|
11456
|
-
console.log(
|
|
11465
|
+
console.log(chalk13.red(" Failed to generate config."));
|
|
11457
11466
|
writeErrorLog(config, rawOutput, void 0, genStopReason);
|
|
11458
11467
|
if (rawOutput) {
|
|
11459
|
-
console.log(
|
|
11460
|
-
console.log(
|
|
11468
|
+
console.log(chalk13.dim("\nRaw LLM output (JSON parse failed):"));
|
|
11469
|
+
console.log(chalk13.dim(rawOutput.slice(0, 500)));
|
|
11461
11470
|
}
|
|
11462
11471
|
throw new Error("__exit__");
|
|
11463
11472
|
}
|
|
@@ -11476,19 +11485,19 @@ async function initCommand(options) {
|
|
|
11476
11485
|
const changes = formatWhatChanged(generatedSetup);
|
|
11477
11486
|
if (changes.length > 0) {
|
|
11478
11487
|
for (const line of changes) {
|
|
11479
|
-
console.log(` ${
|
|
11488
|
+
console.log(` ${chalk13.dim("\u2022")} ${line}`);
|
|
11480
11489
|
}
|
|
11481
11490
|
console.log("");
|
|
11482
11491
|
}
|
|
11483
11492
|
console.log(
|
|
11484
|
-
|
|
11485
|
-
` ${
|
|
11493
|
+
chalk13.dim(
|
|
11494
|
+
` ${chalk13.green(`${staged.newFiles} new`)} / ${chalk13.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}`
|
|
11486
11495
|
)
|
|
11487
11496
|
);
|
|
11488
11497
|
if (skillSearchResult.results.length > 0) {
|
|
11489
11498
|
console.log(
|
|
11490
|
-
|
|
11491
|
-
` ${
|
|
11499
|
+
chalk13.dim(
|
|
11500
|
+
` ${chalk13.cyan(`${skillSearchResult.results.length}`)} community skills available to install
|
|
11492
11501
|
`
|
|
11493
11502
|
)
|
|
11494
11503
|
);
|
|
@@ -11498,7 +11507,7 @@ async function initCommand(options) {
|
|
|
11498
11507
|
const hasSkillResults = skillSearchResult.results.length > 0;
|
|
11499
11508
|
let action;
|
|
11500
11509
|
if (totalChanges === 0 && !hasSkillResults) {
|
|
11501
|
-
console.log(
|
|
11510
|
+
console.log(chalk13.dim(" No changes needed \u2014 your configs are already up to date.\n"));
|
|
11502
11511
|
cleanupStaging();
|
|
11503
11512
|
action = "accept";
|
|
11504
11513
|
} else if (options.autoApprove) {
|
|
@@ -11522,14 +11531,14 @@ async function initCommand(options) {
|
|
|
11522
11531
|
trackInitRefinementRound(refinementRound, !!generatedSetup);
|
|
11523
11532
|
if (!generatedSetup) {
|
|
11524
11533
|
cleanupStaging();
|
|
11525
|
-
console.log(
|
|
11534
|
+
console.log(chalk13.dim("Refinement cancelled. No files were modified."));
|
|
11526
11535
|
return;
|
|
11527
11536
|
}
|
|
11528
11537
|
const updatedFiles = collectSetupFiles(generatedSetup, targetAgent);
|
|
11529
11538
|
const restaged = stageFiles(updatedFiles, process.cwd());
|
|
11530
11539
|
console.log(
|
|
11531
|
-
|
|
11532
|
-
` ${
|
|
11540
|
+
chalk13.dim(
|
|
11541
|
+
` ${chalk13.green(`${restaged.newFiles} new`)} / ${chalk13.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
|
|
11533
11542
|
`
|
|
11534
11543
|
)
|
|
11535
11544
|
);
|
|
@@ -11541,11 +11550,11 @@ async function initCommand(options) {
|
|
|
11541
11550
|
}
|
|
11542
11551
|
cleanupStaging();
|
|
11543
11552
|
if (action === "decline") {
|
|
11544
|
-
console.log(
|
|
11553
|
+
console.log(chalk13.dim("Declined. No files were modified."));
|
|
11545
11554
|
return;
|
|
11546
11555
|
}
|
|
11547
11556
|
if (options.dryRun) {
|
|
11548
|
-
console.log(
|
|
11557
|
+
console.log(chalk13.yellow("\n[Dry run] Would write the following files:"));
|
|
11549
11558
|
console.log(JSON.stringify(generatedSetup, null, 2));
|
|
11550
11559
|
return;
|
|
11551
11560
|
}
|
|
@@ -11576,23 +11585,23 @@ ${agentRefs.join(" ")}
|
|
|
11576
11585
|
0,
|
|
11577
11586
|
result.deleted.length
|
|
11578
11587
|
);
|
|
11579
|
-
console.log(
|
|
11588
|
+
console.log(chalk13.bold("\nFiles created/updated:"));
|
|
11580
11589
|
for (const file of result.written) {
|
|
11581
|
-
console.log(` ${
|
|
11590
|
+
console.log(` ${chalk13.green("\u2713")} ${file}`);
|
|
11582
11591
|
}
|
|
11583
11592
|
if (result.deleted.length > 0) {
|
|
11584
|
-
console.log(
|
|
11593
|
+
console.log(chalk13.bold("\nFiles removed:"));
|
|
11585
11594
|
for (const file of result.deleted) {
|
|
11586
|
-
console.log(` ${
|
|
11595
|
+
console.log(` ${chalk13.red("\u2717")} ${file}`);
|
|
11587
11596
|
}
|
|
11588
11597
|
}
|
|
11589
11598
|
if (result.backupDir) {
|
|
11590
|
-
console.log(
|
|
11599
|
+
console.log(chalk13.dim(`
|
|
11591
11600
|
Backups saved to ${result.backupDir}`));
|
|
11592
11601
|
}
|
|
11593
11602
|
} catch (err) {
|
|
11594
11603
|
writeSpinner.fail("Failed to write files");
|
|
11595
|
-
console.error(
|
|
11604
|
+
console.error(chalk13.red(err instanceof Error ? err.message : "Unknown error"));
|
|
11596
11605
|
throw new Error("__exit__");
|
|
11597
11606
|
}
|
|
11598
11607
|
if (fingerprint) ensurePermissions(fingerprint);
|
|
@@ -11607,7 +11616,7 @@ ${agentRefs.join(" ")}
|
|
|
11607
11616
|
trackInitScoreRegression(baselineScore.score, afterScore.score);
|
|
11608
11617
|
console.log("");
|
|
11609
11618
|
console.log(
|
|
11610
|
-
|
|
11619
|
+
chalk13.yellow(
|
|
11611
11620
|
` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`
|
|
11612
11621
|
)
|
|
11613
11622
|
);
|
|
@@ -11615,7 +11624,7 @@ ${agentRefs.join(" ")}
|
|
|
11615
11624
|
const { restored, removed } = undoSetup();
|
|
11616
11625
|
if (restored.length > 0 || removed.length > 0) {
|
|
11617
11626
|
console.log(
|
|
11618
|
-
|
|
11627
|
+
chalk13.dim(
|
|
11619
11628
|
` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`
|
|
11620
11629
|
)
|
|
11621
11630
|
);
|
|
@@ -11623,7 +11632,7 @@ ${agentRefs.join(" ")}
|
|
|
11623
11632
|
} catch {
|
|
11624
11633
|
}
|
|
11625
11634
|
console.log(
|
|
11626
|
-
|
|
11635
|
+
chalk13.dim(" Run ") + chalk13.hex("#83D1EB")(`${bin} init --force`) + chalk13.dim(" to override.\n")
|
|
11627
11636
|
);
|
|
11628
11637
|
return;
|
|
11629
11638
|
}
|
|
@@ -11654,7 +11663,7 @@ ${agentRefs.join(" ")}
|
|
|
11654
11663
|
}
|
|
11655
11664
|
let communitySkillsInstalled = 0;
|
|
11656
11665
|
if (skillSearchResult.results.length > 0 && !options.autoApprove) {
|
|
11657
|
-
console.log(
|
|
11666
|
+
console.log(chalk13.dim(" Community skills matched to your project:\n"));
|
|
11658
11667
|
const selected = await interactiveSelect(skillSearchResult.results);
|
|
11659
11668
|
if (selected?.length) {
|
|
11660
11669
|
await installSkills(selected, targetAgent, skillSearchResult.contentMap);
|
|
@@ -11663,32 +11672,32 @@ ${agentRefs.join(" ")}
|
|
|
11663
11672
|
}
|
|
11664
11673
|
}
|
|
11665
11674
|
trackInitHookSelected("config-instructions");
|
|
11666
|
-
const done =
|
|
11667
|
-
console.log(
|
|
11668
|
-
console.log(
|
|
11675
|
+
const done = chalk13.green("\u2713");
|
|
11676
|
+
console.log(chalk13.bold.green("\n Caliber is set up!\n"));
|
|
11677
|
+
console.log(chalk13.bold(" What's configured:\n"));
|
|
11669
11678
|
console.log(
|
|
11670
|
-
` ${done} Continuous sync ${
|
|
11679
|
+
` ${done} Continuous sync ${chalk13.dim("pre-commit hook keeps all agent configs in sync")}`
|
|
11671
11680
|
);
|
|
11672
11681
|
console.log(
|
|
11673
|
-
` ${done} Config generated ${title(`${bin} score`)} ${
|
|
11682
|
+
` ${done} Config generated ${title(`${bin} score`)} ${chalk13.dim("for full breakdown")}`
|
|
11674
11683
|
);
|
|
11675
11684
|
console.log(
|
|
11676
|
-
` ${done} Agent skills ${
|
|
11685
|
+
` ${done} Agent skills ${chalk13.dim("/setup-caliber for new team members")}`
|
|
11677
11686
|
);
|
|
11678
11687
|
if (hasLearnableAgent) {
|
|
11679
11688
|
console.log(
|
|
11680
|
-
` ${done} Session learning ${
|
|
11689
|
+
` ${done} Session learning ${chalk13.dim("agent learns from your feedback")}`
|
|
11681
11690
|
);
|
|
11682
11691
|
}
|
|
11683
11692
|
if (communitySkillsInstalled > 0) {
|
|
11684
11693
|
console.log(
|
|
11685
|
-
` ${done} Community skills ${
|
|
11694
|
+
` ${done} Community skills ${chalk13.dim(`${communitySkillsInstalled} skill${communitySkillsInstalled > 1 ? "s" : ""} installed for your stack`)}`
|
|
11686
11695
|
);
|
|
11687
11696
|
}
|
|
11688
|
-
console.log(
|
|
11689
|
-
console.log(
|
|
11690
|
-
console.log(
|
|
11691
|
-
console.log(
|
|
11697
|
+
console.log(chalk13.bold("\n What happens next:\n"));
|
|
11698
|
+
console.log(chalk13.dim(" Every commit will automatically sync your agent configs."));
|
|
11699
|
+
console.log(chalk13.dim(" New team members can run /setup-caliber to get set up instantly.\n"));
|
|
11700
|
+
console.log(chalk13.bold(" Explore:\n"));
|
|
11692
11701
|
console.log(` ${title(`${bin} score`)} Full scoring breakdown with improvement tips`);
|
|
11693
11702
|
console.log(` ${title(`${bin} skills`)} Find community skills for your stack`);
|
|
11694
11703
|
console.log(` ${title(`${bin} undo`)} Revert all changes from this run`);
|
|
@@ -11702,14 +11711,14 @@ ${agentRefs.join(" ")}
|
|
|
11702
11711
|
const reportPath = path28.join(process.cwd(), ".caliber", "debug-report.md");
|
|
11703
11712
|
report.write(reportPath);
|
|
11704
11713
|
console.log(
|
|
11705
|
-
|
|
11714
|
+
chalk13.dim(` Debug report written to ${path28.relative(process.cwd(), reportPath)}
|
|
11706
11715
|
`)
|
|
11707
11716
|
);
|
|
11708
11717
|
}
|
|
11709
11718
|
}
|
|
11710
11719
|
|
|
11711
11720
|
// src/commands/undo.ts
|
|
11712
|
-
import
|
|
11721
|
+
import chalk14 from "chalk";
|
|
11713
11722
|
import ora4 from "ora";
|
|
11714
11723
|
function undoCommand() {
|
|
11715
11724
|
const spinner = ora4("Reverting config changes...").start();
|
|
@@ -11722,26 +11731,26 @@ function undoCommand() {
|
|
|
11722
11731
|
trackUndoExecuted();
|
|
11723
11732
|
spinner.succeed("Config reverted successfully.\n");
|
|
11724
11733
|
if (restored.length > 0) {
|
|
11725
|
-
console.log(
|
|
11734
|
+
console.log(chalk14.cyan(" Restored from backup:"));
|
|
11726
11735
|
for (const file of restored) {
|
|
11727
|
-
console.log(` ${
|
|
11736
|
+
console.log(` ${chalk14.green("\u21A9")} ${file}`);
|
|
11728
11737
|
}
|
|
11729
11738
|
}
|
|
11730
11739
|
if (removed.length > 0) {
|
|
11731
|
-
console.log(
|
|
11740
|
+
console.log(chalk14.cyan(" Removed:"));
|
|
11732
11741
|
for (const file of removed) {
|
|
11733
|
-
console.log(` ${
|
|
11742
|
+
console.log(` ${chalk14.red("\u2717")} ${file}`);
|
|
11734
11743
|
}
|
|
11735
11744
|
}
|
|
11736
11745
|
console.log("");
|
|
11737
11746
|
} catch (err) {
|
|
11738
|
-
spinner.fail(
|
|
11747
|
+
spinner.fail(chalk14.red(err instanceof Error ? err.message : "Undo failed"));
|
|
11739
11748
|
throw new Error("__exit__");
|
|
11740
11749
|
}
|
|
11741
11750
|
}
|
|
11742
11751
|
|
|
11743
11752
|
// src/commands/status.ts
|
|
11744
|
-
import
|
|
11753
|
+
import chalk15 from "chalk";
|
|
11745
11754
|
import fs36 from "fs";
|
|
11746
11755
|
init_config();
|
|
11747
11756
|
init_resolve_caliber();
|
|
@@ -11757,29 +11766,29 @@ async function statusCommand(options) {
|
|
|
11757
11766
|
}, null, 2));
|
|
11758
11767
|
return;
|
|
11759
11768
|
}
|
|
11760
|
-
console.log(
|
|
11769
|
+
console.log(chalk15.bold("\nCaliber Status\n"));
|
|
11761
11770
|
if (config) {
|
|
11762
|
-
console.log(` LLM: ${
|
|
11771
|
+
console.log(` LLM: ${chalk15.green(config.provider)} (${config.model})`);
|
|
11763
11772
|
} else {
|
|
11764
11773
|
const bin = resolveCaliber();
|
|
11765
|
-
console.log(` LLM: ${
|
|
11774
|
+
console.log(` LLM: ${chalk15.yellow("Not configured")} \u2014 run ${chalk15.hex("#83D1EB")(`${bin} config`)}`);
|
|
11766
11775
|
}
|
|
11767
11776
|
if (!manifest) {
|
|
11768
|
-
console.log(` Config: ${
|
|
11769
|
-
console.log(
|
|
11777
|
+
console.log(` Config: ${chalk15.dim("No config applied")}`);
|
|
11778
|
+
console.log(chalk15.dim("\n Run ") + chalk15.hex("#83D1EB")(`${resolveCaliber()} init`) + chalk15.dim(" to get started.\n"));
|
|
11770
11779
|
return;
|
|
11771
11780
|
}
|
|
11772
|
-
console.log(` Files managed: ${
|
|
11781
|
+
console.log(` Files managed: ${chalk15.cyan(manifest.entries.length.toString())}`);
|
|
11773
11782
|
for (const entry of manifest.entries) {
|
|
11774
11783
|
const exists = fs36.existsSync(entry.path);
|
|
11775
|
-
const icon = exists ?
|
|
11784
|
+
const icon = exists ? chalk15.green("\u2713") : chalk15.red("\u2717");
|
|
11776
11785
|
console.log(` ${icon} ${entry.path} (${entry.action})`);
|
|
11777
11786
|
}
|
|
11778
11787
|
console.log("");
|
|
11779
11788
|
}
|
|
11780
11789
|
|
|
11781
11790
|
// src/commands/regenerate.ts
|
|
11782
|
-
import
|
|
11791
|
+
import chalk16 from "chalk";
|
|
11783
11792
|
import ora5 from "ora";
|
|
11784
11793
|
import select6 from "@inquirer/select";
|
|
11785
11794
|
init_review();
|
|
@@ -11789,12 +11798,12 @@ async function regenerateCommand(options) {
|
|
|
11789
11798
|
const bin = resolveCaliber();
|
|
11790
11799
|
const config = loadConfig();
|
|
11791
11800
|
if (!config) {
|
|
11792
|
-
console.log(
|
|
11801
|
+
console.log(chalk16.red("No LLM provider configured. Run ") + chalk16.hex("#83D1EB")(`${bin} config`) + chalk16.red(" first."));
|
|
11793
11802
|
throw new Error("__exit__");
|
|
11794
11803
|
}
|
|
11795
11804
|
const manifest = readManifest();
|
|
11796
11805
|
if (!manifest) {
|
|
11797
|
-
console.log(
|
|
11806
|
+
console.log(chalk16.yellow("No existing config found. Run ") + chalk16.hex("#83D1EB")(`${bin} init`) + chalk16.yellow(" first."));
|
|
11798
11807
|
throw new Error("__exit__");
|
|
11799
11808
|
}
|
|
11800
11809
|
const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
|
|
@@ -11805,7 +11814,7 @@ async function regenerateCommand(options) {
|
|
|
11805
11814
|
const baselineScore = computeLocalScore(process.cwd(), targetAgent);
|
|
11806
11815
|
displayScoreSummary(baselineScore);
|
|
11807
11816
|
if (baselineScore.score === 100) {
|
|
11808
|
-
console.log(
|
|
11817
|
+
console.log(chalk16.green(" Your config is already at 100/100 \u2014 nothing to regenerate.\n"));
|
|
11809
11818
|
return;
|
|
11810
11819
|
}
|
|
11811
11820
|
const genSpinner = ora5("Regenerating config...").start();
|
|
@@ -11847,18 +11856,18 @@ async function regenerateCommand(options) {
|
|
|
11847
11856
|
const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
|
|
11848
11857
|
const staged = stageFiles(setupFiles, process.cwd());
|
|
11849
11858
|
const totalChanges = staged.newFiles + staged.modifiedFiles;
|
|
11850
|
-
console.log(
|
|
11851
|
-
${
|
|
11859
|
+
console.log(chalk16.dim(`
|
|
11860
|
+
${chalk16.green(`${staged.newFiles} new`)} / ${chalk16.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
|
|
11852
11861
|
`));
|
|
11853
11862
|
if (totalChanges === 0) {
|
|
11854
|
-
console.log(
|
|
11863
|
+
console.log(chalk16.dim(" No changes needed \u2014 your configs are already up to date.\n"));
|
|
11855
11864
|
cleanupStaging();
|
|
11856
11865
|
return;
|
|
11857
11866
|
}
|
|
11858
11867
|
if (options.dryRun) {
|
|
11859
|
-
console.log(
|
|
11868
|
+
console.log(chalk16.yellow("[Dry run] Would write:"));
|
|
11860
11869
|
for (const f of staged.stagedFiles) {
|
|
11861
|
-
console.log(` ${f.isNew ?
|
|
11870
|
+
console.log(` ${f.isNew ? chalk16.green("+") : chalk16.yellow("~")} ${f.relativePath}`);
|
|
11862
11871
|
}
|
|
11863
11872
|
cleanupStaging();
|
|
11864
11873
|
return;
|
|
@@ -11877,7 +11886,7 @@ async function regenerateCommand(options) {
|
|
|
11877
11886
|
});
|
|
11878
11887
|
cleanupStaging();
|
|
11879
11888
|
if (action === "decline") {
|
|
11880
|
-
console.log(
|
|
11889
|
+
console.log(chalk16.dim("Regeneration cancelled. No files were modified."));
|
|
11881
11890
|
return;
|
|
11882
11891
|
}
|
|
11883
11892
|
const writeSpinner = ora5("Writing config files...").start();
|
|
@@ -11885,20 +11894,20 @@ async function regenerateCommand(options) {
|
|
|
11885
11894
|
const result = writeSetup(generatedSetup);
|
|
11886
11895
|
writeSpinner.succeed("Config files written");
|
|
11887
11896
|
for (const file of result.written) {
|
|
11888
|
-
console.log(` ${
|
|
11897
|
+
console.log(` ${chalk16.green("\u2713")} ${file}`);
|
|
11889
11898
|
}
|
|
11890
11899
|
if (result.deleted.length > 0) {
|
|
11891
11900
|
for (const file of result.deleted) {
|
|
11892
|
-
console.log(` ${
|
|
11901
|
+
console.log(` ${chalk16.red("\u2717")} ${file}`);
|
|
11893
11902
|
}
|
|
11894
11903
|
}
|
|
11895
11904
|
if (result.backupDir) {
|
|
11896
|
-
console.log(
|
|
11905
|
+
console.log(chalk16.dim(`
|
|
11897
11906
|
Backups saved to ${result.backupDir}`));
|
|
11898
11907
|
}
|
|
11899
11908
|
} catch (err) {
|
|
11900
11909
|
writeSpinner.fail("Failed to write files");
|
|
11901
|
-
console.error(
|
|
11910
|
+
console.error(chalk16.red(err instanceof Error ? err.message : "Unknown error"));
|
|
11902
11911
|
throw new Error("__exit__");
|
|
11903
11912
|
}
|
|
11904
11913
|
const sha = getCurrentHeadSha();
|
|
@@ -11910,21 +11919,21 @@ async function regenerateCommand(options) {
|
|
|
11910
11919
|
const afterScore = computeLocalScore(process.cwd(), targetAgent);
|
|
11911
11920
|
if (afterScore.score < baselineScore.score) {
|
|
11912
11921
|
console.log("");
|
|
11913
|
-
console.log(
|
|
11922
|
+
console.log(chalk16.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
|
|
11914
11923
|
try {
|
|
11915
11924
|
const { restored, removed } = undoSetup();
|
|
11916
11925
|
if (restored.length > 0 || removed.length > 0) {
|
|
11917
|
-
console.log(
|
|
11926
|
+
console.log(chalk16.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
|
|
11918
11927
|
}
|
|
11919
11928
|
} catch {
|
|
11920
11929
|
}
|
|
11921
|
-
console.log(
|
|
11930
|
+
console.log(chalk16.dim(" Run ") + chalk16.hex("#83D1EB")(`${bin} init --force`) + chalk16.dim(" to override.\n"));
|
|
11922
11931
|
return;
|
|
11923
11932
|
}
|
|
11924
11933
|
displayScoreDelta(baselineScore, afterScore);
|
|
11925
11934
|
trackRegenerateCompleted(action, Date.now());
|
|
11926
|
-
console.log(
|
|
11927
|
-
console.log(
|
|
11935
|
+
console.log(chalk16.bold.green(" Regeneration complete!"));
|
|
11936
|
+
console.log(chalk16.dim(" Run ") + chalk16.hex("#83D1EB")(`${bin} undo`) + chalk16.dim(" to revert changes.\n"));
|
|
11928
11937
|
}
|
|
11929
11938
|
|
|
11930
11939
|
// src/commands/score.ts
|
|
@@ -11932,7 +11941,7 @@ import fs37 from "fs";
|
|
|
11932
11941
|
import os7 from "os";
|
|
11933
11942
|
import path29 from "path";
|
|
11934
11943
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
11935
|
-
import
|
|
11944
|
+
import chalk17 from "chalk";
|
|
11936
11945
|
init_resolve_caliber();
|
|
11937
11946
|
var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".cursorrules", "CALIBER_LEARNINGS.md"];
|
|
11938
11947
|
var CONFIG_DIRS = [".claude", ".cursor"];
|
|
@@ -11986,7 +11995,7 @@ async function scoreCommand(options) {
|
|
|
11986
11995
|
const baseResult = scoreBaseRef(options.compare, target);
|
|
11987
11996
|
if (!baseResult) {
|
|
11988
11997
|
console.error(
|
|
11989
|
-
|
|
11998
|
+
chalk17.red(`Could not score ref "${options.compare}" \u2014 branch or ref not found.`)
|
|
11990
11999
|
);
|
|
11991
12000
|
process.exitCode = 1;
|
|
11992
12001
|
return;
|
|
@@ -12012,18 +12021,18 @@ async function scoreCommand(options) {
|
|
|
12012
12021
|
return;
|
|
12013
12022
|
}
|
|
12014
12023
|
displayScore(result);
|
|
12015
|
-
const separator2 =
|
|
12024
|
+
const separator2 = chalk17.gray(" " + "\u2500".repeat(53));
|
|
12016
12025
|
console.log(separator2);
|
|
12017
12026
|
if (delta > 0) {
|
|
12018
12027
|
console.log(
|
|
12019
|
-
|
|
12028
|
+
chalk17.green(` +${delta}`) + chalk17.gray(` from ${options.compare} (${baseResult.score}/100)`)
|
|
12020
12029
|
);
|
|
12021
12030
|
} else if (delta < 0) {
|
|
12022
12031
|
console.log(
|
|
12023
|
-
|
|
12032
|
+
chalk17.red(` ${delta}`) + chalk17.gray(` from ${options.compare} (${baseResult.score}/100)`)
|
|
12024
12033
|
);
|
|
12025
12034
|
} else {
|
|
12026
|
-
console.log(
|
|
12035
|
+
console.log(chalk17.gray(` No change from ${options.compare} (${baseResult.score}/100)`));
|
|
12027
12036
|
}
|
|
12028
12037
|
console.log("");
|
|
12029
12038
|
return;
|
|
@@ -12037,7 +12046,7 @@ async function scoreCommand(options) {
|
|
|
12037
12046
|
return;
|
|
12038
12047
|
}
|
|
12039
12048
|
displayScore(result);
|
|
12040
|
-
const separator =
|
|
12049
|
+
const separator = chalk17.gray(" " + "\u2500".repeat(53));
|
|
12041
12050
|
console.log(separator);
|
|
12042
12051
|
const bin = resolveCaliber();
|
|
12043
12052
|
const failing = result.checks.filter((c) => !c.passed && c.maxPoints > 0).sort((a, b) => b.maxPoints - b.earnedPoints - (a.maxPoints - a.earnedPoints));
|
|
@@ -12045,22 +12054,22 @@ async function scoreCommand(options) {
|
|
|
12045
12054
|
const topFix = failing[0];
|
|
12046
12055
|
const pts = topFix.maxPoints - topFix.earnedPoints;
|
|
12047
12056
|
console.log(
|
|
12048
|
-
|
|
12057
|
+
chalk17.gray(" Biggest gain: ") + chalk17.yellow(`+${pts} pts`) + chalk17.gray(` from "${topFix.name}"`) + (topFix.suggestion ? chalk17.gray(` \u2014 ${topFix.suggestion}`) : "")
|
|
12049
12058
|
);
|
|
12050
12059
|
console.log(
|
|
12051
|
-
|
|
12060
|
+
chalk17.gray(" Run ") + chalk17.hex("#83D1EB")(`${bin} init`) + chalk17.gray(" to generate or update your agent config files.")
|
|
12052
12061
|
);
|
|
12053
12062
|
} else if (failing.length > 0) {
|
|
12054
12063
|
console.log(
|
|
12055
|
-
|
|
12064
|
+
chalk17.green(" Looking good!") + chalk17.gray(
|
|
12056
12065
|
` ${failing.length} optional improvement${failing.length === 1 ? "" : "s"} available.`
|
|
12057
12066
|
)
|
|
12058
12067
|
);
|
|
12059
12068
|
console.log(
|
|
12060
|
-
|
|
12069
|
+
chalk17.gray(" Run ") + chalk17.hex("#83D1EB")(`${bin} init`) + chalk17.gray(" to improve, or ") + chalk17.hex("#83D1EB")(`${bin} regenerate`) + chalk17.gray(" to rebuild from scratch.")
|
|
12061
12070
|
);
|
|
12062
12071
|
} else {
|
|
12063
|
-
console.log(
|
|
12072
|
+
console.log(chalk17.green(" Perfect score! Your agent configs are fully optimized."));
|
|
12064
12073
|
}
|
|
12065
12074
|
console.log("");
|
|
12066
12075
|
}
|
|
@@ -12068,7 +12077,7 @@ async function scoreCommand(options) {
|
|
|
12068
12077
|
// src/commands/refresh.ts
|
|
12069
12078
|
import fs42 from "fs";
|
|
12070
12079
|
import path34 from "path";
|
|
12071
|
-
import
|
|
12080
|
+
import chalk18 from "chalk";
|
|
12072
12081
|
import ora6 from "ora";
|
|
12073
12082
|
import pLimit from "p-limit";
|
|
12074
12083
|
|
|
@@ -12729,7 +12738,7 @@ async function refreshDir(repoDir, dir, diff, options) {
|
|
|
12729
12738
|
const quiet = !!options.quiet;
|
|
12730
12739
|
const suppress = !!options.suppressSpinner;
|
|
12731
12740
|
const effectiveQuiet = quiet || suppress;
|
|
12732
|
-
const prefix = options.label ? `${
|
|
12741
|
+
const prefix = options.label ? `${chalk18.bold(options.label)} ` : "";
|
|
12733
12742
|
const absDir = dir === "." ? repoDir : path34.resolve(repoDir, dir);
|
|
12734
12743
|
const scope = dir === "." ? void 0 : dir;
|
|
12735
12744
|
const spinner = effectiveQuiet ? null : ora6(`${prefix}Analyzing changes...`).start();
|
|
@@ -12786,10 +12795,10 @@ async function refreshDir(repoDir, dir, diff, options) {
|
|
|
12786
12795
|
if (options.dryRun) {
|
|
12787
12796
|
spinner?.info(`${prefix}Dry run \u2014 would update:`);
|
|
12788
12797
|
for (const doc of response.docsUpdated) {
|
|
12789
|
-
console.log(` ${
|
|
12798
|
+
console.log(` ${chalk18.yellow("~")} ${doc}`);
|
|
12790
12799
|
}
|
|
12791
12800
|
if (response.changesSummary) {
|
|
12792
|
-
console.log(
|
|
12801
|
+
console.log(chalk18.dim(`
|
|
12793
12802
|
${response.changesSummary}`));
|
|
12794
12803
|
}
|
|
12795
12804
|
return { written: [], fileChanges: [], syncedAgents: [], changesSummary: null };
|
|
@@ -12830,7 +12839,7 @@ async function refreshDir(repoDir, dir, diff, options) {
|
|
|
12830
12839
|
);
|
|
12831
12840
|
log2(
|
|
12832
12841
|
effectiveQuiet,
|
|
12833
|
-
|
|
12842
|
+
chalk18.dim(` Config quality gate prevented a regression. No files were changed.`)
|
|
12834
12843
|
);
|
|
12835
12844
|
return { written: [], fileChanges: [], syncedAgents: [], changesSummary: null };
|
|
12836
12845
|
}
|
|
@@ -12843,18 +12852,18 @@ async function refreshDir(repoDir, dir, diff, options) {
|
|
|
12843
12852
|
if (!suppress) {
|
|
12844
12853
|
for (const file of written) {
|
|
12845
12854
|
const desc = fileChangesMap.get(file);
|
|
12846
|
-
const suffix = desc ?
|
|
12847
|
-
log2(effectiveQuiet, ` ${
|
|
12855
|
+
const suffix = desc ? chalk18.dim(` \u2014 ${desc}`) : "";
|
|
12856
|
+
log2(effectiveQuiet, ` ${chalk18.green("\u2713")} ${file}${suffix}`);
|
|
12848
12857
|
}
|
|
12849
12858
|
if (syncedAgents.length > 1) {
|
|
12850
12859
|
log2(
|
|
12851
12860
|
effectiveQuiet,
|
|
12852
|
-
|
|
12861
|
+
chalk18.cyan(`
|
|
12853
12862
|
${syncedAgents.length} agent formats in sync (${syncedAgents.join(", ")})`)
|
|
12854
12863
|
);
|
|
12855
12864
|
}
|
|
12856
12865
|
if (response.changesSummary) {
|
|
12857
|
-
log2(effectiveQuiet,
|
|
12866
|
+
log2(effectiveQuiet, chalk18.dim(`
|
|
12858
12867
|
${response.changesSummary}`));
|
|
12859
12868
|
}
|
|
12860
12869
|
}
|
|
@@ -12862,7 +12871,7 @@ async function refreshDir(repoDir, dir, diff, options) {
|
|
|
12862
12871
|
}
|
|
12863
12872
|
async function refreshSingleRepo(repoDir, options) {
|
|
12864
12873
|
const quiet = !!options.quiet;
|
|
12865
|
-
const prefix = options.label ? `${
|
|
12874
|
+
const prefix = options.label ? `${chalk18.bold(options.label)} ` : "";
|
|
12866
12875
|
const state = readState();
|
|
12867
12876
|
const lastSha = state?.lastRefreshSha ?? null;
|
|
12868
12877
|
const currentSha = getCurrentHeadSha();
|
|
@@ -12871,7 +12880,7 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
12871
12880
|
if (elapsed < REFRESH_COOLDOWN_MS && elapsed > 0) {
|
|
12872
12881
|
log2(
|
|
12873
12882
|
quiet,
|
|
12874
|
-
|
|
12883
|
+
chalk18.dim(`${prefix}Skipped \u2014 last refresh was ${Math.round(elapsed / 1e3)}s ago.`)
|
|
12875
12884
|
);
|
|
12876
12885
|
return;
|
|
12877
12886
|
}
|
|
@@ -12881,14 +12890,14 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
12881
12890
|
if (currentSha) {
|
|
12882
12891
|
writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
12883
12892
|
}
|
|
12884
|
-
log2(quiet,
|
|
12893
|
+
log2(quiet, chalk18.dim(`${prefix}No changes since last refresh.`));
|
|
12885
12894
|
return;
|
|
12886
12895
|
}
|
|
12887
12896
|
const configDirs = discoverConfigDirs(repoDir);
|
|
12888
12897
|
if (configDirs.length <= 1) {
|
|
12889
12898
|
await refreshDir(repoDir, ".", diff, options);
|
|
12890
12899
|
} else {
|
|
12891
|
-
log2(quiet,
|
|
12900
|
+
log2(quiet, chalk18.dim(`${prefix}Found configs in ${configDirs.length} directories
|
|
12892
12901
|
`));
|
|
12893
12902
|
const dirsWithChanges = configDirs.map((dir) => ({ dir, scopedDiff: scopeDiffToDir(diff, dir, configDirs) })).filter(({ scopedDiff }) => scopedDiff.hasChanges);
|
|
12894
12903
|
const parallelSpinner = quiet ? null : ora6(
|
|
@@ -12916,7 +12925,7 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
12916
12925
|
hadFailure = true;
|
|
12917
12926
|
log2(
|
|
12918
12927
|
quiet,
|
|
12919
|
-
|
|
12928
|
+
chalk18.yellow(
|
|
12920
12929
|
` ${dirLabel}: refresh failed \u2014 ${result.reason instanceof Error ? result.reason.message : "unknown error"}`
|
|
12921
12930
|
)
|
|
12922
12931
|
);
|
|
@@ -12925,20 +12934,20 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
12925
12934
|
const fileChangesMap = new Map(fileChanges.map((fc) => [fc.file, fc.description]));
|
|
12926
12935
|
for (const file of written) {
|
|
12927
12936
|
const desc = fileChangesMap.get(file);
|
|
12928
|
-
const suffix = desc ?
|
|
12929
|
-
log2(quiet, ` ${
|
|
12937
|
+
const suffix = desc ? chalk18.dim(` \u2014 ${desc}`) : "";
|
|
12938
|
+
log2(quiet, ` ${chalk18.green("\u2713")} ${dirLabel}/${file}${suffix}`);
|
|
12930
12939
|
}
|
|
12931
12940
|
if (syncedAgents.length > 1) {
|
|
12932
12941
|
log2(
|
|
12933
12942
|
quiet,
|
|
12934
|
-
|
|
12943
|
+
chalk18.cyan(
|
|
12935
12944
|
`
|
|
12936
12945
|
${syncedAgents.length} agent formats in sync (${syncedAgents.join(", ")})`
|
|
12937
12946
|
)
|
|
12938
12947
|
);
|
|
12939
12948
|
}
|
|
12940
12949
|
if (changesSummary) {
|
|
12941
|
-
log2(quiet,
|
|
12950
|
+
log2(quiet, chalk18.dim(`
|
|
12942
12951
|
${changesSummary}`));
|
|
12943
12952
|
}
|
|
12944
12953
|
}
|
|
@@ -12949,7 +12958,7 @@ async function refreshSingleRepo(repoDir, options) {
|
|
|
12949
12958
|
}
|
|
12950
12959
|
const builtinWritten = ensureBuiltinSkills();
|
|
12951
12960
|
for (const file of builtinWritten) {
|
|
12952
|
-
log2(quiet, ` ${
|
|
12961
|
+
log2(quiet, ` ${chalk18.green("\u2713")} ${file} ${chalk18.dim("(built-in)")}`);
|
|
12953
12962
|
}
|
|
12954
12963
|
clearRefreshError();
|
|
12955
12964
|
if (currentSha) {
|
|
@@ -12965,11 +12974,11 @@ async function refreshCommand(options) {
|
|
|
12965
12974
|
if (!quiet) {
|
|
12966
12975
|
const lastError = readRefreshError();
|
|
12967
12976
|
if (lastError) {
|
|
12968
|
-
console.log(
|
|
12977
|
+
console.log(chalk18.yellow(`
|
|
12969
12978
|
\u26A0 Last refresh failed (${lastError.timestamp}):`));
|
|
12970
|
-
console.log(
|
|
12979
|
+
console.log(chalk18.dim(` ${lastError.error}`));
|
|
12971
12980
|
console.log(
|
|
12972
|
-
|
|
12981
|
+
chalk18.dim(
|
|
12973
12982
|
` Run with --debug for full details, or report at https://github.com/caliber-ai-org/ai-setup/issues
|
|
12974
12983
|
`
|
|
12975
12984
|
)
|
|
@@ -12982,7 +12991,7 @@ async function refreshCommand(options) {
|
|
|
12982
12991
|
if (!config) {
|
|
12983
12992
|
if (quiet) return;
|
|
12984
12993
|
console.log(
|
|
12985
|
-
|
|
12994
|
+
chalk18.red("No LLM provider configured. Run ") + chalk18.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk18.red(" (e.g. choose Cursor) or set an API key.")
|
|
12986
12995
|
);
|
|
12987
12996
|
throw new Error("__exit__");
|
|
12988
12997
|
}
|
|
@@ -12995,11 +13004,11 @@ async function refreshCommand(options) {
|
|
|
12995
13004
|
if (repos.length === 0) {
|
|
12996
13005
|
if (quiet) return;
|
|
12997
13006
|
console.log(
|
|
12998
|
-
|
|
13007
|
+
chalk18.red("Not inside a git repository and no git repos found in child directories.")
|
|
12999
13008
|
);
|
|
13000
13009
|
throw new Error("__exit__");
|
|
13001
13010
|
}
|
|
13002
|
-
log2(quiet,
|
|
13011
|
+
log2(quiet, chalk18.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
|
|
13003
13012
|
`));
|
|
13004
13013
|
const originalDir = process.cwd();
|
|
13005
13014
|
for (const repo of repos) {
|
|
@@ -13012,7 +13021,7 @@ async function refreshCommand(options) {
|
|
|
13012
13021
|
writeRefreshError(err);
|
|
13013
13022
|
log2(
|
|
13014
13023
|
quiet,
|
|
13015
|
-
|
|
13024
|
+
chalk18.yellow(
|
|
13016
13025
|
`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`
|
|
13017
13026
|
)
|
|
13018
13027
|
);
|
|
@@ -13025,13 +13034,13 @@ async function refreshCommand(options) {
|
|
|
13025
13034
|
writeRefreshError(err);
|
|
13026
13035
|
if (quiet) return;
|
|
13027
13036
|
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
13028
|
-
console.log(
|
|
13037
|
+
console.log(chalk18.red(`Refresh failed: ${msg}`));
|
|
13029
13038
|
throw new Error("__exit__");
|
|
13030
13039
|
}
|
|
13031
13040
|
}
|
|
13032
13041
|
|
|
13033
13042
|
// src/commands/hooks.ts
|
|
13034
|
-
import
|
|
13043
|
+
import chalk19 from "chalk";
|
|
13035
13044
|
import fs43 from "fs";
|
|
13036
13045
|
var HOOKS = [
|
|
13037
13046
|
{
|
|
@@ -13068,41 +13077,41 @@ var HOOKS = [
|
|
|
13068
13077
|
}
|
|
13069
13078
|
];
|
|
13070
13079
|
function printStatus() {
|
|
13071
|
-
console.log(
|
|
13080
|
+
console.log(chalk19.bold("\n Hooks\n"));
|
|
13072
13081
|
for (const hook of HOOKS) {
|
|
13073
13082
|
const installed = hook.isInstalled();
|
|
13074
|
-
const icon = installed ?
|
|
13075
|
-
const state = installed ?
|
|
13083
|
+
const icon = installed ? chalk19.green("\u2713") : chalk19.dim("\u2717");
|
|
13084
|
+
const state = installed ? chalk19.green("enabled") : chalk19.dim("disabled");
|
|
13076
13085
|
console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
|
|
13077
|
-
console.log(
|
|
13086
|
+
console.log(chalk19.dim(` ${hook.description}`));
|
|
13078
13087
|
}
|
|
13079
13088
|
console.log("");
|
|
13080
13089
|
}
|
|
13081
13090
|
async function hooksCommand(options) {
|
|
13082
13091
|
if (!options.install && !options.remove) {
|
|
13083
13092
|
console.log(
|
|
13084
|
-
|
|
13093
|
+
chalk19.dim("\n Note: caliber now adds refresh instructions directly to config files.")
|
|
13085
13094
|
);
|
|
13086
13095
|
console.log(
|
|
13087
|
-
|
|
13096
|
+
chalk19.dim(" These hooks are available for non-agent workflows (manual commits).\n")
|
|
13088
13097
|
);
|
|
13089
13098
|
}
|
|
13090
13099
|
if (options.install) {
|
|
13091
13100
|
for (const hook of HOOKS) {
|
|
13092
13101
|
const result = hook.install();
|
|
13093
13102
|
if (result.alreadyInstalled) {
|
|
13094
|
-
console.log(
|
|
13103
|
+
console.log(chalk19.dim(` ${hook.label} already enabled.`));
|
|
13095
13104
|
} else {
|
|
13096
|
-
console.log(
|
|
13105
|
+
console.log(chalk19.green(" \u2713") + ` ${hook.label} enabled`);
|
|
13097
13106
|
}
|
|
13098
13107
|
}
|
|
13099
13108
|
if (fs43.existsSync(".claude")) {
|
|
13100
13109
|
const r = installLearningHooks();
|
|
13101
|
-
if (r.installed) console.log(
|
|
13110
|
+
if (r.installed) console.log(chalk19.green(" \u2713") + " Claude Code learning hooks enabled");
|
|
13102
13111
|
}
|
|
13103
13112
|
if (fs43.existsSync(".cursor")) {
|
|
13104
13113
|
const r = installCursorLearningHooks();
|
|
13105
|
-
if (r.installed) console.log(
|
|
13114
|
+
if (r.installed) console.log(chalk19.green(" \u2713") + " Cursor learning hooks enabled");
|
|
13106
13115
|
}
|
|
13107
13116
|
return;
|
|
13108
13117
|
}
|
|
@@ -13110,9 +13119,9 @@ async function hooksCommand(options) {
|
|
|
13110
13119
|
for (const hook of HOOKS) {
|
|
13111
13120
|
const result = hook.remove();
|
|
13112
13121
|
if (result.notFound) {
|
|
13113
|
-
console.log(
|
|
13122
|
+
console.log(chalk19.dim(` ${hook.label} already disabled.`));
|
|
13114
13123
|
} else {
|
|
13115
|
-
console.log(
|
|
13124
|
+
console.log(chalk19.green(" \u2713") + ` ${hook.label} removed`);
|
|
13116
13125
|
}
|
|
13117
13126
|
}
|
|
13118
13127
|
return;
|
|
@@ -13127,18 +13136,18 @@ async function hooksCommand(options) {
|
|
|
13127
13136
|
const states = HOOKS.map((h) => h.isInstalled());
|
|
13128
13137
|
function render() {
|
|
13129
13138
|
const lines = [];
|
|
13130
|
-
lines.push(
|
|
13139
|
+
lines.push(chalk19.bold(" Hooks"));
|
|
13131
13140
|
lines.push("");
|
|
13132
13141
|
for (let i = 0; i < HOOKS.length; i++) {
|
|
13133
13142
|
const hook = HOOKS[i];
|
|
13134
13143
|
const enabled = states[i];
|
|
13135
|
-
const toggle = enabled ?
|
|
13136
|
-
const ptr = i === cursor ?
|
|
13144
|
+
const toggle = enabled ? chalk19.green("[on] ") : chalk19.dim("[off]");
|
|
13145
|
+
const ptr = i === cursor ? chalk19.cyan(">") : " ";
|
|
13137
13146
|
lines.push(` ${ptr} ${toggle} ${hook.label}`);
|
|
13138
|
-
lines.push(
|
|
13147
|
+
lines.push(chalk19.dim(` ${hook.description}`));
|
|
13139
13148
|
}
|
|
13140
13149
|
lines.push("");
|
|
13141
|
-
lines.push(
|
|
13150
|
+
lines.push(chalk19.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
|
|
13142
13151
|
return lines.join("\n");
|
|
13143
13152
|
}
|
|
13144
13153
|
function draw(initial) {
|
|
@@ -13169,16 +13178,16 @@ async function hooksCommand(options) {
|
|
|
13169
13178
|
const wantEnabled = states[i];
|
|
13170
13179
|
if (wantEnabled && !wasInstalled) {
|
|
13171
13180
|
hook.install();
|
|
13172
|
-
console.log(
|
|
13181
|
+
console.log(chalk19.green(" \u2713") + ` ${hook.label} enabled`);
|
|
13173
13182
|
changed++;
|
|
13174
13183
|
} else if (!wantEnabled && wasInstalled) {
|
|
13175
13184
|
hook.remove();
|
|
13176
|
-
console.log(
|
|
13185
|
+
console.log(chalk19.green(" \u2713") + ` ${hook.label} disabled`);
|
|
13177
13186
|
changed++;
|
|
13178
13187
|
}
|
|
13179
13188
|
}
|
|
13180
13189
|
if (changed === 0) {
|
|
13181
|
-
console.log(
|
|
13190
|
+
console.log(chalk19.dim(" No changes."));
|
|
13182
13191
|
}
|
|
13183
13192
|
console.log("");
|
|
13184
13193
|
}
|
|
@@ -13214,7 +13223,7 @@ async function hooksCommand(options) {
|
|
|
13214
13223
|
case "\x1B":
|
|
13215
13224
|
case "":
|
|
13216
13225
|
cleanup();
|
|
13217
|
-
console.log(
|
|
13226
|
+
console.log(chalk19.dim("\n Cancelled.\n"));
|
|
13218
13227
|
resolve3();
|
|
13219
13228
|
break;
|
|
13220
13229
|
}
|
|
@@ -13225,52 +13234,52 @@ async function hooksCommand(options) {
|
|
|
13225
13234
|
|
|
13226
13235
|
// src/commands/config.ts
|
|
13227
13236
|
init_config();
|
|
13228
|
-
import
|
|
13237
|
+
import chalk20 from "chalk";
|
|
13229
13238
|
async function configCommand() {
|
|
13230
13239
|
const existing = loadConfig();
|
|
13231
13240
|
if (existing) {
|
|
13232
13241
|
const displayModel = getDisplayModel(existing);
|
|
13233
13242
|
const fastModel = getFastModel();
|
|
13234
|
-
console.log(
|
|
13235
|
-
console.log(` Provider: ${
|
|
13236
|
-
console.log(` Model: ${
|
|
13243
|
+
console.log(chalk20.bold("\nCurrent Configuration\n"));
|
|
13244
|
+
console.log(` Provider: ${chalk20.cyan(existing.provider)}`);
|
|
13245
|
+
console.log(` Model: ${chalk20.cyan(displayModel)}`);
|
|
13237
13246
|
if (fastModel) {
|
|
13238
|
-
console.log(` Scan: ${
|
|
13247
|
+
console.log(` Scan: ${chalk20.cyan(fastModel)}`);
|
|
13239
13248
|
}
|
|
13240
13249
|
if (existing.apiKey) {
|
|
13241
13250
|
const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
|
|
13242
|
-
console.log(` API Key: ${
|
|
13251
|
+
console.log(` API Key: ${chalk20.dim(masked)}`);
|
|
13243
13252
|
}
|
|
13244
13253
|
if (existing.provider === "cursor") {
|
|
13245
|
-
console.log(` Seat: ${
|
|
13254
|
+
console.log(` Seat: ${chalk20.dim("Cursor (agent acp)")}`);
|
|
13246
13255
|
}
|
|
13247
13256
|
if (existing.provider === "claude-cli") {
|
|
13248
|
-
console.log(` Seat: ${
|
|
13257
|
+
console.log(` Seat: ${chalk20.dim("Claude Code (claude -p)")}`);
|
|
13249
13258
|
}
|
|
13250
13259
|
if (existing.baseUrl) {
|
|
13251
|
-
console.log(` Base URL: ${
|
|
13260
|
+
console.log(` Base URL: ${chalk20.dim(existing.baseUrl)}`);
|
|
13252
13261
|
}
|
|
13253
13262
|
if (existing.vertexProjectId) {
|
|
13254
|
-
console.log(` Vertex Project: ${
|
|
13255
|
-
console.log(` Vertex Region: ${
|
|
13263
|
+
console.log(` Vertex Project: ${chalk20.dim(existing.vertexProjectId)}`);
|
|
13264
|
+
console.log(` Vertex Region: ${chalk20.dim(existing.vertexRegion || "us-east5")}`);
|
|
13256
13265
|
}
|
|
13257
|
-
console.log(` Source: ${
|
|
13266
|
+
console.log(` Source: ${chalk20.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())}`);
|
|
13258
13267
|
console.log("");
|
|
13259
13268
|
}
|
|
13260
13269
|
await runInteractiveProviderSetup();
|
|
13261
13270
|
const updated = loadConfig();
|
|
13262
13271
|
if (updated) trackConfigProviderSet(updated.provider);
|
|
13263
|
-
console.log(
|
|
13264
|
-
console.log(
|
|
13272
|
+
console.log(chalk20.green("\n\u2713 Configuration saved"));
|
|
13273
|
+
console.log(chalk20.dim(` ${getConfigFilePath()}
|
|
13265
13274
|
`));
|
|
13266
|
-
console.log(
|
|
13267
|
-
console.log(
|
|
13275
|
+
console.log(chalk20.dim(" You can also set environment variables instead:"));
|
|
13276
|
+
console.log(chalk20.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
|
|
13268
13277
|
}
|
|
13269
13278
|
|
|
13270
13279
|
// src/commands/learn.ts
|
|
13271
13280
|
import fs47 from "fs";
|
|
13272
13281
|
import path38 from "path";
|
|
13273
|
-
import
|
|
13282
|
+
import chalk22 from "chalk";
|
|
13274
13283
|
|
|
13275
13284
|
// src/learner/stdin.ts
|
|
13276
13285
|
var STDIN_TIMEOUT_MS = 5e3;
|
|
@@ -13470,7 +13479,7 @@ function releaseFinalizeLock() {
|
|
|
13470
13479
|
// src/lib/notifications.ts
|
|
13471
13480
|
import fs45 from "fs";
|
|
13472
13481
|
import path36 from "path";
|
|
13473
|
-
import
|
|
13482
|
+
import chalk21 from "chalk";
|
|
13474
13483
|
function notificationFilePath() {
|
|
13475
13484
|
return path36.join(getLearningDir(), "last-finalize-summary.json");
|
|
13476
13485
|
}
|
|
@@ -13490,13 +13499,13 @@ function checkPendingNotifications() {
|
|
|
13490
13499
|
if (!summary.newItemCount || summary.newItemCount === 0) return;
|
|
13491
13500
|
const wasteLabel = summary.wasteTokens > 0 ? ` (~${summary.wasteTokens.toLocaleString()} wasted tokens captured)` : "";
|
|
13492
13501
|
console.log(
|
|
13493
|
-
|
|
13502
|
+
chalk21.dim(`caliber: learned ${summary.newItemCount} new pattern${summary.newItemCount === 1 ? "" : "s"} from your last session${wasteLabel}`)
|
|
13494
13503
|
);
|
|
13495
13504
|
for (const item of summary.newItems.slice(0, 3)) {
|
|
13496
|
-
console.log(
|
|
13505
|
+
console.log(chalk21.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
|
|
13497
13506
|
}
|
|
13498
13507
|
if (summary.newItems.length > 3) {
|
|
13499
|
-
console.log(
|
|
13508
|
+
console.log(chalk21.dim(` ... and ${summary.newItems.length - 3} more`));
|
|
13500
13509
|
}
|
|
13501
13510
|
console.log("");
|
|
13502
13511
|
} catch {
|
|
@@ -13975,10 +13984,26 @@ async function learnObserveCommand(options) {
|
|
|
13975
13984
|
const logFd = fs47.openSync(logPath, "a");
|
|
13976
13985
|
const NPX_SUFFIX = " --yes @rely-ai/caliber";
|
|
13977
13986
|
const [exe, binArgs] = isNpxResolution2() ? [bin.slice(0, -NPX_SUFFIX.length) || "npx", ["--yes", "@rely-ai/caliber"]] : [bin, []];
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13987
|
+
const isWin = process.platform === "win32";
|
|
13988
|
+
const spawnExe = isWin ? `"${exe}"` : exe;
|
|
13989
|
+
const child = spawn5(
|
|
13990
|
+
spawnExe,
|
|
13991
|
+
[...binArgs, "learn", "finalize", "--auto", "--incremental"],
|
|
13992
|
+
{
|
|
13993
|
+
detached: true,
|
|
13994
|
+
stdio: ["ignore", logFd, logFd],
|
|
13995
|
+
...isWin && { shell: true }
|
|
13996
|
+
}
|
|
13997
|
+
);
|
|
13998
|
+
child.on("error", () => {
|
|
13999
|
+
try {
|
|
14000
|
+
const s = readState2();
|
|
14001
|
+
s.lastAnalysisEventCount = s.eventCount;
|
|
14002
|
+
writeState2(s);
|
|
14003
|
+
} catch {
|
|
14004
|
+
}
|
|
14005
|
+
});
|
|
14006
|
+
child.unref();
|
|
13982
14007
|
fs47.closeSync(logFd);
|
|
13983
14008
|
} catch {
|
|
13984
14009
|
}
|
|
@@ -13993,7 +14018,7 @@ async function learnFinalizeCommand(options) {
|
|
|
13993
14018
|
const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
|
|
13994
14019
|
if (isCaliberRunning2()) {
|
|
13995
14020
|
if (!isAuto)
|
|
13996
|
-
console.log(
|
|
14021
|
+
console.log(chalk22.dim("caliber: skipping finalize \u2014 another caliber process is running"));
|
|
13997
14022
|
return;
|
|
13998
14023
|
}
|
|
13999
14024
|
}
|
|
@@ -14002,7 +14027,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14002
14027
|
}
|
|
14003
14028
|
if (!acquireFinalizeLock()) {
|
|
14004
14029
|
if (!isAuto)
|
|
14005
|
-
console.log(
|
|
14030
|
+
console.log(chalk22.dim("caliber: skipping finalize \u2014 another finalize is in progress"));
|
|
14006
14031
|
return;
|
|
14007
14032
|
}
|
|
14008
14033
|
let analyzed = false;
|
|
@@ -14011,7 +14036,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14011
14036
|
if (!config) {
|
|
14012
14037
|
if (isAuto) return;
|
|
14013
14038
|
console.log(
|
|
14014
|
-
|
|
14039
|
+
chalk22.yellow(
|
|
14015
14040
|
`caliber: no LLM provider configured \u2014 run \`${resolveCaliber()} config\` first`
|
|
14016
14041
|
)
|
|
14017
14042
|
);
|
|
@@ -14024,7 +14049,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14024
14049
|
if (allEvents.length < threshold) {
|
|
14025
14050
|
if (!isAuto)
|
|
14026
14051
|
console.log(
|
|
14027
|
-
|
|
14052
|
+
chalk22.dim(
|
|
14028
14053
|
`caliber: ${allEvents.length}/${threshold} events recorded \u2014 need more before analysis`
|
|
14029
14054
|
)
|
|
14030
14055
|
);
|
|
@@ -14038,7 +14063,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14038
14063
|
if (events.length < threshold) {
|
|
14039
14064
|
if (!isAuto)
|
|
14040
14065
|
console.log(
|
|
14041
|
-
|
|
14066
|
+
chalk22.dim(
|
|
14042
14067
|
`caliber: ${events.length}/${threshold} new events since last analysis \u2014 need more`
|
|
14043
14068
|
)
|
|
14044
14069
|
);
|
|
@@ -14078,12 +14103,12 @@ async function learnFinalizeCommand(options) {
|
|
|
14078
14103
|
} else {
|
|
14079
14104
|
const wasteLabel = waste.totalWasteTokens > 0 ? ` (~${waste.totalWasteTokens.toLocaleString()} wasted tokens captured)` : "";
|
|
14080
14105
|
console.log(
|
|
14081
|
-
|
|
14106
|
+
chalk22.dim(
|
|
14082
14107
|
`caliber: learned ${result.newItemCount} new pattern${result.newItemCount === 1 ? "" : "s"}${wasteLabel}`
|
|
14083
14108
|
)
|
|
14084
14109
|
);
|
|
14085
14110
|
for (const item of result.newItems) {
|
|
14086
|
-
console.log(
|
|
14111
|
+
console.log(chalk22.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
|
|
14087
14112
|
}
|
|
14088
14113
|
}
|
|
14089
14114
|
const wastePerLearning = Math.round(waste.totalWasteTokens / result.newItemCount);
|
|
@@ -14177,7 +14202,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14177
14202
|
const staleLearnings = findStaleLearnings(roiStats);
|
|
14178
14203
|
if (staleLearnings.length > 0 && !isAuto) {
|
|
14179
14204
|
console.log(
|
|
14180
|
-
|
|
14205
|
+
chalk22.yellow(
|
|
14181
14206
|
`caliber: ${staleLearnings.length} learning${staleLearnings.length === 1 ? "" : "s"} never activated \u2014 run \`${resolveCaliber()} learn list --verbose\` to review`
|
|
14182
14207
|
)
|
|
14183
14208
|
);
|
|
@@ -14186,7 +14211,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14186
14211
|
if (!isAuto && t.estimatedSavingsTokens > 0) {
|
|
14187
14212
|
const totalLearnings = existingLearnedItems + newLearningsProduced;
|
|
14188
14213
|
console.log(
|
|
14189
|
-
|
|
14214
|
+
chalk22.dim(
|
|
14190
14215
|
`caliber: ${totalLearnings} learnings active \u2014 est. ~${t.estimatedSavingsTokens.toLocaleString()} tokens saved across ${t.totalSessionsWithLearnings} sessions`
|
|
14191
14216
|
)
|
|
14192
14217
|
);
|
|
@@ -14194,7 +14219,7 @@ async function learnFinalizeCommand(options) {
|
|
|
14194
14219
|
} catch (err) {
|
|
14195
14220
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
14196
14221
|
if (options?.force && !isAuto) {
|
|
14197
|
-
console.error(
|
|
14222
|
+
console.error(chalk22.red("caliber: finalize failed \u2014"), errorMsg);
|
|
14198
14223
|
}
|
|
14199
14224
|
writeFinalizeError(errorMsg);
|
|
14200
14225
|
} finally {
|
|
@@ -14217,51 +14242,51 @@ async function learnInstallCommand() {
|
|
|
14217
14242
|
if (fs47.existsSync(".claude")) {
|
|
14218
14243
|
const r = installLearningHooks();
|
|
14219
14244
|
if (r.installed) {
|
|
14220
|
-
console.log(
|
|
14245
|
+
console.log(chalk22.green("\u2713") + " Claude Code learning hooks installed");
|
|
14221
14246
|
anyInstalled = true;
|
|
14222
14247
|
} else if (r.alreadyInstalled) {
|
|
14223
|
-
console.log(
|
|
14248
|
+
console.log(chalk22.dim(" Claude Code hooks already installed"));
|
|
14224
14249
|
}
|
|
14225
14250
|
}
|
|
14226
14251
|
if (fs47.existsSync(".cursor")) {
|
|
14227
14252
|
const r = installCursorLearningHooks();
|
|
14228
14253
|
if (r.installed) {
|
|
14229
|
-
console.log(
|
|
14254
|
+
console.log(chalk22.green("\u2713") + " Cursor learning hooks installed");
|
|
14230
14255
|
anyInstalled = true;
|
|
14231
14256
|
} else if (r.alreadyInstalled) {
|
|
14232
|
-
console.log(
|
|
14257
|
+
console.log(chalk22.dim(" Cursor hooks already installed"));
|
|
14233
14258
|
}
|
|
14234
14259
|
}
|
|
14235
14260
|
if (!fs47.existsSync(".claude") && !fs47.existsSync(".cursor")) {
|
|
14236
|
-
console.log(
|
|
14261
|
+
console.log(chalk22.yellow("No .claude/ or .cursor/ directory found."));
|
|
14237
14262
|
console.log(
|
|
14238
|
-
|
|
14263
|
+
chalk22.dim(` Run \`${resolveCaliber()} init\` first, or create the directory manually.`)
|
|
14239
14264
|
);
|
|
14240
14265
|
return;
|
|
14241
14266
|
}
|
|
14242
14267
|
if (anyInstalled) {
|
|
14243
14268
|
console.log(
|
|
14244
|
-
|
|
14269
|
+
chalk22.dim(
|
|
14245
14270
|
` Tool usage will be recorded and learnings extracted after \u2265${MIN_EVENTS_FOR_ANALYSIS} events.`
|
|
14246
14271
|
)
|
|
14247
14272
|
);
|
|
14248
|
-
console.log(
|
|
14273
|
+
console.log(chalk22.dim(" Learnings written to CALIBER_LEARNINGS.md."));
|
|
14249
14274
|
}
|
|
14250
14275
|
}
|
|
14251
14276
|
async function learnRemoveCommand() {
|
|
14252
14277
|
let anyRemoved = false;
|
|
14253
14278
|
const r1 = removeLearningHooks();
|
|
14254
14279
|
if (r1.removed) {
|
|
14255
|
-
console.log(
|
|
14280
|
+
console.log(chalk22.green("\u2713") + " Claude Code learning hooks removed");
|
|
14256
14281
|
anyRemoved = true;
|
|
14257
14282
|
}
|
|
14258
14283
|
const r2 = removeCursorLearningHooks();
|
|
14259
14284
|
if (r2.removed) {
|
|
14260
|
-
console.log(
|
|
14285
|
+
console.log(chalk22.green("\u2713") + " Cursor learning hooks removed");
|
|
14261
14286
|
anyRemoved = true;
|
|
14262
14287
|
}
|
|
14263
14288
|
if (!anyRemoved) {
|
|
14264
|
-
console.log(
|
|
14289
|
+
console.log(chalk22.dim("No learning hooks found."));
|
|
14265
14290
|
}
|
|
14266
14291
|
}
|
|
14267
14292
|
async function learnStatusCommand() {
|
|
@@ -14269,51 +14294,51 @@ async function learnStatusCommand() {
|
|
|
14269
14294
|
const cursorInstalled = areCursorLearningHooksInstalled();
|
|
14270
14295
|
const state = readState2();
|
|
14271
14296
|
const eventCount = getEventCount();
|
|
14272
|
-
console.log(
|
|
14297
|
+
console.log(chalk22.bold("Session Learning Status"));
|
|
14273
14298
|
console.log();
|
|
14274
14299
|
if (claudeInstalled) {
|
|
14275
|
-
console.log(
|
|
14300
|
+
console.log(chalk22.green("\u2713") + " Claude Code hooks " + chalk22.green("installed"));
|
|
14276
14301
|
} else {
|
|
14277
|
-
console.log(
|
|
14302
|
+
console.log(chalk22.dim("\u2717") + " Claude Code hooks " + chalk22.dim("not installed"));
|
|
14278
14303
|
}
|
|
14279
14304
|
if (cursorInstalled) {
|
|
14280
|
-
console.log(
|
|
14305
|
+
console.log(chalk22.green("\u2713") + " Cursor hooks " + chalk22.green("installed"));
|
|
14281
14306
|
} else {
|
|
14282
|
-
console.log(
|
|
14307
|
+
console.log(chalk22.dim("\u2717") + " Cursor hooks " + chalk22.dim("not installed"));
|
|
14283
14308
|
}
|
|
14284
14309
|
if (!claudeInstalled && !cursorInstalled) {
|
|
14285
14310
|
console.log(
|
|
14286
|
-
|
|
14311
|
+
chalk22.dim(` Run \`${resolveCaliber()} learn install\` to enable session learning.`)
|
|
14287
14312
|
);
|
|
14288
14313
|
}
|
|
14289
14314
|
console.log();
|
|
14290
|
-
console.log(`Events recorded: ${
|
|
14291
|
-
console.log(`Threshold for analysis: ${
|
|
14315
|
+
console.log(`Events recorded: ${chalk22.cyan(String(eventCount))}`);
|
|
14316
|
+
console.log(`Threshold for analysis: ${chalk22.cyan(String(MIN_EVENTS_FOR_ANALYSIS))}`);
|
|
14292
14317
|
if (state.lastAnalysisTimestamp) {
|
|
14293
|
-
console.log(`Last analysis: ${
|
|
14318
|
+
console.log(`Last analysis: ${chalk22.cyan(state.lastAnalysisTimestamp)}`);
|
|
14294
14319
|
} else {
|
|
14295
|
-
console.log(`Last analysis: ${
|
|
14320
|
+
console.log(`Last analysis: ${chalk22.dim("none")}`);
|
|
14296
14321
|
}
|
|
14297
14322
|
const lastError = readFinalizeError();
|
|
14298
14323
|
if (lastError) {
|
|
14299
|
-
console.log(`Last error: ${
|
|
14300
|
-
console.log(
|
|
14324
|
+
console.log(`Last error: ${chalk22.red(lastError.error)}`);
|
|
14325
|
+
console.log(chalk22.dim(` at ${lastError.timestamp}`));
|
|
14301
14326
|
const logPath = path38.join(getLearningDir(), LEARNING_FINALIZE_LOG);
|
|
14302
14327
|
if (fs47.existsSync(logPath)) {
|
|
14303
|
-
console.log(
|
|
14328
|
+
console.log(chalk22.dim(` Full log: ${logPath}`));
|
|
14304
14329
|
}
|
|
14305
14330
|
}
|
|
14306
14331
|
const learnedSection = readLearnedSection();
|
|
14307
14332
|
if (learnedSection) {
|
|
14308
14333
|
const lineCount = learnedSection.split("\n").filter(Boolean).length;
|
|
14309
14334
|
console.log(`
|
|
14310
|
-
Learned items in CALIBER_LEARNINGS.md: ${
|
|
14335
|
+
Learned items in CALIBER_LEARNINGS.md: ${chalk22.cyan(String(lineCount))}`);
|
|
14311
14336
|
}
|
|
14312
14337
|
const roiStats = readROIStats();
|
|
14313
14338
|
const roiSummary = formatROISummary(roiStats);
|
|
14314
14339
|
if (roiSummary) {
|
|
14315
14340
|
console.log();
|
|
14316
|
-
console.log(
|
|
14341
|
+
console.log(chalk22.bold(roiSummary.split("\n")[0]));
|
|
14317
14342
|
for (const line of roiSummary.split("\n").slice(1)) {
|
|
14318
14343
|
console.log(line);
|
|
14319
14344
|
}
|
|
@@ -14339,26 +14364,26 @@ function getAllLearnings() {
|
|
|
14339
14364
|
async function learnListCommand(options) {
|
|
14340
14365
|
const items = getAllLearnings();
|
|
14341
14366
|
if (items.length === 0) {
|
|
14342
|
-
console.log(
|
|
14367
|
+
console.log(chalk22.dim(`No learnings yet. Run \`${resolveCaliber()} learn install\` to start.`));
|
|
14343
14368
|
return;
|
|
14344
14369
|
}
|
|
14345
14370
|
const roiStats = options?.verbose ? readROIStats() : null;
|
|
14346
|
-
console.log(
|
|
14371
|
+
console.log(chalk22.bold(`
|
|
14347
14372
|
Learnings (${items.length})
|
|
14348
14373
|
`));
|
|
14349
14374
|
for (const item of items) {
|
|
14350
|
-
const tag = item.source === "personal" ?
|
|
14375
|
+
const tag = item.source === "personal" ? chalk22.magenta("[personal]") : chalk22.blue("[project]");
|
|
14351
14376
|
const display = item.text.replace(/^- /, "").slice(0, 100);
|
|
14352
|
-
console.log(` ${
|
|
14377
|
+
console.log(` ${chalk22.dim(String(item.index + 1).padStart(2, " "))}. ${tag} ${display}`);
|
|
14353
14378
|
if (options?.verbose && roiStats) {
|
|
14354
14379
|
const match = roiStats.learnings.find((l) => display.includes(l.summary.slice(0, 40)));
|
|
14355
14380
|
if (match) {
|
|
14356
14381
|
const activations = match.activationCount ?? 0;
|
|
14357
14382
|
const stale = activations === 0 && roiStats.sessions.length >= 10;
|
|
14358
|
-
const activationLabel = stale ?
|
|
14383
|
+
const activationLabel = stale ? chalk22.yellow(`${activations} activations [stale]`) : chalk22.dim(`${activations} activation${activations === 1 ? "" : "s"}`);
|
|
14359
14384
|
console.log(` ${activationLabel}`);
|
|
14360
14385
|
if (match.explanation) {
|
|
14361
|
-
console.log(` ${
|
|
14386
|
+
console.log(` ${chalk22.dim("Why: " + match.explanation.slice(0, 80))}`);
|
|
14362
14387
|
}
|
|
14363
14388
|
}
|
|
14364
14389
|
}
|
|
@@ -14369,7 +14394,7 @@ async function learnDeleteCommand(indexStr) {
|
|
|
14369
14394
|
const index = parseInt(indexStr, 10);
|
|
14370
14395
|
if (isNaN(index) || index < 1) {
|
|
14371
14396
|
console.log(
|
|
14372
|
-
|
|
14397
|
+
chalk22.red(
|
|
14373
14398
|
`Invalid index: "${indexStr}". Use a number from \`${resolveCaliber()} learn list\`.`
|
|
14374
14399
|
)
|
|
14375
14400
|
);
|
|
@@ -14378,13 +14403,13 @@ async function learnDeleteCommand(indexStr) {
|
|
|
14378
14403
|
const items = getAllLearnings();
|
|
14379
14404
|
const targetIdx = index - 1;
|
|
14380
14405
|
if (targetIdx >= items.length) {
|
|
14381
|
-
console.log(
|
|
14406
|
+
console.log(chalk22.red(`Index ${index} is out of range. You have ${items.length} learnings.`));
|
|
14382
14407
|
return;
|
|
14383
14408
|
}
|
|
14384
14409
|
const item = items[targetIdx];
|
|
14385
14410
|
const filePath = item.source === "personal" ? PERSONAL_LEARNINGS_FILE : "CALIBER_LEARNINGS.md";
|
|
14386
14411
|
if (!fs47.existsSync(filePath)) {
|
|
14387
|
-
console.log(
|
|
14412
|
+
console.log(chalk22.red("Learnings file not found."));
|
|
14388
14413
|
return;
|
|
14389
14414
|
}
|
|
14390
14415
|
const content = fs47.readFileSync(filePath, "utf-8");
|
|
@@ -14403,7 +14428,7 @@ async function learnDeleteCommand(indexStr) {
|
|
|
14403
14428
|
}
|
|
14404
14429
|
}
|
|
14405
14430
|
if (lineToRemove === -1) {
|
|
14406
|
-
console.log(
|
|
14431
|
+
console.log(chalk22.red("Could not locate learning in file."));
|
|
14407
14432
|
return;
|
|
14408
14433
|
}
|
|
14409
14434
|
const bulletToRemove = lines[lineToRemove];
|
|
@@ -14419,24 +14444,24 @@ async function learnDeleteCommand(indexStr) {
|
|
|
14419
14444
|
roiStats.learnings.splice(roiIdx, 1);
|
|
14420
14445
|
writeROIStats(roiStats);
|
|
14421
14446
|
}
|
|
14422
|
-
console.log(
|
|
14447
|
+
console.log(chalk22.green("\u2713") + ` Removed: ${bulletToRemove.replace(/^- /, "").slice(0, 80)}`);
|
|
14423
14448
|
}
|
|
14424
14449
|
async function learnAddCommand(content, options) {
|
|
14425
14450
|
if (!content.trim()) {
|
|
14426
|
-
console.log(
|
|
14451
|
+
console.log(chalk22.yellow("Please provide learning content."));
|
|
14427
14452
|
throw new Error("__exit__");
|
|
14428
14453
|
}
|
|
14429
14454
|
const scope = options.personal ? "personal" : "project";
|
|
14430
14455
|
const result = addLearning(content.trim(), scope);
|
|
14431
14456
|
if (result.added) {
|
|
14432
|
-
console.log(
|
|
14457
|
+
console.log(chalk22.green("\u2713") + ` Learning saved to ${result.file}`);
|
|
14433
14458
|
} else {
|
|
14434
|
-
console.log(
|
|
14459
|
+
console.log(chalk22.dim(" Similar learning already exists \u2014 skipped."));
|
|
14435
14460
|
}
|
|
14436
14461
|
}
|
|
14437
14462
|
|
|
14438
14463
|
// src/commands/insights.ts
|
|
14439
|
-
import
|
|
14464
|
+
import chalk23 from "chalk";
|
|
14440
14465
|
init_resolve_caliber();
|
|
14441
14466
|
var MIN_SESSIONS_FULL = 20;
|
|
14442
14467
|
function buildInsightsData(stats) {
|
|
@@ -14477,85 +14502,85 @@ function buildInsightsData(stats) {
|
|
|
14477
14502
|
};
|
|
14478
14503
|
}
|
|
14479
14504
|
function displayColdStart(score) {
|
|
14480
|
-
console.log(
|
|
14505
|
+
console.log(chalk23.bold("\n Agent Insights\n"));
|
|
14481
14506
|
const hooksInstalled = areLearningHooksInstalled() || areCursorLearningHooksInstalled();
|
|
14482
14507
|
if (!hooksInstalled) {
|
|
14483
|
-
console.log(
|
|
14484
|
-
console.log(
|
|
14485
|
-
console.log(
|
|
14486
|
-
console.log(
|
|
14508
|
+
console.log(chalk23.yellow(" Learning hooks not installed."));
|
|
14509
|
+
console.log(chalk23.dim(" Session learning captures patterns from your AI coding sessions \u2014 what"));
|
|
14510
|
+
console.log(chalk23.dim(" fails, what works, corrections you make \u2014 so your agents improve over time.\n"));
|
|
14511
|
+
console.log(chalk23.dim(" Run ") + chalk23.cyan(`${resolveCaliber()} learn install`) + chalk23.dim(" to enable."));
|
|
14487
14512
|
} else {
|
|
14488
|
-
console.log(
|
|
14489
|
-
console.log(
|
|
14490
|
-
console.log(
|
|
14513
|
+
console.log(chalk23.dim(" Learning hooks are active. Use your AI agent and insights"));
|
|
14514
|
+
console.log(chalk23.dim(" will appear automatically after each session.\n"));
|
|
14515
|
+
console.log(chalk23.dim(` Progress: 0/${MIN_SESSIONS_FULL} sessions \u2014 full insights unlock at ${MIN_SESSIONS_FULL}`));
|
|
14491
14516
|
}
|
|
14492
|
-
console.log(
|
|
14517
|
+
console.log(chalk23.dim(`
|
|
14493
14518
|
Config score: ${score.score}/100 (${score.grade})`));
|
|
14494
14519
|
console.log("");
|
|
14495
14520
|
}
|
|
14496
14521
|
function displayEarlyData(data, score) {
|
|
14497
|
-
console.log(
|
|
14522
|
+
console.log(chalk23.bold("\n Agent Insights") + chalk23.yellow(" (early data)\n"));
|
|
14498
14523
|
const remaining = MIN_SESSIONS_FULL - data.totalSessions;
|
|
14499
|
-
console.log(
|
|
14524
|
+
console.log(chalk23.dim(` ${data.totalSessions}/${MIN_SESSIONS_FULL} sessions tracked \u2014 ${remaining} more for full insights.
|
|
14500
14525
|
`));
|
|
14501
|
-
console.log(` Sessions tracked: ${
|
|
14502
|
-
console.log(` Learnings accumulated: ${
|
|
14526
|
+
console.log(` Sessions tracked: ${chalk23.cyan(String(data.totalSessions))}`);
|
|
14527
|
+
console.log(` Learnings accumulated: ${chalk23.cyan(String(data.learningCount))}`);
|
|
14503
14528
|
if (data.totalWasteTokens > 0) {
|
|
14504
|
-
console.log(` Waste captured: ${
|
|
14529
|
+
console.log(` Waste captured: ${chalk23.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
|
|
14505
14530
|
}
|
|
14506
14531
|
if (data.failureRateImprovement !== null && data.failureRateImprovement > 0) {
|
|
14507
|
-
console.log(` Failure rate trend: ${
|
|
14532
|
+
console.log(` Failure rate trend: ${chalk23.green(`${data.failureRateImprovement}% fewer`)} failures with learnings ${chalk23.dim("(early signal)")}`);
|
|
14508
14533
|
} else if (data.totalSessions > 0 && data.failureRateImprovement === null) {
|
|
14509
|
-
console.log(` Failure rate trend: ${
|
|
14534
|
+
console.log(` Failure rate trend: ${chalk23.dim("collecting data (need 3+ sessions in each group)")}`);
|
|
14510
14535
|
}
|
|
14511
14536
|
if (data.taskSuccessRate !== null) {
|
|
14512
|
-
console.log(` Task success rate: ${
|
|
14537
|
+
console.log(` Task success rate: ${chalk23.cyan(`${data.taskSuccessRate}%`)} ${chalk23.dim(`(${data.taskCount} tasks)`)}`);
|
|
14513
14538
|
}
|
|
14514
|
-
console.log(` Config score: ${
|
|
14539
|
+
console.log(` Config score: ${chalk23.cyan(`${score.score}/100`)} (${score.grade})`);
|
|
14515
14540
|
console.log("");
|
|
14516
14541
|
}
|
|
14517
14542
|
function displayFullInsights(data, score) {
|
|
14518
|
-
console.log(
|
|
14519
|
-
console.log(
|
|
14543
|
+
console.log(chalk23.bold("\n Agent Insights\n"));
|
|
14544
|
+
console.log(chalk23.bold(" Agent Health"));
|
|
14520
14545
|
if (data.taskSuccessRate !== null) {
|
|
14521
|
-
const color = data.taskSuccessRate >= 80 ?
|
|
14546
|
+
const color = data.taskSuccessRate >= 80 ? chalk23.green : data.taskSuccessRate >= 60 ? chalk23.yellow : chalk23.red;
|
|
14522
14547
|
console.log(` Task success rate: ${color(`${data.taskSuccessRate}%`)} across ${data.taskCount} tasks`);
|
|
14523
14548
|
if (data.taskCorrectionCount > 0) {
|
|
14524
|
-
console.log(` Corrections needed: ${
|
|
14549
|
+
console.log(` Corrections needed: ${chalk23.yellow(String(data.taskCorrectionCount))} tasks required user correction`);
|
|
14525
14550
|
}
|
|
14526
14551
|
}
|
|
14527
|
-
console.log(` Sessions tracked: ${
|
|
14528
|
-
console.log(
|
|
14529
|
-
console.log(` Learnings active: ${
|
|
14552
|
+
console.log(` Sessions tracked: ${chalk23.cyan(String(data.totalSessions))}`);
|
|
14553
|
+
console.log(chalk23.bold("\n Learning Impact"));
|
|
14554
|
+
console.log(` Learnings active: ${chalk23.cyan(String(data.learningCount))}`);
|
|
14530
14555
|
if (data.failureRateWith !== null && data.failureRateWithout !== null) {
|
|
14531
|
-
console.log(` Failure rate: ${
|
|
14556
|
+
console.log(` Failure rate: ${chalk23.red(data.failureRateWithout.toFixed(1))}/session ${chalk23.dim("\u2192")} ${chalk23.green(data.failureRateWith.toFixed(1))}/session with learnings`);
|
|
14532
14557
|
if (data.failureRateImprovement !== null && data.failureRateImprovement > 0) {
|
|
14533
|
-
console.log(` Improvement: ${
|
|
14558
|
+
console.log(` Improvement: ${chalk23.green(`${data.failureRateImprovement}%`)} fewer failures`);
|
|
14534
14559
|
} else if (data.failureRateImprovement === null) {
|
|
14535
|
-
console.log(` Improvement: ${
|
|
14560
|
+
console.log(` Improvement: ${chalk23.dim("collecting data (need 3+ sessions in each group)")}`);
|
|
14536
14561
|
}
|
|
14537
14562
|
}
|
|
14538
14563
|
if (data.totalWasteTokens > 0 || data.estimatedSavingsTokens > 0) {
|
|
14539
|
-
console.log(
|
|
14564
|
+
console.log(chalk23.bold("\n Efficiency"));
|
|
14540
14565
|
if (data.totalWasteTokens > 0) {
|
|
14541
|
-
console.log(` Waste captured: ${
|
|
14566
|
+
console.log(` Waste captured: ${chalk23.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
|
|
14542
14567
|
}
|
|
14543
14568
|
if (data.estimatedSavingsTokens > 0) {
|
|
14544
|
-
console.log(` Estimated savings: ~${
|
|
14569
|
+
console.log(` Estimated savings: ~${chalk23.green(data.estimatedSavingsTokens.toLocaleString())} tokens`);
|
|
14545
14570
|
}
|
|
14546
14571
|
if (data.estimatedSavingsSeconds > 0) {
|
|
14547
|
-
console.log(` Time saved: ~${
|
|
14572
|
+
console.log(` Time saved: ~${chalk23.green(formatDuration(data.estimatedSavingsSeconds))}`);
|
|
14548
14573
|
}
|
|
14549
14574
|
}
|
|
14550
|
-
console.log(
|
|
14551
|
-
console.log(` Score: ${
|
|
14575
|
+
console.log(chalk23.bold("\n Config Quality"));
|
|
14576
|
+
console.log(` Score: ${chalk23.cyan(`${score.score}/100`)} (${score.grade})`);
|
|
14552
14577
|
const history = readScoreHistory();
|
|
14553
14578
|
const trend = getScoreTrend(history);
|
|
14554
14579
|
if (trend) {
|
|
14555
|
-
const trendColor = trend.direction === "up" ?
|
|
14580
|
+
const trendColor = trend.direction === "up" ? chalk23.green : trend.direction === "down" ? chalk23.red : chalk23.gray;
|
|
14556
14581
|
const arrow = trend.direction === "up" ? "\u2191" : trend.direction === "down" ? "\u2193" : "\u2192";
|
|
14557
14582
|
const sign = trend.delta > 0 ? "+" : "";
|
|
14558
|
-
console.log(` Trend: ${trendColor(`${arrow} ${sign}${trend.delta} pts`)} ${
|
|
14583
|
+
console.log(` Trend: ${trendColor(`${arrow} ${sign}${trend.delta} pts`)} ${chalk23.dim(`over ${trend.entries} checks`)}`);
|
|
14559
14584
|
}
|
|
14560
14585
|
console.log("");
|
|
14561
14586
|
}
|
|
@@ -14585,36 +14610,36 @@ async function insightsCommand(options) {
|
|
|
14585
14610
|
// src/commands/sources.ts
|
|
14586
14611
|
import fs48 from "fs";
|
|
14587
14612
|
import path39 from "path";
|
|
14588
|
-
import
|
|
14613
|
+
import chalk24 from "chalk";
|
|
14589
14614
|
init_resolve_caliber();
|
|
14590
14615
|
async function sourcesListCommand() {
|
|
14591
14616
|
const dir = process.cwd();
|
|
14592
14617
|
const configSources = loadSourcesConfig(dir);
|
|
14593
14618
|
const workspaces = getDetectedWorkspaces(dir);
|
|
14594
14619
|
if (configSources.length === 0 && workspaces.length === 0) {
|
|
14595
|
-
console.log(
|
|
14596
|
-
console.log(
|
|
14597
|
-
console.log(
|
|
14620
|
+
console.log(chalk24.dim("\n No sources configured.\n"));
|
|
14621
|
+
console.log(chalk24.dim(" Add a source: ") + chalk24.hex("#83D1EB")(`${resolveCaliber()} sources add <path>`));
|
|
14622
|
+
console.log(chalk24.dim(" Or add to .caliber/sources.json manually.\n"));
|
|
14598
14623
|
return;
|
|
14599
14624
|
}
|
|
14600
|
-
console.log(
|
|
14625
|
+
console.log(chalk24.bold("\n External Sources\n"));
|
|
14601
14626
|
if (configSources.length > 0) {
|
|
14602
14627
|
for (const source of configSources) {
|
|
14603
14628
|
const sourcePath = source.path || source.url || "";
|
|
14604
14629
|
const exists = source.path ? fs48.existsSync(path39.resolve(dir, source.path)) : false;
|
|
14605
|
-
const status = exists ?
|
|
14630
|
+
const status = exists ? chalk24.green("reachable") : chalk24.red("not found");
|
|
14606
14631
|
const hasSummary = source.path && fs48.existsSync(path39.join(path39.resolve(dir, source.path), ".caliber", "summary.json"));
|
|
14607
|
-
console.log(` ${
|
|
14608
|
-
console.log(` Type: ${source.type} Status: ${status}${hasSummary ? " " +
|
|
14609
|
-
if (source.description) console.log(` ${
|
|
14632
|
+
console.log(` ${chalk24.bold(source.role || source.type)} ${chalk24.dim(sourcePath)}`);
|
|
14633
|
+
console.log(` Type: ${source.type} Status: ${status}${hasSummary ? " " + chalk24.cyan("has summary.json") : ""}`);
|
|
14634
|
+
if (source.description) console.log(` ${chalk24.dim(source.description)}`);
|
|
14610
14635
|
console.log("");
|
|
14611
14636
|
}
|
|
14612
14637
|
}
|
|
14613
14638
|
if (workspaces.length > 0) {
|
|
14614
|
-
console.log(
|
|
14639
|
+
console.log(chalk24.dim(" Auto-detected workspaces:"));
|
|
14615
14640
|
for (const ws of workspaces) {
|
|
14616
14641
|
const exists = fs48.existsSync(path39.resolve(dir, ws));
|
|
14617
|
-
console.log(` ${exists ?
|
|
14642
|
+
console.log(` ${exists ? chalk24.green("\u25CF") : chalk24.red("\u25CF")} ${ws}`);
|
|
14618
14643
|
}
|
|
14619
14644
|
console.log("");
|
|
14620
14645
|
}
|
|
@@ -14623,14 +14648,14 @@ async function sourcesAddCommand(sourcePath) {
|
|
|
14623
14648
|
const dir = process.cwd();
|
|
14624
14649
|
const absPath = path39.resolve(dir, sourcePath);
|
|
14625
14650
|
if (!fs48.existsSync(absPath)) {
|
|
14626
|
-
console.log(
|
|
14651
|
+
console.log(chalk24.red(`
|
|
14627
14652
|
Path not found: ${sourcePath}
|
|
14628
14653
|
`));
|
|
14629
14654
|
throw new Error("__exit__");
|
|
14630
14655
|
}
|
|
14631
14656
|
const type = detectSourceType(absPath);
|
|
14632
14657
|
if (isInsideDir(absPath, dir)) {
|
|
14633
|
-
console.log(
|
|
14658
|
+
console.log(chalk24.red(`
|
|
14634
14659
|
Cannot add a path inside the current project as a source.
|
|
14635
14660
|
`));
|
|
14636
14661
|
throw new Error("__exit__");
|
|
@@ -14640,7 +14665,7 @@ async function sourcesAddCommand(sourcePath) {
|
|
|
14640
14665
|
(s) => s.path && path39.resolve(dir, s.path) === absPath
|
|
14641
14666
|
);
|
|
14642
14667
|
if (alreadyConfigured) {
|
|
14643
|
-
console.log(
|
|
14668
|
+
console.log(chalk24.yellow(`
|
|
14644
14669
|
Already configured: ${sourcePath}
|
|
14645
14670
|
`));
|
|
14646
14671
|
return;
|
|
@@ -14657,7 +14682,7 @@ async function sourcesAddCommand(sourcePath) {
|
|
|
14657
14682
|
};
|
|
14658
14683
|
existing.push(newSource);
|
|
14659
14684
|
writeSourcesConfig(dir, existing);
|
|
14660
|
-
console.log(
|
|
14685
|
+
console.log(chalk24.green(`
|
|
14661
14686
|
\u2713 Added ${sourcePath} as ${type} source (${role})
|
|
14662
14687
|
`));
|
|
14663
14688
|
}
|
|
@@ -14668,18 +14693,18 @@ async function sourcesRemoveCommand(name) {
|
|
|
14668
14693
|
(s) => s.path?.includes(name) || s.role === name
|
|
14669
14694
|
);
|
|
14670
14695
|
if (idx === -1) {
|
|
14671
|
-
console.log(
|
|
14696
|
+
console.log(chalk24.red(`
|
|
14672
14697
|
Source not found: ${name}
|
|
14673
14698
|
`));
|
|
14674
|
-
console.log(
|
|
14699
|
+
console.log(chalk24.dim(" Available sources:"));
|
|
14675
14700
|
for (const s of existing) {
|
|
14676
|
-
console.log(
|
|
14701
|
+
console.log(chalk24.dim(` ${s.path || s.url} (${s.role || s.type})`));
|
|
14677
14702
|
}
|
|
14678
14703
|
throw new Error("__exit__");
|
|
14679
14704
|
}
|
|
14680
14705
|
const removed = existing.splice(idx, 1)[0];
|
|
14681
14706
|
writeSourcesConfig(dir, existing);
|
|
14682
|
-
console.log(
|
|
14707
|
+
console.log(chalk24.green(`
|
|
14683
14708
|
\u2713 Removed ${removed.path || removed.url} (${removed.role || removed.type})
|
|
14684
14709
|
`));
|
|
14685
14710
|
}
|
|
@@ -14687,7 +14712,7 @@ async function sourcesRemoveCommand(name) {
|
|
|
14687
14712
|
// src/commands/publish.ts
|
|
14688
14713
|
import fs49 from "fs";
|
|
14689
14714
|
import path40 from "path";
|
|
14690
|
-
import
|
|
14715
|
+
import chalk25 from "chalk";
|
|
14691
14716
|
import ora7 from "ora";
|
|
14692
14717
|
init_config();
|
|
14693
14718
|
init_resolve_caliber();
|
|
@@ -14695,7 +14720,7 @@ async function publishCommand() {
|
|
|
14695
14720
|
const dir = process.cwd();
|
|
14696
14721
|
const config = loadConfig();
|
|
14697
14722
|
if (!config) {
|
|
14698
|
-
console.log(
|
|
14723
|
+
console.log(chalk25.red("No LLM provider configured. Run ") + chalk25.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk25.red(" first."));
|
|
14699
14724
|
throw new Error("__exit__");
|
|
14700
14725
|
}
|
|
14701
14726
|
const spinner = ora7("Generating project summary...").start();
|
|
@@ -14736,13 +14761,13 @@ async function publishCommand() {
|
|
|
14736
14761
|
const outputPath = path40.join(outputDir, "summary.json");
|
|
14737
14762
|
fs49.writeFileSync(outputPath, JSON.stringify(summary, null, 2) + "\n", "utf-8");
|
|
14738
14763
|
spinner.succeed("Project summary published");
|
|
14739
|
-
console.log(` ${
|
|
14740
|
-
console.log(
|
|
14741
|
-
console.log(
|
|
14764
|
+
console.log(` ${chalk25.green("\u2713")} ${path40.relative(dir, outputPath)}`);
|
|
14765
|
+
console.log(chalk25.dim("\n Other projects can now reference this repo as a source."));
|
|
14766
|
+
console.log(chalk25.dim(" When they run `caliber init`, they'll read this summary automatically.\n"));
|
|
14742
14767
|
} catch (err) {
|
|
14743
14768
|
spinner.fail("Failed to generate summary");
|
|
14744
14769
|
if (err instanceof Error && err.message === "__exit__") throw err;
|
|
14745
|
-
console.error(
|
|
14770
|
+
console.error(chalk25.red(err instanceof Error ? err.message : "Unknown error"));
|
|
14746
14771
|
throw new Error("__exit__");
|
|
14747
14772
|
}
|
|
14748
14773
|
}
|
|
@@ -14750,7 +14775,7 @@ async function publishCommand() {
|
|
|
14750
14775
|
// src/commands/bootstrap.ts
|
|
14751
14776
|
init_builtin_skills();
|
|
14752
14777
|
import fs50 from "fs";
|
|
14753
|
-
import
|
|
14778
|
+
import chalk26 from "chalk";
|
|
14754
14779
|
var PLATFORM_SKILL_DIRS = {
|
|
14755
14780
|
claude: ".claude/skills",
|
|
14756
14781
|
cursor: ".cursor/skills",
|
|
@@ -14776,21 +14801,21 @@ async function bootstrapCommand() {
|
|
|
14776
14801
|
}
|
|
14777
14802
|
}
|
|
14778
14803
|
if (written.length === 0) {
|
|
14779
|
-
console.log(
|
|
14804
|
+
console.log(chalk26.yellow("No skills were written."));
|
|
14780
14805
|
return;
|
|
14781
14806
|
}
|
|
14782
|
-
console.log(
|
|
14807
|
+
console.log(chalk26.bold.green("\n Caliber skills installed!\n"));
|
|
14783
14808
|
for (const file of written) {
|
|
14784
|
-
console.log(` ${
|
|
14809
|
+
console.log(` ${chalk26.green("\u2713")} ${file}`);
|
|
14785
14810
|
}
|
|
14786
|
-
console.log(
|
|
14787
|
-
console.log(
|
|
14811
|
+
console.log(chalk26.dim("\n Your agent can now run /setup-caliber to complete the setup."));
|
|
14812
|
+
console.log(chalk26.dim(' Just tell your agent: "Run /setup-caliber"\n'));
|
|
14788
14813
|
}
|
|
14789
14814
|
|
|
14790
14815
|
// src/commands/uninstall.ts
|
|
14791
14816
|
import fs51 from "fs";
|
|
14792
14817
|
import path41 from "path";
|
|
14793
|
-
import
|
|
14818
|
+
import chalk27 from "chalk";
|
|
14794
14819
|
import confirm3 from "@inquirer/confirm";
|
|
14795
14820
|
init_pre_commit_block();
|
|
14796
14821
|
init_builtin_skills();
|
|
@@ -14853,19 +14878,19 @@ function removeDirectory(dir) {
|
|
|
14853
14878
|
return true;
|
|
14854
14879
|
}
|
|
14855
14880
|
async function uninstallCommand(options) {
|
|
14856
|
-
console.log(
|
|
14857
|
-
console.log(
|
|
14858
|
-
console.log(
|
|
14859
|
-
console.log(
|
|
14860
|
-
console.log(
|
|
14861
|
-
console.log(
|
|
14862
|
-
console.log(
|
|
14863
|
-
console.log(
|
|
14864
|
-
console.log(
|
|
14881
|
+
console.log(chalk27.bold("\n Caliber Uninstall\n"));
|
|
14882
|
+
console.log(chalk27.dim(" This will remove all Caliber resources from this project:\n"));
|
|
14883
|
+
console.log(chalk27.dim(" \u2022 Pre-commit hook"));
|
|
14884
|
+
console.log(chalk27.dim(" \u2022 Session learning hooks"));
|
|
14885
|
+
console.log(chalk27.dim(" \u2022 Managed blocks in CLAUDE.md, AGENTS.md, copilot-instructions.md"));
|
|
14886
|
+
console.log(chalk27.dim(" \u2022 Cursor rules (caliber-*.mdc)"));
|
|
14887
|
+
console.log(chalk27.dim(" \u2022 Built-in skills (setup-caliber, find-skills, save-learning)"));
|
|
14888
|
+
console.log(chalk27.dim(" \u2022 CALIBER_LEARNINGS.md"));
|
|
14889
|
+
console.log(chalk27.dim(" \u2022 .caliber/ directory (backups, cache, state)\n"));
|
|
14865
14890
|
if (!options.force) {
|
|
14866
14891
|
const proceed = await confirm3({ message: "Continue with uninstall?" });
|
|
14867
14892
|
if (!proceed) {
|
|
14868
|
-
console.log(
|
|
14893
|
+
console.log(chalk27.dim("\n Cancelled.\n"));
|
|
14869
14894
|
return;
|
|
14870
14895
|
}
|
|
14871
14896
|
}
|
|
@@ -14873,65 +14898,65 @@ async function uninstallCommand(options) {
|
|
|
14873
14898
|
const actions = [];
|
|
14874
14899
|
const hookResult = removePreCommitHook();
|
|
14875
14900
|
if (hookResult.removed) {
|
|
14876
|
-
console.log(` ${
|
|
14901
|
+
console.log(` ${chalk27.red("\u2717")} Pre-commit hook removed`);
|
|
14877
14902
|
actions.push("pre-commit hook");
|
|
14878
14903
|
}
|
|
14879
14904
|
const stopHookResult = removeStopHook();
|
|
14880
14905
|
if (stopHookResult.removed) {
|
|
14881
|
-
console.log(` ${
|
|
14906
|
+
console.log(` ${chalk27.red("\u2717")} Onboarding hook removed`);
|
|
14882
14907
|
actions.push("onboarding hook");
|
|
14883
14908
|
}
|
|
14884
14909
|
const notificationHookResult = removeNotificationHook();
|
|
14885
14910
|
if (notificationHookResult.removed) {
|
|
14886
|
-
console.log(` ${
|
|
14911
|
+
console.log(` ${chalk27.red("\u2717")} Notification hook removed`);
|
|
14887
14912
|
actions.push("notification hook");
|
|
14888
14913
|
}
|
|
14889
14914
|
const sessionStartResult = removeSessionStartHook();
|
|
14890
14915
|
if (sessionStartResult.removed) {
|
|
14891
|
-
console.log(` ${
|
|
14916
|
+
console.log(` ${chalk27.red("\u2717")} SessionStart hook removed`);
|
|
14892
14917
|
actions.push("session-start hook");
|
|
14893
14918
|
}
|
|
14894
14919
|
const learnResult = removeLearningHooks();
|
|
14895
14920
|
if (learnResult.removed) {
|
|
14896
|
-
console.log(` ${
|
|
14921
|
+
console.log(` ${chalk27.red("\u2717")} Claude Code learning hooks removed`);
|
|
14897
14922
|
actions.push("claude learning hooks");
|
|
14898
14923
|
}
|
|
14899
14924
|
const cursorLearnResult = removeCursorLearningHooks();
|
|
14900
14925
|
if (cursorLearnResult.removed) {
|
|
14901
|
-
console.log(` ${
|
|
14926
|
+
console.log(` ${chalk27.red("\u2717")} Cursor learning hooks removed`);
|
|
14902
14927
|
actions.push("cursor learning hooks");
|
|
14903
14928
|
}
|
|
14904
14929
|
const strippedFiles = stripManagedBlocksFromFiles();
|
|
14905
14930
|
for (const file of strippedFiles) {
|
|
14906
|
-
console.log(` ${
|
|
14931
|
+
console.log(` ${chalk27.yellow("~")} ${file} \u2014 managed blocks removed`);
|
|
14907
14932
|
actions.push(file);
|
|
14908
14933
|
}
|
|
14909
14934
|
const removedCursorRules = removeCaliberManagedFiles(CURSOR_RULES_DIR, ".mdc");
|
|
14910
14935
|
for (const rule of removedCursorRules) {
|
|
14911
|
-
console.log(` ${
|
|
14936
|
+
console.log(` ${chalk27.red("\u2717")} ${rule}`);
|
|
14912
14937
|
}
|
|
14913
14938
|
if (removedCursorRules.length > 0) actions.push("cursor rules");
|
|
14914
14939
|
const removedClaudeRules = removeCaliberManagedFiles(CLAUDE_RULES_DIR, ".md");
|
|
14915
14940
|
for (const rule of removedClaudeRules) {
|
|
14916
|
-
console.log(` ${
|
|
14941
|
+
console.log(` ${chalk27.red("\u2717")} ${rule}`);
|
|
14917
14942
|
}
|
|
14918
14943
|
if (removedClaudeRules.length > 0) actions.push("claude rules");
|
|
14919
14944
|
const removedSkills = removeBuiltinSkills();
|
|
14920
14945
|
for (const skill of removedSkills) {
|
|
14921
|
-
console.log(` ${
|
|
14946
|
+
console.log(` ${chalk27.red("\u2717")} ${skill}/`);
|
|
14922
14947
|
}
|
|
14923
14948
|
if (removedSkills.length > 0) actions.push("builtin skills");
|
|
14924
14949
|
if (fs51.existsSync("CALIBER_LEARNINGS.md")) {
|
|
14925
14950
|
fs51.unlinkSync("CALIBER_LEARNINGS.md");
|
|
14926
|
-
console.log(` ${
|
|
14951
|
+
console.log(` ${chalk27.red("\u2717")} CALIBER_LEARNINGS.md`);
|
|
14927
14952
|
actions.push("learnings file");
|
|
14928
14953
|
}
|
|
14929
14954
|
if (removeDirectory(CALIBER_DIR)) {
|
|
14930
|
-
console.log(` ${
|
|
14955
|
+
console.log(` ${chalk27.red("\u2717")} .caliber/ directory`);
|
|
14931
14956
|
actions.push(".caliber directory");
|
|
14932
14957
|
}
|
|
14933
14958
|
if (actions.length === 0) {
|
|
14934
|
-
console.log(
|
|
14959
|
+
console.log(chalk27.dim(" Nothing to remove \u2014 Caliber is not installed in this project.\n"));
|
|
14935
14960
|
return;
|
|
14936
14961
|
}
|
|
14937
14962
|
trackUninstallExecuted();
|
|
@@ -14943,7 +14968,7 @@ async function uninstallCommand(options) {
|
|
|
14943
14968
|
});
|
|
14944
14969
|
if (removeConfig) {
|
|
14945
14970
|
fs51.unlinkSync(configPath);
|
|
14946
|
-
console.log(` ${
|
|
14971
|
+
console.log(` ${chalk27.red("\u2717")} ${configPath}`);
|
|
14947
14972
|
const configDir = path41.dirname(configPath);
|
|
14948
14973
|
try {
|
|
14949
14974
|
const remaining = fs51.readdirSync(configDir);
|
|
@@ -14952,9 +14977,9 @@ async function uninstallCommand(options) {
|
|
|
14952
14977
|
}
|
|
14953
14978
|
}
|
|
14954
14979
|
}
|
|
14955
|
-
console.log(
|
|
14980
|
+
console.log(chalk27.bold.green(`
|
|
14956
14981
|
Caliber has been removed from this project.`));
|
|
14957
|
-
console.log(
|
|
14982
|
+
console.log(chalk27.dim(" Your code is untouched \u2014 only Caliber config files were removed.\n"));
|
|
14958
14983
|
}
|
|
14959
14984
|
|
|
14960
14985
|
// src/cli.ts
|
|
@@ -15074,7 +15099,7 @@ import fs53 from "fs";
|
|
|
15074
15099
|
import path43 from "path";
|
|
15075
15100
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
15076
15101
|
import { execSync as execSync18, execFileSync as execFileSync5 } from "child_process";
|
|
15077
|
-
import
|
|
15102
|
+
import chalk28 from "chalk";
|
|
15078
15103
|
import ora8 from "ora";
|
|
15079
15104
|
import confirm4 from "@inquirer/confirm";
|
|
15080
15105
|
var __dirname_vc = path43.dirname(fileURLToPath2(import.meta.url));
|
|
@@ -15131,16 +15156,16 @@ async function checkForUpdates() {
|
|
|
15131
15156
|
if (!isInteractive) {
|
|
15132
15157
|
const installTag = channel === "latest" ? "" : `@${channel}`;
|
|
15133
15158
|
console.log(
|
|
15134
|
-
|
|
15159
|
+
chalk28.yellow(
|
|
15135
15160
|
`
|
|
15136
15161
|
Update available: ${current} -> ${latest}
|
|
15137
|
-
Run ${
|
|
15162
|
+
Run ${chalk28.bold(`npm install -g @rely-ai/caliber${installTag}`)} to upgrade.
|
|
15138
15163
|
`
|
|
15139
15164
|
)
|
|
15140
15165
|
);
|
|
15141
15166
|
return;
|
|
15142
15167
|
}
|
|
15143
|
-
console.log(
|
|
15168
|
+
console.log(chalk28.yellow(`
|
|
15144
15169
|
Update available: ${current} -> ${latest}`));
|
|
15145
15170
|
const shouldUpdate = await confirm4({
|
|
15146
15171
|
message: "Would you like to update now? (Y/n)",
|
|
@@ -15163,14 +15188,14 @@ Update available: ${current} -> ${latest}`));
|
|
|
15163
15188
|
if (installed !== latest) {
|
|
15164
15189
|
spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
|
|
15165
15190
|
console.log(
|
|
15166
|
-
|
|
15191
|
+
chalk28.yellow(`Run ${chalk28.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually.
|
|
15167
15192
|
`)
|
|
15168
15193
|
);
|
|
15169
15194
|
return;
|
|
15170
15195
|
}
|
|
15171
|
-
spinner.succeed(
|
|
15196
|
+
spinner.succeed(chalk28.green(`Updated to ${latest}`));
|
|
15172
15197
|
const args = process.argv.slice(2);
|
|
15173
|
-
console.log(
|
|
15198
|
+
console.log(chalk28.dim(`
|
|
15174
15199
|
Restarting: caliber ${args.join(" ")}
|
|
15175
15200
|
`));
|
|
15176
15201
|
execFileSync5("caliber", args, {
|
|
@@ -15183,11 +15208,11 @@ Restarting: caliber ${args.join(" ")}
|
|
|
15183
15208
|
if (err instanceof Error) {
|
|
15184
15209
|
const stderr = err.stderr;
|
|
15185
15210
|
const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
|
|
15186
|
-
if (errMsg && !errMsg.includes("SIGTERM")) console.log(
|
|
15211
|
+
if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk28.dim(` ${errMsg}`));
|
|
15187
15212
|
}
|
|
15188
15213
|
console.log(
|
|
15189
|
-
|
|
15190
|
-
`Run ${
|
|
15214
|
+
chalk28.yellow(
|
|
15215
|
+
`Run ${chalk28.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually to upgrade.
|
|
15191
15216
|
`
|
|
15192
15217
|
)
|
|
15193
15218
|
);
|