@rely-ai/caliber 1.6.1 → 1.7.0

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.
Files changed (2) hide show
  1. package/dist/bin.js +604 -403
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -20,6 +20,120 @@ var __copyProps = (to, from, except, desc) => {
20
20
  };
21
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
22
 
23
+ // src/llm/config.ts
24
+ var config_exports = {};
25
+ __export(config_exports, {
26
+ DEFAULT_FAST_MODELS: () => DEFAULT_FAST_MODELS,
27
+ DEFAULT_MODELS: () => DEFAULT_MODELS,
28
+ getConfigFilePath: () => getConfigFilePath,
29
+ getFastModel: () => getFastModel,
30
+ loadConfig: () => loadConfig,
31
+ readConfigFile: () => readConfigFile,
32
+ resolveFromEnv: () => resolveFromEnv,
33
+ writeConfigFile: () => writeConfigFile
34
+ });
35
+ import fs4 from "fs";
36
+ import path4 from "path";
37
+ import os from "os";
38
+ function loadConfig() {
39
+ const envConfig = resolveFromEnv();
40
+ if (envConfig) return envConfig;
41
+ return readConfigFile();
42
+ }
43
+ function resolveFromEnv() {
44
+ if (process.env.ANTHROPIC_API_KEY) {
45
+ return {
46
+ provider: "anthropic",
47
+ apiKey: process.env.ANTHROPIC_API_KEY,
48
+ model: process.env.CALIBER_MODEL || DEFAULT_MODELS.anthropic
49
+ };
50
+ }
51
+ if (process.env.VERTEX_PROJECT_ID || process.env.GCP_PROJECT_ID) {
52
+ return {
53
+ provider: "vertex",
54
+ model: process.env.CALIBER_MODEL || DEFAULT_MODELS.vertex,
55
+ vertexProjectId: process.env.VERTEX_PROJECT_ID || process.env.GCP_PROJECT_ID,
56
+ vertexRegion: process.env.VERTEX_REGION || process.env.GCP_REGION || "us-east5",
57
+ vertexCredentials: process.env.VERTEX_SA_CREDENTIALS || process.env.GOOGLE_APPLICATION_CREDENTIALS
58
+ };
59
+ }
60
+ if (process.env.OPENAI_API_KEY) {
61
+ return {
62
+ provider: "openai",
63
+ apiKey: process.env.OPENAI_API_KEY,
64
+ model: process.env.CALIBER_MODEL || DEFAULT_MODELS.openai,
65
+ baseUrl: process.env.OPENAI_BASE_URL
66
+ };
67
+ }
68
+ if (process.env.CALIBER_USE_CURSOR_SEAT === "1" || process.env.CALIBER_USE_CURSOR_SEAT === "true") {
69
+ return {
70
+ provider: "cursor",
71
+ model: DEFAULT_MODELS.cursor
72
+ };
73
+ }
74
+ if (process.env.CALIBER_USE_CLAUDE_CLI === "1" || process.env.CALIBER_USE_CLAUDE_CLI === "true") {
75
+ return {
76
+ provider: "claude-cli",
77
+ model: DEFAULT_MODELS["claude-cli"]
78
+ };
79
+ }
80
+ return null;
81
+ }
82
+ function readConfigFile() {
83
+ try {
84
+ if (!fs4.existsSync(CONFIG_FILE)) return null;
85
+ const raw = fs4.readFileSync(CONFIG_FILE, "utf-8");
86
+ const parsed = JSON.parse(raw);
87
+ if (!parsed.provider || !["anthropic", "vertex", "openai", "cursor", "claude-cli"].includes(parsed.provider)) {
88
+ return null;
89
+ }
90
+ return parsed;
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+ function writeConfigFile(config) {
96
+ if (!fs4.existsSync(CONFIG_DIR)) {
97
+ fs4.mkdirSync(CONFIG_DIR, { recursive: true });
98
+ }
99
+ const sanitized = { ...config };
100
+ if (sanitized.apiKey) {
101
+ sanitized.apiKey = sanitized.apiKey.trim();
102
+ }
103
+ fs4.writeFileSync(CONFIG_FILE, JSON.stringify(sanitized, null, 2) + "\n", { mode: 384 });
104
+ }
105
+ function getConfigFilePath() {
106
+ return CONFIG_FILE;
107
+ }
108
+ function getFastModel() {
109
+ if (process.env.CALIBER_FAST_MODEL) return process.env.CALIBER_FAST_MODEL;
110
+ if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL;
111
+ const config = loadConfig();
112
+ if (config?.fastModel) return config.fastModel;
113
+ if (config?.provider) return DEFAULT_FAST_MODELS[config.provider];
114
+ return void 0;
115
+ }
116
+ var CONFIG_DIR, CONFIG_FILE, DEFAULT_MODELS, DEFAULT_FAST_MODELS;
117
+ var init_config = __esm({
118
+ "src/llm/config.ts"() {
119
+ "use strict";
120
+ CONFIG_DIR = path4.join(os.homedir(), ".caliber");
121
+ CONFIG_FILE = path4.join(CONFIG_DIR, "config.json");
122
+ DEFAULT_MODELS = {
123
+ anthropic: "claude-sonnet-4-6",
124
+ vertex: "claude-sonnet-4-6",
125
+ openai: "gpt-4.1",
126
+ cursor: "default",
127
+ "claude-cli": "default"
128
+ };
129
+ DEFAULT_FAST_MODELS = {
130
+ anthropic: "claude-haiku-4-5-20251001",
131
+ vertex: "claude-haiku-4-5-20251001",
132
+ openai: "gpt-4.1-mini"
133
+ };
134
+ }
135
+ });
136
+
23
137
  // src/constants.ts
24
138
  var constants_exports = {};
25
139
  __export(constants_exports, {
@@ -56,10 +170,10 @@ import path21 from "path";
56
170
  import { fileURLToPath } from "url";
57
171
 
58
172
  // src/commands/onboard.ts
59
- import chalk6 from "chalk";
173
+ import chalk7 from "chalk";
60
174
  import ora2 from "ora";
61
175
  import readline3 from "readline";
62
- import select4 from "@inquirer/select";
176
+ import select5 from "@inquirer/select";
63
177
  import checkbox from "@inquirer/checkbox";
64
178
  import fs21 from "fs";
65
179
 
@@ -507,102 +621,8 @@ function estimateSummarySize(summary) {
507
621
  return summary.path.length + summary.imports.reduce((s, i) => s + i.length, 0) + summary.exports.reduce((s, e) => s + e.length, 0) + summary.functions.reduce((s, f) => s + f.length, 0) + summary.classes.reduce((s, c) => s + c.length, 0) + summary.types.reduce((s, t) => s + t.length, 0) + summary.routes.reduce((s, r) => s + r.length, 0);
508
622
  }
509
623
 
510
- // src/llm/config.ts
511
- import fs4 from "fs";
512
- import path4 from "path";
513
- import os from "os";
514
- var CONFIG_DIR = path4.join(os.homedir(), ".caliber");
515
- var CONFIG_FILE = path4.join(CONFIG_DIR, "config.json");
516
- var DEFAULT_MODELS = {
517
- anthropic: "claude-sonnet-4-6",
518
- vertex: "claude-sonnet-4-6",
519
- openai: "gpt-4.1",
520
- cursor: "default",
521
- "claude-cli": "default"
522
- };
523
- var DEFAULT_FAST_MODELS = {
524
- anthropic: "claude-haiku-4-5-20251001",
525
- vertex: "claude-haiku-4-5-20251001",
526
- openai: "gpt-4.1-mini"
527
- };
528
- function loadConfig() {
529
- const envConfig = resolveFromEnv();
530
- if (envConfig) return envConfig;
531
- return readConfigFile();
532
- }
533
- function resolveFromEnv() {
534
- if (process.env.ANTHROPIC_API_KEY) {
535
- return {
536
- provider: "anthropic",
537
- apiKey: process.env.ANTHROPIC_API_KEY,
538
- model: process.env.CALIBER_MODEL || DEFAULT_MODELS.anthropic
539
- };
540
- }
541
- if (process.env.VERTEX_PROJECT_ID || process.env.GCP_PROJECT_ID) {
542
- return {
543
- provider: "vertex",
544
- model: process.env.CALIBER_MODEL || DEFAULT_MODELS.vertex,
545
- vertexProjectId: process.env.VERTEX_PROJECT_ID || process.env.GCP_PROJECT_ID,
546
- vertexRegion: process.env.VERTEX_REGION || process.env.GCP_REGION || "us-east5",
547
- vertexCredentials: process.env.VERTEX_SA_CREDENTIALS || process.env.GOOGLE_APPLICATION_CREDENTIALS
548
- };
549
- }
550
- if (process.env.OPENAI_API_KEY) {
551
- return {
552
- provider: "openai",
553
- apiKey: process.env.OPENAI_API_KEY,
554
- model: process.env.CALIBER_MODEL || DEFAULT_MODELS.openai,
555
- baseUrl: process.env.OPENAI_BASE_URL
556
- };
557
- }
558
- if (process.env.CALIBER_USE_CURSOR_SEAT === "1" || process.env.CALIBER_USE_CURSOR_SEAT === "true") {
559
- return {
560
- provider: "cursor",
561
- model: DEFAULT_MODELS.cursor
562
- };
563
- }
564
- if (process.env.CALIBER_USE_CLAUDE_CLI === "1" || process.env.CALIBER_USE_CLAUDE_CLI === "true") {
565
- return {
566
- provider: "claude-cli",
567
- model: DEFAULT_MODELS["claude-cli"]
568
- };
569
- }
570
- return null;
571
- }
572
- function readConfigFile() {
573
- try {
574
- if (!fs4.existsSync(CONFIG_FILE)) return null;
575
- const raw = fs4.readFileSync(CONFIG_FILE, "utf-8");
576
- const parsed = JSON.parse(raw);
577
- if (!parsed.provider || !["anthropic", "vertex", "openai", "cursor", "claude-cli"].includes(parsed.provider)) {
578
- return null;
579
- }
580
- return parsed;
581
- } catch {
582
- return null;
583
- }
584
- }
585
- function writeConfigFile(config) {
586
- if (!fs4.existsSync(CONFIG_DIR)) {
587
- fs4.mkdirSync(CONFIG_DIR, { recursive: true });
588
- }
589
- const sanitized = { ...config };
590
- if (sanitized.apiKey) {
591
- sanitized.apiKey = sanitized.apiKey.trim();
592
- }
593
- fs4.writeFileSync(CONFIG_FILE, JSON.stringify(sanitized, null, 2) + "\n", { mode: 384 });
594
- }
595
- function getConfigFilePath() {
596
- return CONFIG_FILE;
597
- }
598
- function getFastModel() {
599
- if (process.env.CALIBER_FAST_MODEL) return process.env.CALIBER_FAST_MODEL;
600
- if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL;
601
- const config = loadConfig();
602
- if (config?.fastModel) return config.fastModel;
603
- if (config?.provider) return DEFAULT_FAST_MODELS[config.provider];
604
- return void 0;
605
- }
624
+ // src/llm/index.ts
625
+ init_config();
606
626
 
607
627
  // src/llm/anthropic.ts
608
628
  import Anthropic from "@anthropic-ai/sdk";
@@ -623,6 +643,14 @@ var AnthropicProvider = class {
623
643
  const block = response.content[0];
624
644
  return block.type === "text" ? block.text : "";
625
645
  }
646
+ async listModels() {
647
+ const models = [];
648
+ const page = await this.client.models.list({ limit: 100 });
649
+ for (const model of page.data) {
650
+ models.push(model.id);
651
+ }
652
+ return models;
653
+ }
626
654
  async stream(options, callbacks) {
627
655
  const messages = options.messages ? [
628
656
  ...options.messages.map((msg) => ({
@@ -743,6 +771,13 @@ var OpenAICompatProvider = class {
743
771
  });
744
772
  return response.choices[0]?.message?.content || "";
745
773
  }
774
+ async listModels() {
775
+ const models = [];
776
+ for await (const model of this.client.models.list()) {
777
+ models.push(model.id);
778
+ }
779
+ return models;
780
+ }
746
781
  async stream(options, callbacks) {
747
782
  const messages = [
748
783
  { role: "system", content: options.system }
@@ -1108,7 +1143,108 @@ function estimateTokens(text) {
1108
1143
  return Math.ceil(text.length / 4);
1109
1144
  }
1110
1145
 
1146
+ // src/llm/model-recovery.ts
1147
+ init_config();
1148
+ import chalk from "chalk";
1149
+ import select from "@inquirer/select";
1150
+ var KNOWN_MODELS = {
1151
+ anthropic: [
1152
+ "claude-sonnet-4-6",
1153
+ "claude-sonnet-4-5-20250514",
1154
+ "claude-haiku-4-5-20251001",
1155
+ "claude-opus-4-6",
1156
+ "claude-opus-4-1-20250620"
1157
+ ],
1158
+ vertex: [
1159
+ "claude-sonnet-4-6@20250514",
1160
+ "claude-sonnet-4-5-20250514",
1161
+ "claude-haiku-4-5-20251001",
1162
+ "claude-opus-4-6@20250605",
1163
+ "claude-opus-4-1-20250620"
1164
+ ],
1165
+ openai: [
1166
+ "gpt-4.1",
1167
+ "gpt-4.1-mini",
1168
+ "gpt-4o",
1169
+ "gpt-4o-mini",
1170
+ "o3-mini"
1171
+ ],
1172
+ cursor: [],
1173
+ "claude-cli": []
1174
+ };
1175
+ function isModelNotAvailableError(error) {
1176
+ const msg = error.message.toLowerCase();
1177
+ const status = error.status;
1178
+ if (status === 404 && msg.includes("model")) return true;
1179
+ if (msg.includes("model") && (msg.includes("not found") || msg.includes("not_found"))) return true;
1180
+ if (msg.includes("model") && msg.includes("not available")) return true;
1181
+ if (msg.includes("model") && msg.includes("does not exist")) return true;
1182
+ if (msg.includes("publisher model")) return true;
1183
+ return false;
1184
+ }
1185
+ function filterRelevantModels(models, provider) {
1186
+ switch (provider) {
1187
+ case "anthropic":
1188
+ case "vertex":
1189
+ return models.filter((m) => m.startsWith("claude-"));
1190
+ case "openai":
1191
+ return models.filter(
1192
+ (m) => m.startsWith("gpt-4") || m.startsWith("gpt-3.5") || m.startsWith("o1") || m.startsWith("o3")
1193
+ );
1194
+ default:
1195
+ return models;
1196
+ }
1197
+ }
1198
+ async function handleModelNotAvailable(failedModel, provider, config) {
1199
+ if (!process.stdin.isTTY) {
1200
+ console.error(
1201
+ chalk.red(`Model "${failedModel}" is not available. Run \`caliber config\` to select a different model.`)
1202
+ );
1203
+ return null;
1204
+ }
1205
+ console.log(chalk.yellow(`
1206
+ \u26A0 Model "${failedModel}" is not available on your ${config.provider} deployment.`));
1207
+ let models = [];
1208
+ if (provider.listModels) {
1209
+ try {
1210
+ const allModels = await provider.listModels();
1211
+ models = filterRelevantModels(allModels, config.provider);
1212
+ } catch {
1213
+ }
1214
+ }
1215
+ if (models.length === 0) {
1216
+ models = KNOWN_MODELS[config.provider] ?? [];
1217
+ }
1218
+ models = models.filter((m) => m !== failedModel);
1219
+ if (models.length === 0) {
1220
+ console.log(chalk.red(" No alternative models found. Run `caliber config` to configure manually."));
1221
+ return null;
1222
+ }
1223
+ console.log("");
1224
+ let selected;
1225
+ try {
1226
+ selected = await select({
1227
+ message: "Pick an available model",
1228
+ choices: models.map((m) => ({ name: m, value: m }))
1229
+ });
1230
+ } catch {
1231
+ return null;
1232
+ }
1233
+ const isDefaultModel = failedModel === config.model;
1234
+ const updatedConfig = isDefaultModel ? { ...config, model: selected } : { ...config, fastModel: selected };
1235
+ writeConfigFile(updatedConfig);
1236
+ if (isDefaultModel) {
1237
+ process.env.CALIBER_MODEL = selected;
1238
+ } else {
1239
+ process.env.CALIBER_FAST_MODEL = selected;
1240
+ }
1241
+ console.log(chalk.green(`\u2713 Switched to ${selected}
1242
+ `));
1243
+ return selected;
1244
+ }
1245
+
1111
1246
  // src/llm/index.ts
1247
+ init_config();
1112
1248
  var cachedProvider = null;
1113
1249
  var cachedConfig = null;
1114
1250
  function createProvider(config) {
@@ -1151,6 +1287,10 @@ function getProvider() {
1151
1287
  cachedProvider = createProvider(config);
1152
1288
  return cachedProvider;
1153
1289
  }
1290
+ function resetProvider() {
1291
+ cachedProvider = null;
1292
+ cachedConfig = null;
1293
+ }
1154
1294
  var TRANSIENT_ERRORS = ["terminated", "ECONNRESET", "ETIMEDOUT", "socket hang up", "other side closed"];
1155
1295
  var MAX_RETRIES = 3;
1156
1296
  function isTransientError(error) {
@@ -1168,6 +1308,16 @@ async function llmCall(options) {
1168
1308
  return await provider.call(options);
1169
1309
  } catch (err) {
1170
1310
  const error = err instanceof Error ? err : new Error(String(err));
1311
+ if (isModelNotAvailableError(error) && cachedConfig) {
1312
+ const failedModel = options.model || cachedConfig.model;
1313
+ const newModel = await handleModelNotAvailable(failedModel, provider, cachedConfig);
1314
+ if (newModel) {
1315
+ resetProvider();
1316
+ const newProvider = getProvider();
1317
+ return await newProvider.call({ ...options, model: newModel });
1318
+ }
1319
+ throw error;
1320
+ }
1171
1321
  if (isOverloaded(error) && attempt < MAX_RETRIES) {
1172
1322
  await new Promise((r) => setTimeout(r, 2e3));
1173
1323
  continue;
@@ -1185,6 +1335,40 @@ async function llmJsonCall(options) {
1185
1335
  const text = await llmCall(options);
1186
1336
  return parseJsonResponse(text);
1187
1337
  }
1338
+ async function validateModel(options) {
1339
+ const provider = getProvider();
1340
+ const config = cachedConfig;
1341
+ if (!config) return;
1342
+ const modelsToCheck = [config.model];
1343
+ if (options?.fast) {
1344
+ const { getFastModel: getFastModel2 } = await Promise.resolve().then(() => (init_config(), config_exports));
1345
+ const fast = getFastModel2();
1346
+ if (fast && fast !== config.model) modelsToCheck.push(fast);
1347
+ }
1348
+ for (const model of modelsToCheck) {
1349
+ try {
1350
+ await provider.call({
1351
+ system: "Respond with OK",
1352
+ prompt: "ping",
1353
+ model,
1354
+ maxTokens: 1
1355
+ });
1356
+ } catch (err) {
1357
+ const error = err instanceof Error ? err : new Error(String(err));
1358
+ if (isModelNotAvailableError(error)) {
1359
+ const newModel = await handleModelNotAvailable(model, provider, config);
1360
+ if (newModel) {
1361
+ resetProvider();
1362
+ return;
1363
+ }
1364
+ throw error;
1365
+ }
1366
+ }
1367
+ }
1368
+ }
1369
+
1370
+ // src/ai/detect.ts
1371
+ init_config();
1188
1372
 
1189
1373
  // src/ai/prompts.ts
1190
1374
  var GENERATION_SYSTEM_PROMPT = `You are an expert auditor for coding agent configurations (Claude Code, Cursor, and Codex).
@@ -1479,6 +1663,7 @@ async function detectProjectStack(fileTree, fileContents) {
1479
1663
  }
1480
1664
 
1481
1665
  // src/fingerprint/index.ts
1666
+ init_config();
1482
1667
  async function collectFingerprint(dir) {
1483
1668
  const gitRemoteUrl = getGitRemoteUrl();
1484
1669
  const fileTree = getFileTree(dir);
@@ -2176,9 +2361,9 @@ function cleanupStaging() {
2176
2361
  }
2177
2362
 
2178
2363
  // src/utils/review.ts
2179
- import chalk from "chalk";
2364
+ import chalk2 from "chalk";
2180
2365
  import fs14 from "fs";
2181
- import select from "@inquirer/select";
2366
+ import select2 from "@inquirer/select";
2182
2367
  import { createTwoFilesPatch } from "diff";
2183
2368
 
2184
2369
  // src/utils/editor.ts
@@ -2221,7 +2406,7 @@ function openDiffsInEditor(editor, files) {
2221
2406
 
2222
2407
  // src/utils/review.ts
2223
2408
  async function promptWantsReview() {
2224
- return select({
2409
+ return select2({
2225
2410
  message: "Would you like to review the diffs before deciding?",
2226
2411
  choices: [
2227
2412
  { name: "Yes, show me the diffs", value: true },
@@ -2242,7 +2427,7 @@ async function promptReviewMethod() {
2242
2427
  return { name: "Terminal", value: "terminal" };
2243
2428
  }
2244
2429
  });
2245
- return select({ message: "How would you like to review the changes?", choices });
2430
+ return select2({ message: "How would you like to review the changes?", choices });
2246
2431
  }
2247
2432
  async function openReview(method, stagedFiles) {
2248
2433
  if (method === "cursor" || method === "vscode") {
@@ -2250,7 +2435,7 @@ async function openReview(method, stagedFiles) {
2250
2435
  originalPath: f.originalPath,
2251
2436
  proposedPath: f.proposedPath
2252
2437
  })));
2253
- console.log(chalk.dim(" Diffs opened in your editor.\n"));
2438
+ console.log(chalk2.dim(" Diffs opened in your editor.\n"));
2254
2439
  return;
2255
2440
  }
2256
2441
  const fileInfos = stagedFiles.map((file) => {
@@ -2281,8 +2466,8 @@ async function openReview(method, stagedFiles) {
2281
2466
  async function interactiveDiffExplorer(files) {
2282
2467
  if (!process.stdin.isTTY) {
2283
2468
  for (const f of files) {
2284
- const icon = f.isNew ? chalk.green("+") : chalk.yellow("~");
2285
- const stats = f.isNew ? chalk.dim(`${f.lines} lines`) : `${chalk.green(`+${f.added}`)} ${chalk.red(`-${f.removed}`)}`;
2469
+ const icon = f.isNew ? chalk2.green("+") : chalk2.yellow("~");
2470
+ const stats = f.isNew ? chalk2.dim(`${f.lines} lines`) : `${chalk2.green(`+${f.added}`)} ${chalk2.red(`-${f.removed}`)}`;
2286
2471
  console.log(` ${icon} ${f.relativePath} ${stats}`);
2287
2472
  }
2288
2473
  console.log("");
@@ -2298,47 +2483,47 @@ async function interactiveDiffExplorer(files) {
2298
2483
  }
2299
2484
  function renderFileList() {
2300
2485
  const lines = [];
2301
- lines.push(chalk.bold(" Review changes"));
2486
+ lines.push(chalk2.bold(" Review changes"));
2302
2487
  lines.push("");
2303
2488
  for (let i = 0; i < files.length; i++) {
2304
2489
  const f = files[i];
2305
- const ptr = i === cursor ? chalk.cyan(">") : " ";
2306
- const icon = f.isNew ? chalk.green("+") : chalk.yellow("~");
2307
- const stats = f.isNew ? chalk.dim(`${f.lines} lines`) : `${chalk.green(`+${f.added}`)} ${chalk.red(`-${f.removed}`)}`;
2490
+ const ptr = i === cursor ? chalk2.cyan(">") : " ";
2491
+ const icon = f.isNew ? chalk2.green("+") : chalk2.yellow("~");
2492
+ const stats = f.isNew ? chalk2.dim(`${f.lines} lines`) : `${chalk2.green(`+${f.added}`)} ${chalk2.red(`-${f.removed}`)}`;
2308
2493
  lines.push(` ${ptr} ${icon} ${f.relativePath} ${stats}`);
2309
2494
  }
2310
2495
  lines.push("");
2311
- lines.push(chalk.dim(" \u2191\u2193 navigate \u23CE view diff q done"));
2496
+ lines.push(chalk2.dim(" \u2191\u2193 navigate \u23CE view diff q done"));
2312
2497
  return lines.join("\n");
2313
2498
  }
2314
2499
  function renderDiff(index) {
2315
2500
  const f = files[index];
2316
2501
  const lines = [];
2317
- const header = f.isNew ? ` ${chalk.green("+")} ${f.relativePath} ${chalk.dim("(new file)")}` : ` ${chalk.yellow("~")} ${f.relativePath} ${chalk.green(`+${f.added}`)} ${chalk.red(`-${f.removed}`)}`;
2502
+ const header = f.isNew ? ` ${chalk2.green("+")} ${f.relativePath} ${chalk2.dim("(new file)")}` : ` ${chalk2.yellow("~")} ${f.relativePath} ${chalk2.green(`+${f.added}`)} ${chalk2.red(`-${f.removed}`)}`;
2318
2503
  lines.push(header);
2319
- lines.push(chalk.dim(" " + "\u2500".repeat(60)));
2504
+ lines.push(chalk2.dim(" " + "\u2500".repeat(60)));
2320
2505
  const patchLines = f.patch.split("\n");
2321
2506
  const bodyLines = patchLines.slice(4);
2322
2507
  const maxVisible = getTermHeight() - 4;
2323
2508
  const visibleLines = bodyLines.slice(scrollOffset, scrollOffset + maxVisible);
2324
2509
  for (const line of visibleLines) {
2325
2510
  if (line.startsWith("+")) {
2326
- lines.push(chalk.green(" " + line));
2511
+ lines.push(chalk2.green(" " + line));
2327
2512
  } else if (line.startsWith("-")) {
2328
- lines.push(chalk.red(" " + line));
2513
+ lines.push(chalk2.red(" " + line));
2329
2514
  } else if (line.startsWith("@@")) {
2330
- lines.push(chalk.cyan(" " + line));
2515
+ lines.push(chalk2.cyan(" " + line));
2331
2516
  } else {
2332
- lines.push(chalk.dim(" " + line));
2517
+ lines.push(chalk2.dim(" " + line));
2333
2518
  }
2334
2519
  }
2335
2520
  const totalBody = bodyLines.length;
2336
2521
  if (totalBody > maxVisible) {
2337
2522
  const pct = Math.round((scrollOffset + maxVisible) / totalBody * 100);
2338
- lines.push(chalk.dim(` \u2500\u2500 ${Math.min(pct, 100)}% \u2500\u2500`));
2523
+ lines.push(chalk2.dim(` \u2500\u2500 ${Math.min(pct, 100)}% \u2500\u2500`));
2339
2524
  }
2340
2525
  lines.push("");
2341
- lines.push(chalk.dim(" \u2191\u2193 scroll \u23B5/esc back to file list"));
2526
+ lines.push(chalk2.dim(" \u2191\u2193 scroll \u23B5/esc back to file list"));
2342
2527
  return lines.join("\n");
2343
2528
  }
2344
2529
  function draw(initial) {
@@ -2744,7 +2929,7 @@ function getCurrentHeadSha() {
2744
2929
  }
2745
2930
 
2746
2931
  // src/utils/spinner-messages.ts
2747
- import chalk2 from "chalk";
2932
+ import chalk3 from "chalk";
2748
2933
  var GENERATION_MESSAGES = [
2749
2934
  "Analyzing your project structure and dependencies...",
2750
2935
  "Mapping out build commands and test workflows...",
@@ -2794,9 +2979,9 @@ var SpinnerMessages = class {
2794
2979
  this.currentBaseMessage = this.messages[0];
2795
2980
  this.updateSpinnerText();
2796
2981
  if (this.showElapsedTime) {
2797
- this.spinner.suffixText = chalk2.dim(`(${this.formatElapsed()})`);
2982
+ this.spinner.suffixText = chalk3.dim(`(${this.formatElapsed()})`);
2798
2983
  this.elapsedTimer = setInterval(() => {
2799
- this.spinner.suffixText = chalk2.dim(`(${this.formatElapsed()})`);
2984
+ this.spinner.suffixText = chalk3.dim(`(${this.formatElapsed()})`);
2800
2985
  }, 1e3);
2801
2986
  }
2802
2987
  this.timer = setInterval(() => {
@@ -2830,14 +3015,18 @@ var SpinnerMessages = class {
2830
3015
  }
2831
3016
  };
2832
3017
 
3018
+ // src/commands/onboard.ts
3019
+ init_config();
3020
+
2833
3021
  // src/commands/interactive-provider-setup.ts
2834
- import chalk3 from "chalk";
3022
+ init_config();
3023
+ import chalk4 from "chalk";
2835
3024
  import readline2 from "readline";
2836
- import select2 from "@inquirer/select";
3025
+ import select3 from "@inquirer/select";
2837
3026
  function promptInput(question) {
2838
3027
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
2839
3028
  return new Promise((resolve2) => {
2840
- rl.question(chalk3.cyan(`${question} `), (answer) => {
3029
+ rl.question(chalk4.cyan(`${question} `), (answer) => {
2841
3030
  rl.close();
2842
3031
  resolve2(answer.trim());
2843
3032
  });
@@ -2852,7 +3041,7 @@ var PROVIDER_CHOICES = [
2852
3041
  ];
2853
3042
  async function runInteractiveProviderSetup(options) {
2854
3043
  const message = options?.selectMessage ?? "Select LLM provider";
2855
- const provider = await select2({
3044
+ const provider = await select3({
2856
3045
  message,
2857
3046
  choices: PROVIDER_CHOICES
2858
3047
  });
@@ -2860,19 +3049,19 @@ async function runInteractiveProviderSetup(options) {
2860
3049
  switch (provider) {
2861
3050
  case "claude-cli": {
2862
3051
  config.model = "default";
2863
- console.log(chalk3.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
3052
+ console.log(chalk4.dim(" Run `claude` once and log in with your Pro/Max/Team account if you haven't."));
2864
3053
  break;
2865
3054
  }
2866
3055
  case "cursor": {
2867
3056
  config.model = "default";
2868
- console.log(chalk3.dim(" Run `agent login` if you haven't, or set CURSOR_API_KEY."));
3057
+ console.log(chalk4.dim(" Run `agent login` if you haven't, or set CURSOR_API_KEY."));
2869
3058
  break;
2870
3059
  }
2871
3060
  case "anthropic": {
2872
- console.log(chalk3.dim(" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."));
3061
+ console.log(chalk4.dim(" Get a key at https://console.anthropic.com (same account as Claude Pro/Team/Max)."));
2873
3062
  config.apiKey = await promptInput("Anthropic API key:");
2874
3063
  if (!config.apiKey) {
2875
- console.log(chalk3.red("API key is required."));
3064
+ console.log(chalk4.red("API key is required."));
2876
3065
  throw new Error("__exit__");
2877
3066
  }
2878
3067
  config.model = await promptInput(`Model (default: ${DEFAULT_MODELS.anthropic}):`) || DEFAULT_MODELS.anthropic;
@@ -2881,7 +3070,7 @@ async function runInteractiveProviderSetup(options) {
2881
3070
  case "vertex": {
2882
3071
  config.vertexProjectId = await promptInput("GCP Project ID:");
2883
3072
  if (!config.vertexProjectId) {
2884
- console.log(chalk3.red("Project ID is required."));
3073
+ console.log(chalk4.red("Project ID is required."));
2885
3074
  throw new Error("__exit__");
2886
3075
  }
2887
3076
  config.vertexRegion = await promptInput("Region (default: us-east5):") || "us-east5";
@@ -2892,7 +3081,7 @@ async function runInteractiveProviderSetup(options) {
2892
3081
  case "openai": {
2893
3082
  config.apiKey = await promptInput("API key:");
2894
3083
  if (!config.apiKey) {
2895
- console.log(chalk3.red("API key is required."));
3084
+ console.log(chalk4.red("API key is required."));
2896
3085
  throw new Error("__exit__");
2897
3086
  }
2898
3087
  config.baseUrl = await promptInput("Base URL (leave empty for OpenAI, or enter custom endpoint):") || void 0;
@@ -4030,7 +4219,7 @@ function computeLocalScore(dir, targetAgent) {
4030
4219
  }
4031
4220
 
4032
4221
  // src/scoring/display.ts
4033
- import chalk4 from "chalk";
4222
+ import chalk5 from "chalk";
4034
4223
  var AGENT_DISPLAY_NAMES = {
4035
4224
  claude: "Claude Code",
4036
4225
  cursor: "Cursor",
@@ -4048,31 +4237,31 @@ var CATEGORY_ORDER = ["existence", "quality", "coverage", "accuracy", "freshness
4048
4237
  function gradeColor(grade) {
4049
4238
  switch (grade) {
4050
4239
  case "A":
4051
- return chalk4.green;
4240
+ return chalk5.green;
4052
4241
  case "B":
4053
- return chalk4.greenBright;
4242
+ return chalk5.greenBright;
4054
4243
  case "C":
4055
- return chalk4.yellow;
4244
+ return chalk5.yellow;
4056
4245
  case "D":
4057
- return chalk4.hex("#f97316");
4246
+ return chalk5.hex("#f97316");
4058
4247
  case "F":
4059
- return chalk4.red;
4248
+ return chalk5.red;
4060
4249
  default:
4061
- return chalk4.white;
4250
+ return chalk5.white;
4062
4251
  }
4063
4252
  }
4064
4253
  function progressBar(score, max, width = 40) {
4065
4254
  const filled = Math.round(score / max * width);
4066
4255
  const empty = width - filled;
4067
- const bar = chalk4.hex("#f97316")("\u2593".repeat(filled)) + chalk4.gray("\u2591".repeat(empty));
4256
+ const bar = chalk5.hex("#f97316")("\u2593".repeat(filled)) + chalk5.gray("\u2591".repeat(empty));
4068
4257
  return bar;
4069
4258
  }
4070
4259
  function formatCheck(check) {
4071
- const icon = check.passed ? chalk4.green("\u2713") : check.earnedPoints < 0 ? chalk4.red("\u2717") : chalk4.gray("\u2717");
4072
- const points = check.passed ? chalk4.green(`+${check.earnedPoints}`.padStart(4)) : check.earnedPoints < 0 ? chalk4.red(`${check.earnedPoints}`.padStart(4)) : chalk4.gray(" \u2014");
4073
- const name = check.passed ? chalk4.white(check.name) : chalk4.gray(check.name);
4074
- const detail = check.detail ? chalk4.gray(` (${check.detail})`) : "";
4075
- const suggestion = !check.passed && check.suggestion ? chalk4.gray(`
4260
+ const icon = check.passed ? chalk5.green("\u2713") : check.earnedPoints < 0 ? chalk5.red("\u2717") : chalk5.gray("\u2717");
4261
+ const points = check.passed ? chalk5.green(`+${check.earnedPoints}`.padStart(4)) : check.earnedPoints < 0 ? chalk5.red(`${check.earnedPoints}`.padStart(4)) : chalk5.gray(" \u2014");
4262
+ const name = check.passed ? chalk5.white(check.name) : chalk5.gray(check.name);
4263
+ const detail = check.detail ? chalk5.gray(` (${check.detail})`) : "";
4264
+ const suggestion = !check.passed && check.suggestion ? chalk5.gray(`
4076
4265
  \u2192 ${check.suggestion}`) : "";
4077
4266
  return ` ${icon} ${name.padEnd(38)}${points}${detail}${suggestion}`;
4078
4267
  }
@@ -4080,19 +4269,19 @@ function displayScore(result) {
4080
4269
  const gc = gradeColor(result.grade);
4081
4270
  const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
4082
4271
  console.log("");
4083
- console.log(chalk4.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"));
4272
+ console.log(chalk5.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"));
4084
4273
  console.log("");
4085
- console.log(` ${chalk4.bold("Agent Config Score")} ${gc(chalk4.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk4.bold(result.grade))}`);
4274
+ console.log(` ${chalk5.bold("Agent Config Score")} ${gc(chalk5.bold(`${result.score} / ${result.maxScore}`))} Grade ${gc(chalk5.bold(result.grade))}`);
4086
4275
  console.log(` ${progressBar(result.score, result.maxScore)}`);
4087
- console.log(chalk4.dim(` Target: ${agentLabel}`));
4276
+ console.log(chalk5.dim(` Target: ${agentLabel}`));
4088
4277
  console.log("");
4089
- console.log(chalk4.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"));
4278
+ console.log(chalk5.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"));
4090
4279
  console.log("");
4091
4280
  for (const category of CATEGORY_ORDER) {
4092
4281
  const summary = result.categories[category];
4093
4282
  const categoryChecks = result.checks.filter((c) => c.category === category);
4094
4283
  console.log(
4095
- chalk4.gray(` ${CATEGORY_LABELS[category]}`) + chalk4.gray(" ".repeat(Math.max(1, 45 - CATEGORY_LABELS[category].length))) + chalk4.white(`${summary.earned}`) + chalk4.gray(` / ${summary.max}`)
4284
+ chalk5.gray(` ${CATEGORY_LABELS[category]}`) + chalk5.gray(" ".repeat(Math.max(1, 45 - CATEGORY_LABELS[category].length))) + chalk5.white(`${summary.earned}`) + chalk5.gray(` / ${summary.max}`)
4096
4285
  );
4097
4286
  for (const check of categoryChecks) {
4098
4287
  console.log(formatCheck(check));
@@ -4105,48 +4294,48 @@ function displayScoreSummary(result) {
4105
4294
  const agentLabel = result.targetAgent.map((a) => AGENT_DISPLAY_NAMES[a] || a).join(" + ");
4106
4295
  console.log("");
4107
4296
  console.log(
4108
- chalk4.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk4.gray(` (Grade ${result.grade})`) + chalk4.gray(` \xB7 ${agentLabel}`) + chalk4.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
4297
+ chalk5.gray(" ") + gc(`${result.score}/${result.maxScore}`) + chalk5.gray(` (Grade ${result.grade})`) + chalk5.gray(` \xB7 ${agentLabel}`) + chalk5.gray(` \xB7 ${progressBar(result.score, result.maxScore, 20)}`)
4109
4298
  );
4110
4299
  const failing = result.checks.filter((c) => !c.passed);
4111
4300
  if (failing.length > 0) {
4112
4301
  const shown = failing.slice(0, 5);
4113
4302
  for (const check of shown) {
4114
- console.log(chalk4.gray(` \u2717 ${check.name}`));
4303
+ console.log(chalk5.gray(` \u2717 ${check.name}`));
4115
4304
  }
4116
4305
  const remaining = failing.length - shown.length;
4117
4306
  const moreText = remaining > 0 ? ` (+${remaining} more)` : "";
4118
- console.log(chalk4.dim(`
4119
- Run ${chalk4.hex("#83D1EB")("caliber score")} for details.${moreText}`));
4307
+ console.log(chalk5.dim(`
4308
+ Run ${chalk5.hex("#83D1EB")("caliber score")} for details.${moreText}`));
4120
4309
  }
4121
4310
  console.log("");
4122
4311
  }
4123
4312
  function displayScoreDelta(before, after) {
4124
4313
  const delta = after.score - before.score;
4125
4314
  const deltaStr = delta >= 0 ? `+${delta}` : `${delta}`;
4126
- const deltaColor = delta >= 0 ? chalk4.green : chalk4.red;
4315
+ const deltaColor = delta >= 0 ? chalk5.green : chalk5.red;
4127
4316
  const beforeGc = gradeColor(before.grade);
4128
4317
  const afterGc = gradeColor(after.grade);
4129
4318
  console.log("");
4130
- console.log(chalk4.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"));
4319
+ console.log(chalk5.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"));
4131
4320
  console.log("");
4132
4321
  console.log(
4133
- ` Score: ${beforeGc(`${before.score}`)} ${chalk4.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk4.gray("\u2192")} ${afterGc(after.grade)}`
4322
+ ` Score: ${beforeGc(`${before.score}`)} ${chalk5.gray("\u2192")} ${afterGc(`${after.score}`)} ${deltaColor(deltaStr + " pts")} ${beforeGc(before.grade)} ${chalk5.gray("\u2192")} ${afterGc(after.grade)}`
4134
4323
  );
4135
- console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk4.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
4324
+ console.log(` ${progressBar(before.score, before.maxScore, 19)} ${chalk5.gray("\u2192")} ${progressBar(after.score, after.maxScore, 19)}`);
4136
4325
  console.log("");
4137
- console.log(chalk4.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"));
4326
+ console.log(chalk5.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"));
4138
4327
  console.log("");
4139
4328
  const improved = after.checks.filter((ac) => {
4140
4329
  const bc = before.checks.find((b) => b.id === ac.id);
4141
4330
  return bc && ac.earnedPoints > bc.earnedPoints;
4142
4331
  });
4143
4332
  if (improved.length > 0) {
4144
- console.log(chalk4.gray(" What improved:"));
4333
+ console.log(chalk5.gray(" What improved:"));
4145
4334
  for (const check of improved) {
4146
4335
  const bc = before.checks.find((b) => b.id === check.id);
4147
4336
  const gain = check.earnedPoints - bc.earnedPoints;
4148
4337
  console.log(
4149
- chalk4.green(" +") + chalk4.white(` ${check.name.padEnd(50)}`) + chalk4.green(`+${gain}`)
4338
+ chalk5.green(" +") + chalk5.white(` ${check.name.padEnd(50)}`) + chalk5.green(`+${gain}`)
4150
4339
  );
4151
4340
  }
4152
4341
  console.log("");
@@ -4154,9 +4343,9 @@ function displayScoreDelta(before, after) {
4154
4343
  }
4155
4344
 
4156
4345
  // src/commands/recommend.ts
4157
- import chalk5 from "chalk";
4346
+ import chalk6 from "chalk";
4158
4347
  import ora from "ora";
4159
- import select3 from "@inquirer/select";
4348
+ import select4 from "@inquirer/select";
4160
4349
  import { mkdirSync, readFileSync as readFileSync7, readdirSync as readdirSync5, existsSync as existsSync9, writeFileSync } from "fs";
4161
4350
  import { join as join8, dirname as dirname2 } from "path";
4162
4351
 
@@ -4305,6 +4494,7 @@ function hashJson(obj) {
4305
4494
  }
4306
4495
 
4307
4496
  // src/commands/recommend.ts
4497
+ init_config();
4308
4498
  function detectLocalPlatforms() {
4309
4499
  const items = scanLocalState(process.cwd());
4310
4500
  const platforms = /* @__PURE__ */ new Set();
@@ -4604,7 +4794,7 @@ function extractTopDeps() {
4604
4794
  }
4605
4795
  }
4606
4796
  async function recommendCommand() {
4607
- const proceed = await select3({
4797
+ const proceed = await select4({
4608
4798
  message: "Search public repos for relevant skills to add to this project?",
4609
4799
  choices: [
4610
4800
  { name: "Yes, find skills for my project", value: true },
@@ -4612,7 +4802,7 @@ async function recommendCommand() {
4612
4802
  ]
4613
4803
  });
4614
4804
  if (!proceed) {
4615
- console.log(chalk5.dim(" Cancelled.\n"));
4805
+ console.log(chalk6.dim(" Cancelled.\n"));
4616
4806
  return;
4617
4807
  }
4618
4808
  await searchAndInstallSkills();
@@ -4627,7 +4817,7 @@ async function searchAndInstallSkills() {
4627
4817
  ...extractTopDeps()
4628
4818
  ].filter(Boolean))];
4629
4819
  if (technologies.length === 0) {
4630
- console.log(chalk5.yellow("Could not detect any languages or dependencies. Try running from a project root."));
4820
+ console.log(chalk6.yellow("Could not detect any languages or dependencies. Try running from a project root."));
4631
4821
  throw new Error("__exit__");
4632
4822
  }
4633
4823
  const primaryPlatform = platforms.includes("claude") ? "claude" : platforms[0];
@@ -4644,7 +4834,7 @@ async function searchAndInstallSkills() {
4644
4834
  return;
4645
4835
  }
4646
4836
  searchSpinner.succeed(
4647
- `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk5.dim(` (${filteredCount} already installed)`) : "")
4837
+ `Found ${allCandidates.length} skills` + (filteredCount > 0 ? chalk6.dim(` (${filteredCount} already installed)`) : "")
4648
4838
  );
4649
4839
  let results;
4650
4840
  const config = loadConfig();
@@ -4678,7 +4868,7 @@ async function searchAndInstallSkills() {
4678
4868
  }
4679
4869
  const unavailableCount = results.length - available.length;
4680
4870
  fetchSpinner.succeed(
4681
- `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk5.dim(` (${unavailableCount} unavailable)`) : "")
4871
+ `${available.length} installable skill${available.length > 1 ? "s" : ""}` + (unavailableCount > 0 ? chalk6.dim(` (${unavailableCount} unavailable)`) : "")
4682
4872
  );
4683
4873
  const selected = await interactiveSelect(available);
4684
4874
  if (selected?.length) {
@@ -4701,30 +4891,30 @@ async function interactiveSelect(recs) {
4701
4891
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
4702
4892
  const prefixWidth = 8;
4703
4893
  const scoreWidth = 6;
4704
- lines.push(chalk5.bold(" Skills"));
4894
+ lines.push(chalk6.bold(" Skills"));
4705
4895
  lines.push("");
4706
4896
  if (hasScores) {
4707
- const header = " ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why");
4897
+ const header = " ".repeat(prefixWidth) + chalk6.dim("Score".padEnd(scoreWidth)) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Why");
4708
4898
  lines.push(header);
4709
4899
  } else {
4710
- const header = " ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source");
4900
+ const header = " ".repeat(prefixWidth) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Technology".padEnd(18)) + chalk6.dim("Source");
4711
4901
  lines.push(header);
4712
4902
  }
4713
- lines.push(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
4903
+ lines.push(chalk6.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
4714
4904
  for (let i = 0; i < recs.length; i++) {
4715
4905
  const rec = recs[i];
4716
- const check = selected.has(i) ? chalk5.green("[x]") : "[ ]";
4717
- const ptr = i === cursor ? chalk5.cyan(">") : " ";
4906
+ const check = selected.has(i) ? chalk6.green("[x]") : "[ ]";
4907
+ const ptr = i === cursor ? chalk6.cyan(">") : " ";
4718
4908
  if (hasScores) {
4719
- const scoreColor = rec.score >= 90 ? chalk5.green : rec.score >= 70 ? chalk5.yellow : chalk5.dim;
4909
+ const scoreColor = rec.score >= 90 ? chalk6.green : rec.score >= 70 ? chalk6.yellow : chalk6.dim;
4720
4910
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
4721
- lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`);
4911
+ lines.push(` ${ptr} ${check} ${scoreColor(String(rec.score).padStart(3))} ${rec.name.padEnd(nameWidth)}${chalk6.dim(rec.reason.slice(0, reasonMax))}`);
4722
4912
  } else {
4723
- lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`);
4913
+ lines.push(` ${ptr} ${check} ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk6.dim(rec.source_url || "")}`);
4724
4914
  }
4725
4915
  }
4726
4916
  lines.push("");
4727
- lines.push(chalk5.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
4917
+ lines.push(chalk6.dim(" \u2191\u2193 navigate \u23B5 toggle a all n none \u23CE install q cancel"));
4728
4918
  return lines.join("\n");
4729
4919
  }
4730
4920
  function draw(initial) {
@@ -4773,7 +4963,7 @@ async function interactiveSelect(recs) {
4773
4963
  case "\n":
4774
4964
  cleanup();
4775
4965
  if (selected.size === 0) {
4776
- console.log(chalk5.dim("\n No skills selected.\n"));
4966
+ console.log(chalk6.dim("\n No skills selected.\n"));
4777
4967
  resolve2(null);
4778
4968
  } else {
4779
4969
  resolve2(Array.from(selected).sort().map((i) => recs[i]));
@@ -4783,7 +4973,7 @@ async function interactiveSelect(recs) {
4783
4973
  case "\x1B":
4784
4974
  case "":
4785
4975
  cleanup();
4786
- console.log(chalk5.dim("\n Cancelled.\n"));
4976
+ console.log(chalk6.dim("\n Cancelled.\n"));
4787
4977
  resolve2(null);
4788
4978
  break;
4789
4979
  }
@@ -4846,7 +5036,7 @@ async function installSkills(recs, platforms, contentMap) {
4846
5036
  if (installed.length > 0) {
4847
5037
  spinner.succeed(`Installed ${installed.length} file${installed.length > 1 ? "s" : ""}`);
4848
5038
  for (const p of installed) {
4849
- console.log(chalk5.green(` \u2713 ${p}`));
5039
+ console.log(chalk6.green(` \u2713 ${p}`));
4850
5040
  }
4851
5041
  } else {
4852
5042
  spinner.fail("No skills were installed");
@@ -4859,19 +5049,19 @@ function printSkills(recs) {
4859
5049
  const nameWidth = Math.max(...recs.map((r) => r.name.length), 4) + 2;
4860
5050
  const scoreWidth = 6;
4861
5051
  const prefixWidth = 2;
4862
- console.log(chalk5.bold("\n Skills\n"));
5052
+ console.log(chalk6.bold("\n Skills\n"));
4863
5053
  if (hasScores) {
4864
- console.log(" ".repeat(prefixWidth) + chalk5.dim("Score".padEnd(scoreWidth)) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Why"));
5054
+ console.log(" ".repeat(prefixWidth) + chalk6.dim("Score".padEnd(scoreWidth)) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Why"));
4865
5055
  } else {
4866
- console.log(" ".repeat(prefixWidth) + chalk5.dim("Name".padEnd(nameWidth)) + chalk5.dim("Technology".padEnd(18)) + chalk5.dim("Source"));
5056
+ console.log(" ".repeat(prefixWidth) + chalk6.dim("Name".padEnd(nameWidth)) + chalk6.dim("Technology".padEnd(18)) + chalk6.dim("Source"));
4867
5057
  }
4868
- console.log(chalk5.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
5058
+ console.log(chalk6.dim(" " + "\u2500".repeat(Math.min(cols - 4, 90))));
4869
5059
  for (const rec of recs) {
4870
5060
  if (hasScores) {
4871
5061
  const reasonMax = Math.max(cols - prefixWidth - scoreWidth - nameWidth - 2, 20);
4872
- console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk5.dim(rec.reason.slice(0, reasonMax))}`);
5062
+ console.log(` ${String(rec.score).padStart(3)} ${rec.name.padEnd(nameWidth)}${chalk6.dim(rec.reason.slice(0, reasonMax))}`);
4873
5063
  } else {
4874
- console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk5.dim(rec.source_url || "")}`);
5064
+ console.log(` ${rec.name.padEnd(nameWidth)}${rec.detected_technology.padEnd(16)} ${chalk6.dim(rec.source_url || "")}`);
4875
5065
  }
4876
5066
  }
4877
5067
  console.log("");
@@ -4879,8 +5069,8 @@ function printSkills(recs) {
4879
5069
 
4880
5070
  // src/commands/onboard.ts
4881
5071
  async function initCommand(options) {
4882
- const brand = chalk6.hex("#EB9D83");
4883
- const title = chalk6.hex("#83D1EB");
5072
+ const brand = chalk7.hex("#EB9D83");
5073
+ const title = chalk7.hex("#83D1EB");
4884
5074
  console.log(brand.bold(`
4885
5075
  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
4886
5076
  \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
@@ -4889,21 +5079,21 @@ async function initCommand(options) {
4889
5079
  \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
4890
5080
  \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
4891
5081
  `));
4892
- console.log(chalk6.dim(" Onboard your project for AI-assisted development\n"));
5082
+ console.log(chalk7.dim(" Onboard your project for AI-assisted development\n"));
4893
5083
  console.log(title.bold(" Welcome to Caliber\n"));
4894
- console.log(chalk6.dim(" Caliber analyzes your codebase and creates tailored config files"));
4895
- console.log(chalk6.dim(" so your AI coding agents understand your project from day one.\n"));
5084
+ console.log(chalk7.dim(" Caliber analyzes your codebase and creates tailored config files"));
5085
+ console.log(chalk7.dim(" so your AI coding agents understand your project from day one.\n"));
4896
5086
  console.log(title.bold(" How onboarding works:\n"));
4897
- console.log(chalk6.dim(" 1. Connect Set up your LLM provider"));
4898
- console.log(chalk6.dim(" 2. Discover Analyze your code, dependencies, and structure"));
4899
- console.log(chalk6.dim(" 3. Generate Create config files tailored to your project"));
4900
- console.log(chalk6.dim(" 4. Review Preview, refine, and apply the changes"));
4901
- console.log(chalk6.dim(" 5. Enhance Discover MCP servers for your tools"));
4902
- console.log(chalk6.dim(" 6. Skills Browse community skills for your stack\n"));
5087
+ console.log(chalk7.dim(" 1. Connect Set up your LLM provider"));
5088
+ console.log(chalk7.dim(" 2. Discover Analyze your code, dependencies, and structure"));
5089
+ console.log(chalk7.dim(" 3. Generate Create config files tailored to your project"));
5090
+ console.log(chalk7.dim(" 4. Review Preview, refine, and apply the changes"));
5091
+ console.log(chalk7.dim(" 5. Enhance Discover MCP servers for your tools"));
5092
+ console.log(chalk7.dim(" 6. Skills Browse community skills for your stack\n"));
4903
5093
  console.log(title.bold(" Step 1/6 \u2014 Connect your LLM\n"));
4904
5094
  let config = loadConfig();
4905
5095
  if (!config) {
4906
- console.log(chalk6.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
5096
+ console.log(chalk7.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
4907
5097
  try {
4908
5098
  await runInteractiveProviderSetup({
4909
5099
  selectMessage: "How do you want to use Caliber? (choose LLM provider)"
@@ -4914,22 +5104,23 @@ async function initCommand(options) {
4914
5104
  }
4915
5105
  config = loadConfig();
4916
5106
  if (!config) {
4917
- console.log(chalk6.red(" Setup was cancelled or failed.\n"));
5107
+ console.log(chalk7.red(" Setup was cancelled or failed.\n"));
4918
5108
  throw new Error("__exit__");
4919
5109
  }
4920
- console.log(chalk6.green(" \u2713 Provider saved. Let's continue.\n"));
5110
+ console.log(chalk7.green(" \u2713 Provider saved. Let's continue.\n"));
4921
5111
  }
4922
5112
  const displayModel = config.model === "default" && config.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : config.model;
4923
5113
  const fastModel = getFastModel();
4924
5114
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
4925
- console.log(chalk6.dim(modelLine + "\n"));
5115
+ console.log(chalk7.dim(modelLine + "\n"));
5116
+ await validateModel({ fast: true });
4926
5117
  console.log(title.bold(" Step 2/6 \u2014 Discover your project\n"));
4927
- console.log(chalk6.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
5118
+ console.log(chalk7.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
4928
5119
  const spinner = ora2("Analyzing project...").start();
4929
5120
  const fingerprint = await collectFingerprint(process.cwd());
4930
5121
  spinner.succeed("Project analyzed");
4931
- console.log(chalk6.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
4932
- console.log(chalk6.dim(` Files: ${fingerprint.fileTree.length} found
5122
+ console.log(chalk7.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
5123
+ console.log(chalk7.dim(` Files: ${fingerprint.fileTree.length} found
4933
5124
  `));
4934
5125
  const targetAgent = options.agent || await promptAgent();
4935
5126
  const preScore = computeLocalScore(process.cwd(), targetAgent);
@@ -4948,23 +5139,23 @@ async function initCommand(options) {
4948
5139
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length || fingerprint.existingConfigs.agentsMd);
4949
5140
  const NON_LLM_CHECKS = /* @__PURE__ */ new Set(["hooks_configured", "agents_md_exists", "permissions_configured", "mcp_servers"]);
4950
5141
  if (hasExistingConfig && baselineScore.score === 100) {
4951
- console.log(chalk6.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
4952
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to regenerate anyway.\n"));
5142
+ console.log(chalk7.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
5143
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to regenerate anyway.\n"));
4953
5144
  if (!options.force) return;
4954
5145
  }
4955
5146
  const allFailingChecks = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
4956
5147
  const llmFixableChecks = allFailingChecks.filter((c) => !NON_LLM_CHECKS.has(c.id));
4957
5148
  if (hasExistingConfig && llmFixableChecks.length === 0 && allFailingChecks.length > 0 && !options.force) {
4958
- console.log(chalk6.bold.green("\n Your config is fully optimized for LLM generation.\n"));
4959
- console.log(chalk6.dim(" Remaining items need CLI actions:\n"));
5149
+ console.log(chalk7.bold.green("\n Your config is fully optimized for LLM generation.\n"));
5150
+ console.log(chalk7.dim(" Remaining items need CLI actions:\n"));
4960
5151
  for (const check of allFailingChecks) {
4961
- console.log(chalk6.dim(` \u2022 ${check.name}`));
5152
+ console.log(chalk7.dim(` \u2022 ${check.name}`));
4962
5153
  if (check.suggestion) {
4963
- console.log(` ${chalk6.hex("#83D1EB")(check.suggestion)}`);
5154
+ console.log(` ${chalk7.hex("#83D1EB")(check.suggestion)}`);
4964
5155
  }
4965
5156
  }
4966
5157
  console.log("");
4967
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to regenerate anyway.\n"));
5158
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to regenerate anyway.\n"));
4968
5159
  return;
4969
5160
  }
4970
5161
  const isEmpty = fingerprint.fileTree.length < 3;
@@ -4980,22 +5171,22 @@ async function initCommand(options) {
4980
5171
  currentScore = baselineScore.score;
4981
5172
  if (failingChecks.length > 0) {
4982
5173
  console.log(title.bold(" Step 3/6 \u2014 Fine-tuning\n"));
4983
- console.log(chalk6.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
5174
+ console.log(chalk7.dim(` Your setup scores ${baselineScore.score}/100 \u2014 fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
4984
5175
  `));
4985
5176
  for (const check of failingChecks) {
4986
- console.log(chalk6.dim(` \u2022 ${check.name}`));
5177
+ console.log(chalk7.dim(` \u2022 ${check.name}`));
4987
5178
  }
4988
5179
  console.log("");
4989
5180
  }
4990
5181
  } else if (hasExistingConfig) {
4991
5182
  console.log(title.bold(" Step 3/6 \u2014 Improve your setup\n"));
4992
- console.log(chalk6.dim(" Reviewing your existing configs against your codebase"));
4993
- console.log(chalk6.dim(" and preparing improvements.\n"));
5183
+ console.log(chalk7.dim(" Reviewing your existing configs against your codebase"));
5184
+ console.log(chalk7.dim(" and preparing improvements.\n"));
4994
5185
  } else {
4995
5186
  console.log(title.bold(" Step 3/6 \u2014 Build your agent setup\n"));
4996
- console.log(chalk6.dim(" Creating config files tailored to your project.\n"));
5187
+ console.log(chalk7.dim(" Creating config files tailored to your project.\n"));
4997
5188
  }
4998
- console.log(chalk6.dim(" This can take a couple of minutes depending on your model and provider.\n"));
5189
+ console.log(chalk7.dim(" This can take a couple of minutes depending on your model and provider.\n"));
4999
5190
  const genStartTime = Date.now();
5000
5191
  const genSpinner = ora2("Generating setup...").start();
5001
5192
  const genMessages = new SpinnerMessages(genSpinner, GENERATION_MESSAGES, { showElapsedTime: true });
@@ -5037,8 +5228,8 @@ async function initCommand(options) {
5037
5228
  if (!generatedSetup) {
5038
5229
  genSpinner.fail("Failed to generate setup.");
5039
5230
  if (rawOutput) {
5040
- console.log(chalk6.dim("\nRaw LLM output (JSON parse failed):"));
5041
- console.log(chalk6.dim(rawOutput.slice(0, 500)));
5231
+ console.log(chalk7.dim("\nRaw LLM output (JSON parse failed):"));
5232
+ console.log(chalk7.dim(rawOutput.slice(0, 500)));
5042
5233
  }
5043
5234
  throw new Error("__exit__");
5044
5235
  }
@@ -5046,7 +5237,7 @@ async function initCommand(options) {
5046
5237
  const mins = Math.floor(elapsedMs / 6e4);
5047
5238
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
5048
5239
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
5049
- genSpinner.succeed(`Setup generated ${chalk6.dim(`in ${timeStr}`)}`);
5240
+ genSpinner.succeed(`Setup generated ${chalk7.dim(`in ${timeStr}`)}`);
5050
5241
  printSetupSummary(generatedSetup);
5051
5242
  const sessionHistory = [];
5052
5243
  sessionHistory.push({
@@ -5057,11 +5248,11 @@ async function initCommand(options) {
5057
5248
  const setupFiles = collectSetupFiles(generatedSetup);
5058
5249
  const staged = stageFiles(setupFiles, process.cwd());
5059
5250
  const totalChanges = staged.newFiles + staged.modifiedFiles;
5060
- console.log(chalk6.dim(` ${chalk6.green(`${staged.newFiles} new`)} / ${chalk6.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5251
+ console.log(chalk7.dim(` ${chalk7.green(`${staged.newFiles} new`)} / ${chalk7.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5061
5252
  `));
5062
5253
  let action;
5063
5254
  if (totalChanges === 0) {
5064
- console.log(chalk6.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5255
+ console.log(chalk7.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5065
5256
  cleanupStaging();
5066
5257
  action = "accept";
5067
5258
  } else {
@@ -5076,12 +5267,12 @@ async function initCommand(options) {
5076
5267
  generatedSetup = await refineLoop(generatedSetup, targetAgent, sessionHistory);
5077
5268
  if (!generatedSetup) {
5078
5269
  cleanupStaging();
5079
- console.log(chalk6.dim("Refinement cancelled. No files were modified."));
5270
+ console.log(chalk7.dim("Refinement cancelled. No files were modified."));
5080
5271
  return;
5081
5272
  }
5082
5273
  const updatedFiles = collectSetupFiles(generatedSetup);
5083
5274
  const restaged = stageFiles(updatedFiles, process.cwd());
5084
- console.log(chalk6.dim(` ${chalk6.green(`${restaged.newFiles} new`)} / ${chalk6.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
5275
+ console.log(chalk7.dim(` ${chalk7.green(`${restaged.newFiles} new`)} / ${chalk7.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
5085
5276
  `));
5086
5277
  printSetupSummary(generatedSetup);
5087
5278
  await openReview("terminal", restaged.stagedFiles);
@@ -5089,11 +5280,11 @@ async function initCommand(options) {
5089
5280
  }
5090
5281
  cleanupStaging();
5091
5282
  if (action === "decline") {
5092
- console.log(chalk6.dim("Setup declined. No files were modified."));
5283
+ console.log(chalk7.dim("Setup declined. No files were modified."));
5093
5284
  return;
5094
5285
  }
5095
5286
  if (options.dryRun) {
5096
- console.log(chalk6.yellow("\n[Dry run] Would write the following files:"));
5287
+ console.log(chalk7.yellow("\n[Dry run] Would write the following files:"));
5097
5288
  console.log(JSON.stringify(generatedSetup, null, 2));
5098
5289
  return;
5099
5290
  }
@@ -5101,23 +5292,23 @@ async function initCommand(options) {
5101
5292
  try {
5102
5293
  const result = writeSetup(generatedSetup);
5103
5294
  writeSpinner.succeed("Config files written");
5104
- console.log(chalk6.bold("\nFiles created/updated:"));
5295
+ console.log(chalk7.bold("\nFiles created/updated:"));
5105
5296
  for (const file of result.written) {
5106
- console.log(` ${chalk6.green("\u2713")} ${file}`);
5297
+ console.log(` ${chalk7.green("\u2713")} ${file}`);
5107
5298
  }
5108
5299
  if (result.deleted.length > 0) {
5109
- console.log(chalk6.bold("\nFiles removed:"));
5300
+ console.log(chalk7.bold("\nFiles removed:"));
5110
5301
  for (const file of result.deleted) {
5111
- console.log(` ${chalk6.red("\u2717")} ${file}`);
5302
+ console.log(` ${chalk7.red("\u2717")} ${file}`);
5112
5303
  }
5113
5304
  }
5114
5305
  if (result.backupDir) {
5115
- console.log(chalk6.dim(`
5306
+ console.log(chalk7.dim(`
5116
5307
  Backups saved to ${result.backupDir}`));
5117
5308
  }
5118
5309
  } catch (err) {
5119
5310
  writeSpinner.fail("Failed to write files");
5120
- console.error(chalk6.red(err instanceof Error ? err.message : "Unknown error"));
5311
+ console.error(chalk7.red(err instanceof Error ? err.message : "Unknown error"));
5121
5312
  throw new Error("__exit__");
5122
5313
  }
5123
5314
  ensurePermissions();
@@ -5129,56 +5320,56 @@ async function initCommand(options) {
5129
5320
  });
5130
5321
  console.log("");
5131
5322
  console.log(title.bold(" Keep your configs fresh\n"));
5132
- console.log(chalk6.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
5323
+ console.log(chalk7.dim(" Caliber can automatically update your agent configs when your code changes.\n"));
5133
5324
  const hookChoice = await promptHookType(targetAgent);
5134
5325
  if (hookChoice === "claude" || hookChoice === "both") {
5135
5326
  const hookResult = installHook();
5136
5327
  if (hookResult.installed) {
5137
- console.log(` ${chalk6.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
5138
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber hooks --remove") + chalk6.dim(" to disable"));
5328
+ console.log(` ${chalk7.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
5329
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber hooks --remove") + chalk7.dim(" to disable"));
5139
5330
  } else if (hookResult.alreadyInstalled) {
5140
- console.log(chalk6.dim(" Claude Code hook already installed"));
5331
+ console.log(chalk7.dim(" Claude Code hook already installed"));
5141
5332
  }
5142
5333
  const learnResult = installLearningHooks();
5143
5334
  if (learnResult.installed) {
5144
- console.log(` ${chalk6.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
5145
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber learn remove") + chalk6.dim(" to disable"));
5335
+ console.log(` ${chalk7.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
5336
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber learn remove") + chalk7.dim(" to disable"));
5146
5337
  } else if (learnResult.alreadyInstalled) {
5147
- console.log(chalk6.dim(" Learning hooks already installed"));
5338
+ console.log(chalk7.dim(" Learning hooks already installed"));
5148
5339
  }
5149
5340
  }
5150
5341
  if (hookChoice === "precommit" || hookChoice === "both") {
5151
5342
  const precommitResult = installPreCommitHook();
5152
5343
  if (precommitResult.installed) {
5153
- console.log(` ${chalk6.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
5154
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber hooks --remove") + chalk6.dim(" to disable"));
5344
+ console.log(` ${chalk7.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
5345
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber hooks --remove") + chalk7.dim(" to disable"));
5155
5346
  } else if (precommitResult.alreadyInstalled) {
5156
- console.log(chalk6.dim(" Pre-commit hook already installed"));
5347
+ console.log(chalk7.dim(" Pre-commit hook already installed"));
5157
5348
  } else {
5158
- console.log(chalk6.yellow(" Could not install pre-commit hook (not a git repository?)"));
5349
+ console.log(chalk7.yellow(" Could not install pre-commit hook (not a git repository?)"));
5159
5350
  }
5160
5351
  }
5161
5352
  if (hookChoice === "skip") {
5162
- console.log(chalk6.dim(" Skipped auto-refresh hooks. Run ") + chalk6.hex("#83D1EB")("caliber hooks --install") + chalk6.dim(" later to enable."));
5353
+ console.log(chalk7.dim(" Skipped auto-refresh hooks. Run ") + chalk7.hex("#83D1EB")("caliber hooks --install") + chalk7.dim(" later to enable."));
5163
5354
  }
5164
5355
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
5165
5356
  if (afterScore.score < baselineScore.score) {
5166
5357
  console.log("");
5167
- console.log(chalk6.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5358
+ console.log(chalk7.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5168
5359
  try {
5169
5360
  const { restored, removed } = undoSetup();
5170
5361
  if (restored.length > 0 || removed.length > 0) {
5171
- console.log(chalk6.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5362
+ console.log(chalk7.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5172
5363
  }
5173
5364
  } catch {
5174
5365
  }
5175
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber onboard --force") + chalk6.dim(" to override.\n"));
5366
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber onboard --force") + chalk7.dim(" to override.\n"));
5176
5367
  return;
5177
5368
  }
5178
5369
  displayScoreDelta(baselineScore, afterScore);
5179
5370
  console.log(title.bold("\n Step 6/6 \u2014 Community skills\n"));
5180
- console.log(chalk6.dim(" Search public skill registries for skills that match your tech stack.\n"));
5181
- const wantsSkills = await select4({
5371
+ console.log(chalk7.dim(" Search public skill registries for skills that match your tech stack.\n"));
5372
+ const wantsSkills = await select5({
5182
5373
  message: "Search public repos for relevant skills to add to this project?",
5183
5374
  choices: [
5184
5375
  { name: "Yes, find skills for my project", value: true },
@@ -5190,16 +5381,16 @@ async function initCommand(options) {
5190
5381
  await searchAndInstallSkills();
5191
5382
  } catch (err) {
5192
5383
  if (err.message !== "__exit__") {
5193
- console.log(chalk6.dim(" Skills search failed: " + (err.message || "unknown error")));
5384
+ console.log(chalk7.dim(" Skills search failed: " + (err.message || "unknown error")));
5194
5385
  }
5195
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber skills") + chalk6.dim(" later to try again.\n"));
5386
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber skills") + chalk7.dim(" later to try again.\n"));
5196
5387
  }
5197
5388
  } else {
5198
- console.log(chalk6.dim(" Skipped. Run ") + chalk6.hex("#83D1EB")("caliber skills") + chalk6.dim(" later to browse.\n"));
5389
+ console.log(chalk7.dim(" Skipped. Run ") + chalk7.hex("#83D1EB")("caliber skills") + chalk7.dim(" later to browse.\n"));
5199
5390
  }
5200
- console.log(chalk6.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
5201
- console.log(chalk6.dim(" Run ") + chalk6.hex("#83D1EB")("caliber undo") + chalk6.dim(" to revert changes.\n"));
5202
- console.log(chalk6.bold(" Next steps:\n"));
5391
+ console.log(chalk7.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
5392
+ console.log(chalk7.dim(" Run ") + chalk7.hex("#83D1EB")("caliber undo") + chalk7.dim(" to revert changes.\n"));
5393
+ console.log(chalk7.bold(" Next steps:\n"));
5203
5394
  console.log(` ${title("caliber score")} See your full config breakdown`);
5204
5395
  console.log(` ${title("caliber skills")} Discover community skills for your stack`);
5205
5396
  console.log(` ${title("caliber undo")} Revert all changes from this run`);
@@ -5216,9 +5407,9 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5216
5407
  }
5217
5408
  const isValid = await classifyRefineIntent(message);
5218
5409
  if (!isValid) {
5219
- console.log(chalk6.dim(" This doesn't look like a config change request."));
5220
- console.log(chalk6.dim(" Describe what to add, remove, or modify in your configs."));
5221
- console.log(chalk6.dim(' Type "done" to accept the current setup.\n'));
5410
+ console.log(chalk7.dim(" This doesn't look like a config change request."));
5411
+ console.log(chalk7.dim(" Describe what to add, remove, or modify in your configs."));
5412
+ console.log(chalk7.dim(' Type "done" to accept the current setup.\n'));
5222
5413
  continue;
5223
5414
  }
5224
5415
  const refineSpinner = ora2("Refining setup...").start();
@@ -5239,10 +5430,10 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5239
5430
  });
5240
5431
  refineSpinner.succeed("Setup updated");
5241
5432
  printSetupSummary(refined);
5242
- console.log(chalk6.dim('Type "done" to accept, or describe more changes.'));
5433
+ console.log(chalk7.dim('Type "done" to accept, or describe more changes.'));
5243
5434
  } else {
5244
5435
  refineSpinner.fail("Refinement failed \u2014 could not parse AI response.");
5245
- console.log(chalk6.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
5436
+ console.log(chalk7.dim('Try rephrasing your request, or type "done" to keep the current setup.'));
5246
5437
  }
5247
5438
  }
5248
5439
  }
@@ -5302,7 +5493,7 @@ ${JSON.stringify(checkList, null, 2)}`,
5302
5493
  function promptInput2(question) {
5303
5494
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
5304
5495
  return new Promise((resolve2) => {
5305
- rl.question(chalk6.cyan(`${question} `), (answer) => {
5496
+ rl.question(chalk7.cyan(`${question} `), (answer) => {
5306
5497
  rl.close();
5307
5498
  resolve2(answer.trim());
5308
5499
  });
@@ -5334,13 +5525,13 @@ async function promptHookType(targetAgent) {
5334
5525
  choices.push({ name: "Both (Claude Code + pre-commit)", value: "both" });
5335
5526
  }
5336
5527
  choices.push({ name: "Skip for now", value: "skip" });
5337
- return select4({
5528
+ return select5({
5338
5529
  message: "How would you like to auto-refresh your docs?",
5339
5530
  choices
5340
5531
  });
5341
5532
  }
5342
5533
  async function promptReviewAction() {
5343
- return select4({
5534
+ return select5({
5344
5535
  message: "What would you like to do?",
5345
5536
  choices: [
5346
5537
  { name: "Accept and apply", value: "accept" },
@@ -5355,26 +5546,26 @@ function printSetupSummary(setup) {
5355
5546
  const fileDescriptions = setup.fileDescriptions;
5356
5547
  const deletions = setup.deletions;
5357
5548
  console.log("");
5358
- console.log(chalk6.bold(" Proposed changes:\n"));
5549
+ console.log(chalk7.bold(" Proposed changes:\n"));
5359
5550
  const getDescription = (filePath) => {
5360
5551
  return fileDescriptions?.[filePath];
5361
5552
  };
5362
5553
  if (claude) {
5363
5554
  if (claude.claudeMd) {
5364
- const icon = fs21.existsSync("CLAUDE.md") ? chalk6.yellow("~") : chalk6.green("+");
5555
+ const icon = fs21.existsSync("CLAUDE.md") ? chalk7.yellow("~") : chalk7.green("+");
5365
5556
  const desc = getDescription("CLAUDE.md");
5366
- console.log(` ${icon} ${chalk6.bold("CLAUDE.md")}`);
5367
- if (desc) console.log(chalk6.dim(` ${desc}`));
5557
+ console.log(` ${icon} ${chalk7.bold("CLAUDE.md")}`);
5558
+ if (desc) console.log(chalk7.dim(` ${desc}`));
5368
5559
  console.log("");
5369
5560
  }
5370
5561
  const skills = claude.skills;
5371
5562
  if (Array.isArray(skills) && skills.length > 0) {
5372
5563
  for (const skill of skills) {
5373
5564
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
5374
- const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5565
+ const icon = fs21.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5375
5566
  const desc = getDescription(skillPath);
5376
- console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5377
- console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5567
+ console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5568
+ console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5378
5569
  console.log("");
5379
5570
  }
5380
5571
  }
@@ -5382,40 +5573,40 @@ function printSetupSummary(setup) {
5382
5573
  const codex = setup.codex;
5383
5574
  if (codex) {
5384
5575
  if (codex.agentsMd) {
5385
- const icon = fs21.existsSync("AGENTS.md") ? chalk6.yellow("~") : chalk6.green("+");
5576
+ const icon = fs21.existsSync("AGENTS.md") ? chalk7.yellow("~") : chalk7.green("+");
5386
5577
  const desc = getDescription("AGENTS.md");
5387
- console.log(` ${icon} ${chalk6.bold("AGENTS.md")}`);
5388
- if (desc) console.log(chalk6.dim(` ${desc}`));
5578
+ console.log(` ${icon} ${chalk7.bold("AGENTS.md")}`);
5579
+ if (desc) console.log(chalk7.dim(` ${desc}`));
5389
5580
  console.log("");
5390
5581
  }
5391
5582
  const codexSkills = codex.skills;
5392
5583
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
5393
5584
  for (const skill of codexSkills) {
5394
5585
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
5395
- const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5586
+ const icon = fs21.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5396
5587
  const desc = getDescription(skillPath);
5397
- console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5398
- console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5588
+ console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5589
+ console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5399
5590
  console.log("");
5400
5591
  }
5401
5592
  }
5402
5593
  }
5403
5594
  if (cursor) {
5404
5595
  if (cursor.cursorrules) {
5405
- const icon = fs21.existsSync(".cursorrules") ? chalk6.yellow("~") : chalk6.green("+");
5596
+ const icon = fs21.existsSync(".cursorrules") ? chalk7.yellow("~") : chalk7.green("+");
5406
5597
  const desc = getDescription(".cursorrules");
5407
- console.log(` ${icon} ${chalk6.bold(".cursorrules")}`);
5408
- if (desc) console.log(chalk6.dim(` ${desc}`));
5598
+ console.log(` ${icon} ${chalk7.bold(".cursorrules")}`);
5599
+ if (desc) console.log(chalk7.dim(` ${desc}`));
5409
5600
  console.log("");
5410
5601
  }
5411
5602
  const cursorSkills = cursor.skills;
5412
5603
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
5413
5604
  for (const skill of cursorSkills) {
5414
5605
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
5415
- const icon = fs21.existsSync(skillPath) ? chalk6.yellow("~") : chalk6.green("+");
5606
+ const icon = fs21.existsSync(skillPath) ? chalk7.yellow("~") : chalk7.green("+");
5416
5607
  const desc = getDescription(skillPath);
5417
- console.log(` ${icon} ${chalk6.bold(skillPath)}`);
5418
- console.log(chalk6.dim(` ${desc || skill.description || skill.name}`));
5608
+ console.log(` ${icon} ${chalk7.bold(skillPath)}`);
5609
+ console.log(chalk7.dim(` ${desc || skill.description || skill.name}`));
5419
5610
  console.log("");
5420
5611
  }
5421
5612
  }
@@ -5423,32 +5614,32 @@ function printSetupSummary(setup) {
5423
5614
  if (Array.isArray(rules) && rules.length > 0) {
5424
5615
  for (const rule of rules) {
5425
5616
  const rulePath = `.cursor/rules/${rule.filename}`;
5426
- const icon = fs21.existsSync(rulePath) ? chalk6.yellow("~") : chalk6.green("+");
5617
+ const icon = fs21.existsSync(rulePath) ? chalk7.yellow("~") : chalk7.green("+");
5427
5618
  const desc = getDescription(rulePath);
5428
- console.log(` ${icon} ${chalk6.bold(rulePath)}`);
5619
+ console.log(` ${icon} ${chalk7.bold(rulePath)}`);
5429
5620
  if (desc) {
5430
- console.log(chalk6.dim(` ${desc}`));
5621
+ console.log(chalk7.dim(` ${desc}`));
5431
5622
  } else {
5432
5623
  const firstLine = rule.content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("#"))[0];
5433
- if (firstLine) console.log(chalk6.dim(` ${firstLine.trim().slice(0, 80)}`));
5624
+ if (firstLine) console.log(chalk7.dim(` ${firstLine.trim().slice(0, 80)}`));
5434
5625
  }
5435
5626
  console.log("");
5436
5627
  }
5437
5628
  }
5438
5629
  }
5439
5630
  if (!codex && !fs21.existsSync("AGENTS.md")) {
5440
- console.log(` ${chalk6.green("+")} ${chalk6.bold("AGENTS.md")}`);
5441
- console.log(chalk6.dim(" Cross-agent coordination file"));
5631
+ console.log(` ${chalk7.green("+")} ${chalk7.bold("AGENTS.md")}`);
5632
+ console.log(chalk7.dim(" Cross-agent coordination file"));
5442
5633
  console.log("");
5443
5634
  }
5444
5635
  if (Array.isArray(deletions) && deletions.length > 0) {
5445
5636
  for (const del of deletions) {
5446
- console.log(` ${chalk6.red("-")} ${chalk6.bold(del.filePath)}`);
5447
- console.log(chalk6.dim(` ${del.reason}`));
5637
+ console.log(` ${chalk7.red("-")} ${chalk7.bold(del.filePath)}`);
5638
+ console.log(chalk7.dim(` ${del.reason}`));
5448
5639
  console.log("");
5449
5640
  }
5450
5641
  }
5451
- console.log(` ${chalk6.green("+")} ${chalk6.dim("new")} ${chalk6.yellow("~")} ${chalk6.dim("modified")} ${chalk6.red("-")} ${chalk6.dim("removed")}`);
5642
+ console.log(` ${chalk7.green("+")} ${chalk7.dim("new")} ${chalk7.yellow("~")} ${chalk7.dim("modified")} ${chalk7.red("-")} ${chalk7.dim("removed")}`);
5452
5643
  console.log("");
5453
5644
  }
5454
5645
  function ensurePermissions() {
@@ -5475,7 +5666,7 @@ function ensurePermissions() {
5475
5666
  }
5476
5667
 
5477
5668
  // src/commands/undo.ts
5478
- import chalk7 from "chalk";
5669
+ import chalk8 from "chalk";
5479
5670
  import ora3 from "ora";
5480
5671
  function undoCommand() {
5481
5672
  const spinner = ora3("Reverting setup...").start();
@@ -5487,27 +5678,28 @@ function undoCommand() {
5487
5678
  }
5488
5679
  spinner.succeed("Setup reverted successfully.\n");
5489
5680
  if (restored.length > 0) {
5490
- console.log(chalk7.cyan(" Restored from backup:"));
5681
+ console.log(chalk8.cyan(" Restored from backup:"));
5491
5682
  for (const file of restored) {
5492
- console.log(` ${chalk7.green("\u21A9")} ${file}`);
5683
+ console.log(` ${chalk8.green("\u21A9")} ${file}`);
5493
5684
  }
5494
5685
  }
5495
5686
  if (removed.length > 0) {
5496
- console.log(chalk7.cyan(" Removed:"));
5687
+ console.log(chalk8.cyan(" Removed:"));
5497
5688
  for (const file of removed) {
5498
- console.log(` ${chalk7.red("\u2717")} ${file}`);
5689
+ console.log(` ${chalk8.red("\u2717")} ${file}`);
5499
5690
  }
5500
5691
  }
5501
5692
  console.log("");
5502
5693
  } catch (err) {
5503
- spinner.fail(chalk7.red(err instanceof Error ? err.message : "Undo failed"));
5694
+ spinner.fail(chalk8.red(err instanceof Error ? err.message : "Undo failed"));
5504
5695
  throw new Error("__exit__");
5505
5696
  }
5506
5697
  }
5507
5698
 
5508
5699
  // src/commands/status.ts
5509
- import chalk8 from "chalk";
5700
+ import chalk9 from "chalk";
5510
5701
  import fs22 from "fs";
5702
+ init_config();
5511
5703
  async function statusCommand(options) {
5512
5704
  const config = loadConfig();
5513
5705
  const manifest = readManifest();
@@ -5520,49 +5712,51 @@ async function statusCommand(options) {
5520
5712
  }, null, 2));
5521
5713
  return;
5522
5714
  }
5523
- console.log(chalk8.bold("\nCaliber Status\n"));
5715
+ console.log(chalk9.bold("\nCaliber Status\n"));
5524
5716
  if (config) {
5525
- console.log(` LLM: ${chalk8.green(config.provider)} (${config.model})`);
5717
+ console.log(` LLM: ${chalk9.green(config.provider)} (${config.model})`);
5526
5718
  } else {
5527
- console.log(` LLM: ${chalk8.yellow("Not configured")} \u2014 run ${chalk8.hex("#83D1EB")("caliber config")}`);
5719
+ console.log(` LLM: ${chalk9.yellow("Not configured")} \u2014 run ${chalk9.hex("#83D1EB")("caliber config")}`);
5528
5720
  }
5529
5721
  if (!manifest) {
5530
- console.log(` Setup: ${chalk8.dim("No setup applied")}`);
5531
- console.log(chalk8.dim("\n Run ") + chalk8.hex("#83D1EB")("caliber onboard") + chalk8.dim(" to get started.\n"));
5722
+ console.log(` Setup: ${chalk9.dim("No setup applied")}`);
5723
+ console.log(chalk9.dim("\n Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.dim(" to get started.\n"));
5532
5724
  return;
5533
5725
  }
5534
- console.log(` Files managed: ${chalk8.cyan(manifest.entries.length.toString())}`);
5726
+ console.log(` Files managed: ${chalk9.cyan(manifest.entries.length.toString())}`);
5535
5727
  for (const entry of manifest.entries) {
5536
5728
  const exists = fs22.existsSync(entry.path);
5537
- const icon = exists ? chalk8.green("\u2713") : chalk8.red("\u2717");
5729
+ const icon = exists ? chalk9.green("\u2713") : chalk9.red("\u2717");
5538
5730
  console.log(` ${icon} ${entry.path} (${entry.action})`);
5539
5731
  }
5540
5732
  console.log("");
5541
5733
  }
5542
5734
 
5543
5735
  // src/commands/regenerate.ts
5544
- import chalk9 from "chalk";
5736
+ import chalk10 from "chalk";
5545
5737
  import ora4 from "ora";
5546
- import select5 from "@inquirer/select";
5738
+ import select6 from "@inquirer/select";
5739
+ init_config();
5547
5740
  async function regenerateCommand(options) {
5548
5741
  const config = loadConfig();
5549
5742
  if (!config) {
5550
- console.log(chalk9.red("No LLM provider configured. Run ") + chalk9.hex("#83D1EB")("caliber config") + chalk9.red(" first."));
5743
+ console.log(chalk10.red("No LLM provider configured. Run ") + chalk10.hex("#83D1EB")("caliber config") + chalk10.red(" first."));
5551
5744
  throw new Error("__exit__");
5552
5745
  }
5553
5746
  const manifest = readManifest();
5554
5747
  if (!manifest) {
5555
- console.log(chalk9.yellow("No existing setup found. Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.yellow(" first."));
5748
+ console.log(chalk10.yellow("No existing setup found. Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.yellow(" first."));
5556
5749
  throw new Error("__exit__");
5557
5750
  }
5558
5751
  const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
5752
+ await validateModel({ fast: true });
5559
5753
  const spinner = ora4("Analyzing project...").start();
5560
5754
  const fingerprint = await collectFingerprint(process.cwd());
5561
5755
  spinner.succeed("Project analyzed");
5562
5756
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
5563
5757
  displayScoreSummary(baselineScore);
5564
5758
  if (baselineScore.score === 100) {
5565
- console.log(chalk9.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
5759
+ console.log(chalk10.green(" Your setup is already at 100/100 \u2014 nothing to regenerate.\n"));
5566
5760
  return;
5567
5761
  }
5568
5762
  const genSpinner = ora4("Regenerating setup...").start();
@@ -5603,18 +5797,18 @@ async function regenerateCommand(options) {
5603
5797
  const setupFiles = collectSetupFiles(generatedSetup);
5604
5798
  const staged = stageFiles(setupFiles, process.cwd());
5605
5799
  const totalChanges = staged.newFiles + staged.modifiedFiles;
5606
- console.log(chalk9.dim(`
5607
- ${chalk9.green(`${staged.newFiles} new`)} / ${chalk9.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5800
+ console.log(chalk10.dim(`
5801
+ ${chalk10.green(`${staged.newFiles} new`)} / ${chalk10.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
5608
5802
  `));
5609
5803
  if (totalChanges === 0) {
5610
- console.log(chalk9.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5804
+ console.log(chalk10.dim(" No changes needed \u2014 your configs are already up to date.\n"));
5611
5805
  cleanupStaging();
5612
5806
  return;
5613
5807
  }
5614
5808
  if (options.dryRun) {
5615
- console.log(chalk9.yellow("[Dry run] Would write:"));
5809
+ console.log(chalk10.yellow("[Dry run] Would write:"));
5616
5810
  for (const f of staged.stagedFiles) {
5617
- console.log(` ${f.isNew ? chalk9.green("+") : chalk9.yellow("~")} ${f.relativePath}`);
5811
+ console.log(` ${f.isNew ? chalk10.green("+") : chalk10.yellow("~")} ${f.relativePath}`);
5618
5812
  }
5619
5813
  cleanupStaging();
5620
5814
  return;
@@ -5624,7 +5818,7 @@ async function regenerateCommand(options) {
5624
5818
  const reviewMethod = await promptReviewMethod();
5625
5819
  await openReview(reviewMethod, staged.stagedFiles);
5626
5820
  }
5627
- const action = await select5({
5821
+ const action = await select6({
5628
5822
  message: "Apply regenerated setup?",
5629
5823
  choices: [
5630
5824
  { name: "Accept and apply", value: "accept" },
@@ -5633,7 +5827,7 @@ async function regenerateCommand(options) {
5633
5827
  });
5634
5828
  cleanupStaging();
5635
5829
  if (action === "decline") {
5636
- console.log(chalk9.dim("Regeneration cancelled. No files were modified."));
5830
+ console.log(chalk10.dim("Regeneration cancelled. No files were modified."));
5637
5831
  return;
5638
5832
  }
5639
5833
  const writeSpinner = ora4("Writing config files...").start();
@@ -5641,20 +5835,20 @@ async function regenerateCommand(options) {
5641
5835
  const result = writeSetup(generatedSetup);
5642
5836
  writeSpinner.succeed("Config files written");
5643
5837
  for (const file of result.written) {
5644
- console.log(` ${chalk9.green("\u2713")} ${file}`);
5838
+ console.log(` ${chalk10.green("\u2713")} ${file}`);
5645
5839
  }
5646
5840
  if (result.deleted.length > 0) {
5647
5841
  for (const file of result.deleted) {
5648
- console.log(` ${chalk9.red("\u2717")} ${file}`);
5842
+ console.log(` ${chalk10.red("\u2717")} ${file}`);
5649
5843
  }
5650
5844
  }
5651
5845
  if (result.backupDir) {
5652
- console.log(chalk9.dim(`
5846
+ console.log(chalk10.dim(`
5653
5847
  Backups saved to ${result.backupDir}`));
5654
5848
  }
5655
5849
  } catch (err) {
5656
5850
  writeSpinner.fail("Failed to write files");
5657
- console.error(chalk9.red(err instanceof Error ? err.message : "Unknown error"));
5851
+ console.error(chalk10.red(err instanceof Error ? err.message : "Unknown error"));
5658
5852
  throw new Error("__exit__");
5659
5853
  }
5660
5854
  const sha = getCurrentHeadSha();
@@ -5666,24 +5860,24 @@ async function regenerateCommand(options) {
5666
5860
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
5667
5861
  if (afterScore.score < baselineScore.score) {
5668
5862
  console.log("");
5669
- console.log(chalk9.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5863
+ console.log(chalk10.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
5670
5864
  try {
5671
5865
  const { restored, removed } = undoSetup();
5672
5866
  if (restored.length > 0 || removed.length > 0) {
5673
- console.log(chalk9.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5867
+ console.log(chalk10.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
5674
5868
  }
5675
5869
  } catch {
5676
5870
  }
5677
- console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber onboard --force") + chalk9.dim(" to override.\n"));
5871
+ console.log(chalk10.dim(" Run ") + chalk10.hex("#83D1EB")("caliber onboard --force") + chalk10.dim(" to override.\n"));
5678
5872
  return;
5679
5873
  }
5680
5874
  displayScoreDelta(baselineScore, afterScore);
5681
- console.log(chalk9.bold.green(" Regeneration complete!"));
5682
- console.log(chalk9.dim(" Run ") + chalk9.hex("#83D1EB")("caliber undo") + chalk9.dim(" to revert changes.\n"));
5875
+ console.log(chalk10.bold.green(" Regeneration complete!"));
5876
+ console.log(chalk10.dim(" Run ") + chalk10.hex("#83D1EB")("caliber undo") + chalk10.dim(" to revert changes.\n"));
5683
5877
  }
5684
5878
 
5685
5879
  // src/commands/score.ts
5686
- import chalk10 from "chalk";
5880
+ import chalk11 from "chalk";
5687
5881
  async function scoreCommand(options) {
5688
5882
  const dir = process.cwd();
5689
5883
  const target = options.agent ?? readState()?.targetAgent;
@@ -5697,14 +5891,14 @@ async function scoreCommand(options) {
5697
5891
  return;
5698
5892
  }
5699
5893
  displayScore(result);
5700
- const separator = chalk10.gray(" " + "\u2500".repeat(53));
5894
+ const separator = chalk11.gray(" " + "\u2500".repeat(53));
5701
5895
  console.log(separator);
5702
5896
  if (result.score < 40) {
5703
- console.log(chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.gray(" to generate a complete, optimized setup."));
5897
+ console.log(chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber onboard") + chalk11.gray(" to generate a complete, optimized setup."));
5704
5898
  } else if (result.score < 70) {
5705
- console.log(chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber onboard") + chalk10.gray(" to improve your setup."));
5899
+ console.log(chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber onboard") + chalk11.gray(" to improve your setup."));
5706
5900
  } else {
5707
- console.log(chalk10.green(" Looking good!") + chalk10.gray(" Run ") + chalk10.hex("#83D1EB")("caliber regenerate") + chalk10.gray(" to rebuild from scratch."));
5901
+ console.log(chalk11.green(" Looking good!") + chalk11.gray(" Run ") + chalk11.hex("#83D1EB")("caliber regenerate") + chalk11.gray(" to rebuild from scratch."));
5708
5902
  }
5709
5903
  console.log("");
5710
5904
  }
@@ -5712,7 +5906,7 @@ async function scoreCommand(options) {
5712
5906
  // src/commands/refresh.ts
5713
5907
  import fs24 from "fs";
5714
5908
  import path18 from "path";
5715
- import chalk11 from "chalk";
5909
+ import chalk12 from "chalk";
5716
5910
  import ora5 from "ora";
5717
5911
 
5718
5912
  // src/lib/git-diff.ts
@@ -5826,6 +6020,7 @@ function writeRefreshDocs(docs) {
5826
6020
  }
5827
6021
 
5828
6022
  // src/ai/refresh.ts
6023
+ init_config();
5829
6024
  async function refreshDocs(diff, existingDocs, projectContext) {
5830
6025
  const prompt = buildRefreshPrompt(diff, existingDocs, projectContext);
5831
6026
  const fastModel = getFastModel();
@@ -5889,6 +6084,7 @@ Changed files: ${diff.changedFiles.join(", ")}`);
5889
6084
  }
5890
6085
 
5891
6086
  // src/commands/refresh.ts
6087
+ init_config();
5892
6088
  function log(quiet, ...args) {
5893
6089
  if (!quiet) console.log(...args);
5894
6090
  }
@@ -5909,7 +6105,7 @@ function discoverGitRepos(parentDir) {
5909
6105
  }
5910
6106
  async function refreshSingleRepo(repoDir, options) {
5911
6107
  const quiet = !!options.quiet;
5912
- const prefix = options.label ? `${chalk11.bold(options.label)} ` : "";
6108
+ const prefix = options.label ? `${chalk12.bold(options.label)} ` : "";
5913
6109
  const state = readState();
5914
6110
  const lastSha = state?.lastRefreshSha ?? null;
5915
6111
  const diff = collectDiff(lastSha);
@@ -5918,7 +6114,7 @@ async function refreshSingleRepo(repoDir, options) {
5918
6114
  if (currentSha) {
5919
6115
  writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
5920
6116
  }
5921
- log(quiet, chalk11.dim(`${prefix}No changes since last refresh.`));
6117
+ log(quiet, chalk12.dim(`${prefix}No changes since last refresh.`));
5922
6118
  return;
5923
6119
  }
5924
6120
  const spinner = quiet ? null : ora5(`${prefix}Analyzing changes...`).start();
@@ -5950,10 +6146,10 @@ async function refreshSingleRepo(repoDir, options) {
5950
6146
  if (options.dryRun) {
5951
6147
  spinner?.info(`${prefix}Dry run \u2014 would update:`);
5952
6148
  for (const doc of response.docsUpdated) {
5953
- console.log(` ${chalk11.yellow("~")} ${doc}`);
6149
+ console.log(` ${chalk12.yellow("~")} ${doc}`);
5954
6150
  }
5955
6151
  if (response.changesSummary) {
5956
- console.log(chalk11.dim(`
6152
+ console.log(chalk12.dim(`
5957
6153
  ${response.changesSummary}`));
5958
6154
  }
5959
6155
  return;
@@ -5961,10 +6157,10 @@ async function refreshSingleRepo(repoDir, options) {
5961
6157
  const written = writeRefreshDocs(response.updatedDocs);
5962
6158
  spinner?.succeed(`${prefix}Updated ${written.length} doc${written.length === 1 ? "" : "s"}`);
5963
6159
  for (const file of written) {
5964
- log(quiet, ` ${chalk11.green("\u2713")} ${file}`);
6160
+ log(quiet, ` ${chalk12.green("\u2713")} ${file}`);
5965
6161
  }
5966
6162
  if (response.changesSummary) {
5967
- log(quiet, chalk11.dim(`
6163
+ log(quiet, chalk12.dim(`
5968
6164
  ${response.changesSummary}`));
5969
6165
  }
5970
6166
  if (currentSha) {
@@ -5977,9 +6173,10 @@ async function refreshCommand(options) {
5977
6173
  const config = loadConfig();
5978
6174
  if (!config) {
5979
6175
  if (quiet) return;
5980
- console.log(chalk11.red("No LLM provider configured. Run ") + chalk11.hex("#83D1EB")("caliber config") + chalk11.red(" (e.g. choose Cursor) or set an API key."));
6176
+ console.log(chalk12.red("No LLM provider configured. Run ") + chalk12.hex("#83D1EB")("caliber config") + chalk12.red(" (e.g. choose Cursor) or set an API key."));
5981
6177
  throw new Error("__exit__");
5982
6178
  }
6179
+ await validateModel({ fast: true });
5983
6180
  if (isGitRepo()) {
5984
6181
  await refreshSingleRepo(process.cwd(), options);
5985
6182
  return;
@@ -5987,10 +6184,10 @@ async function refreshCommand(options) {
5987
6184
  const repos = discoverGitRepos(process.cwd());
5988
6185
  if (repos.length === 0) {
5989
6186
  if (quiet) return;
5990
- console.log(chalk11.red("Not inside a git repository and no git repos found in child directories."));
6187
+ console.log(chalk12.red("Not inside a git repository and no git repos found in child directories."));
5991
6188
  throw new Error("__exit__");
5992
6189
  }
5993
- log(quiet, chalk11.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
6190
+ log(quiet, chalk12.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
5994
6191
  `));
5995
6192
  const originalDir = process.cwd();
5996
6193
  for (const repo of repos) {
@@ -6000,7 +6197,7 @@ async function refreshCommand(options) {
6000
6197
  await refreshSingleRepo(repo, { ...options, label: repoName });
6001
6198
  } catch (err) {
6002
6199
  if (err instanceof Error && err.message === "__exit__") continue;
6003
- log(quiet, chalk11.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
6200
+ log(quiet, chalk12.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
6004
6201
  }
6005
6202
  }
6006
6203
  process.chdir(originalDir);
@@ -6008,13 +6205,13 @@ async function refreshCommand(options) {
6008
6205
  if (err instanceof Error && err.message === "__exit__") throw err;
6009
6206
  if (quiet) return;
6010
6207
  const msg = err instanceof Error ? err.message : "Unknown error";
6011
- console.log(chalk11.red(`Refresh failed: ${msg}`));
6208
+ console.log(chalk12.red(`Refresh failed: ${msg}`));
6012
6209
  throw new Error("__exit__");
6013
6210
  }
6014
6211
  }
6015
6212
 
6016
6213
  // src/commands/hooks.ts
6017
- import chalk12 from "chalk";
6214
+ import chalk13 from "chalk";
6018
6215
  var HOOKS = [
6019
6216
  {
6020
6217
  id: "session-end",
@@ -6034,13 +6231,13 @@ var HOOKS = [
6034
6231
  }
6035
6232
  ];
6036
6233
  function printStatus() {
6037
- console.log(chalk12.bold("\n Hooks\n"));
6234
+ console.log(chalk13.bold("\n Hooks\n"));
6038
6235
  for (const hook of HOOKS) {
6039
6236
  const installed = hook.isInstalled();
6040
- const icon = installed ? chalk12.green("\u2713") : chalk12.dim("\u2717");
6041
- const state = installed ? chalk12.green("enabled") : chalk12.dim("disabled");
6237
+ const icon = installed ? chalk13.green("\u2713") : chalk13.dim("\u2717");
6238
+ const state = installed ? chalk13.green("enabled") : chalk13.dim("disabled");
6042
6239
  console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
6043
- console.log(chalk12.dim(` ${hook.description}`));
6240
+ console.log(chalk13.dim(` ${hook.description}`));
6044
6241
  }
6045
6242
  console.log("");
6046
6243
  }
@@ -6049,9 +6246,9 @@ async function hooksCommand(options) {
6049
6246
  for (const hook of HOOKS) {
6050
6247
  const result = hook.install();
6051
6248
  if (result.alreadyInstalled) {
6052
- console.log(chalk12.dim(` ${hook.label} already enabled.`));
6249
+ console.log(chalk13.dim(` ${hook.label} already enabled.`));
6053
6250
  } else {
6054
- console.log(chalk12.green(" \u2713") + ` ${hook.label} enabled`);
6251
+ console.log(chalk13.green(" \u2713") + ` ${hook.label} enabled`);
6055
6252
  }
6056
6253
  }
6057
6254
  return;
@@ -6060,9 +6257,9 @@ async function hooksCommand(options) {
6060
6257
  for (const hook of HOOKS) {
6061
6258
  const result = hook.remove();
6062
6259
  if (result.notFound) {
6063
- console.log(chalk12.dim(` ${hook.label} already disabled.`));
6260
+ console.log(chalk13.dim(` ${hook.label} already disabled.`));
6064
6261
  } else {
6065
- console.log(chalk12.green(" \u2713") + ` ${hook.label} removed`);
6262
+ console.log(chalk13.green(" \u2713") + ` ${hook.label} removed`);
6066
6263
  }
6067
6264
  }
6068
6265
  return;
@@ -6077,18 +6274,18 @@ async function hooksCommand(options) {
6077
6274
  const states = HOOKS.map((h) => h.isInstalled());
6078
6275
  function render() {
6079
6276
  const lines = [];
6080
- lines.push(chalk12.bold(" Hooks"));
6277
+ lines.push(chalk13.bold(" Hooks"));
6081
6278
  lines.push("");
6082
6279
  for (let i = 0; i < HOOKS.length; i++) {
6083
6280
  const hook = HOOKS[i];
6084
6281
  const enabled = states[i];
6085
- const toggle = enabled ? chalk12.green("[on] ") : chalk12.dim("[off]");
6086
- const ptr = i === cursor ? chalk12.cyan(">") : " ";
6282
+ const toggle = enabled ? chalk13.green("[on] ") : chalk13.dim("[off]");
6283
+ const ptr = i === cursor ? chalk13.cyan(">") : " ";
6087
6284
  lines.push(` ${ptr} ${toggle} ${hook.label}`);
6088
- lines.push(chalk12.dim(` ${hook.description}`));
6285
+ lines.push(chalk13.dim(` ${hook.description}`));
6089
6286
  }
6090
6287
  lines.push("");
6091
- lines.push(chalk12.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
6288
+ lines.push(chalk13.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
6092
6289
  return lines.join("\n");
6093
6290
  }
6094
6291
  function draw(initial) {
@@ -6119,16 +6316,16 @@ async function hooksCommand(options) {
6119
6316
  const wantEnabled = states[i];
6120
6317
  if (wantEnabled && !wasInstalled) {
6121
6318
  hook.install();
6122
- console.log(chalk12.green(" \u2713") + ` ${hook.label} enabled`);
6319
+ console.log(chalk13.green(" \u2713") + ` ${hook.label} enabled`);
6123
6320
  changed++;
6124
6321
  } else if (!wantEnabled && wasInstalled) {
6125
6322
  hook.remove();
6126
- console.log(chalk12.green(" \u2713") + ` ${hook.label} disabled`);
6323
+ console.log(chalk13.green(" \u2713") + ` ${hook.label} disabled`);
6127
6324
  changed++;
6128
6325
  }
6129
6326
  }
6130
6327
  if (changed === 0) {
6131
- console.log(chalk12.dim(" No changes."));
6328
+ console.log(chalk13.dim(" No changes."));
6132
6329
  }
6133
6330
  console.log("");
6134
6331
  }
@@ -6164,7 +6361,7 @@ async function hooksCommand(options) {
6164
6361
  case "\x1B":
6165
6362
  case "":
6166
6363
  cleanup();
6167
- console.log(chalk12.dim("\n Cancelled.\n"));
6364
+ console.log(chalk13.dim("\n Cancelled.\n"));
6168
6365
  resolve2();
6169
6366
  break;
6170
6367
  }
@@ -6174,48 +6371,49 @@ async function hooksCommand(options) {
6174
6371
  }
6175
6372
 
6176
6373
  // src/commands/config.ts
6177
- import chalk13 from "chalk";
6374
+ init_config();
6375
+ import chalk14 from "chalk";
6178
6376
  async function configCommand() {
6179
6377
  const existing = loadConfig();
6180
6378
  if (existing) {
6181
6379
  const displayModel = existing.model === "default" && existing.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : existing.model;
6182
6380
  const fastModel = getFastModel();
6183
- console.log(chalk13.bold("\nCurrent Configuration\n"));
6184
- console.log(` Provider: ${chalk13.cyan(existing.provider)}`);
6185
- console.log(` Model: ${chalk13.cyan(displayModel)}`);
6381
+ console.log(chalk14.bold("\nCurrent Configuration\n"));
6382
+ console.log(` Provider: ${chalk14.cyan(existing.provider)}`);
6383
+ console.log(` Model: ${chalk14.cyan(displayModel)}`);
6186
6384
  if (fastModel) {
6187
- console.log(` Scan: ${chalk13.cyan(fastModel)}`);
6385
+ console.log(` Scan: ${chalk14.cyan(fastModel)}`);
6188
6386
  }
6189
6387
  if (existing.apiKey) {
6190
6388
  const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
6191
- console.log(` API Key: ${chalk13.dim(masked)}`);
6389
+ console.log(` API Key: ${chalk14.dim(masked)}`);
6192
6390
  }
6193
6391
  if (existing.provider === "cursor") {
6194
- console.log(` Seat: ${chalk13.dim("Cursor (agent acp)")}`);
6392
+ console.log(` Seat: ${chalk14.dim("Cursor (agent acp)")}`);
6195
6393
  }
6196
6394
  if (existing.provider === "claude-cli") {
6197
- console.log(` Seat: ${chalk13.dim("Claude Code (claude -p)")}`);
6395
+ console.log(` Seat: ${chalk14.dim("Claude Code (claude -p)")}`);
6198
6396
  }
6199
6397
  if (existing.baseUrl) {
6200
- console.log(` Base URL: ${chalk13.dim(existing.baseUrl)}`);
6398
+ console.log(` Base URL: ${chalk14.dim(existing.baseUrl)}`);
6201
6399
  }
6202
6400
  if (existing.vertexProjectId) {
6203
- console.log(` Vertex Project: ${chalk13.dim(existing.vertexProjectId)}`);
6204
- console.log(` Vertex Region: ${chalk13.dim(existing.vertexRegion || "us-east5")}`);
6401
+ console.log(` Vertex Project: ${chalk14.dim(existing.vertexProjectId)}`);
6402
+ console.log(` Vertex Region: ${chalk14.dim(existing.vertexRegion || "us-east5")}`);
6205
6403
  }
6206
- console.log(` Source: ${chalk13.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())}`);
6404
+ console.log(` Source: ${chalk14.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())}`);
6207
6405
  console.log("");
6208
6406
  }
6209
6407
  await runInteractiveProviderSetup();
6210
- console.log(chalk13.green("\n\u2713 Configuration saved"));
6211
- console.log(chalk13.dim(` ${getConfigFilePath()}
6408
+ console.log(chalk14.green("\n\u2713 Configuration saved"));
6409
+ console.log(chalk14.dim(` ${getConfigFilePath()}
6212
6410
  `));
6213
- console.log(chalk13.dim(" You can also set environment variables instead:"));
6214
- console.log(chalk13.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
6411
+ console.log(chalk14.dim(" You can also set environment variables instead:"));
6412
+ console.log(chalk14.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
6215
6413
  }
6216
6414
 
6217
6415
  // src/commands/learn.ts
6218
- import chalk14 from "chalk";
6416
+ import chalk15 from "chalk";
6219
6417
 
6220
6418
  // src/learner/stdin.ts
6221
6419
  var STDIN_TIMEOUT_MS = 5e3;
@@ -6384,6 +6582,7 @@ function readLearnedSection() {
6384
6582
  }
6385
6583
 
6386
6584
  // src/ai/learn.ts
6585
+ init_config();
6387
6586
  var MAX_PROMPT_TOKENS = 1e5;
6388
6587
  function formatEventsForPrompt(events) {
6389
6588
  return events.map((e, i) => {
@@ -6457,6 +6656,7 @@ ${eventsText}`;
6457
6656
  }
6458
6657
 
6459
6658
  // src/commands/learn.ts
6659
+ init_config();
6460
6660
  async function learnObserveCommand(options) {
6461
6661
  try {
6462
6662
  const raw = await readStdin();
@@ -6494,6 +6694,7 @@ async function learnFinalizeCommand() {
6494
6694
  resetState();
6495
6695
  return;
6496
6696
  }
6697
+ await validateModel();
6497
6698
  const existingConfigs = readExistingConfigs(process.cwd());
6498
6699
  const existingLearnedSection = readLearnedSection();
6499
6700
  const existingSkills = existingConfigs.claudeSkills || [];
@@ -6518,46 +6719,46 @@ async function learnFinalizeCommand() {
6518
6719
  async function learnInstallCommand() {
6519
6720
  const result = installLearningHooks();
6520
6721
  if (result.alreadyInstalled) {
6521
- console.log(chalk14.dim("Learning hooks already installed."));
6722
+ console.log(chalk15.dim("Learning hooks already installed."));
6522
6723
  return;
6523
6724
  }
6524
- console.log(chalk14.green("\u2713") + " Learning hooks installed in .claude/settings.json");
6525
- console.log(chalk14.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
6526
- console.log(chalk14.dim(" Session learnings will be written to CLAUDE.md and skills."));
6725
+ console.log(chalk15.green("\u2713") + " Learning hooks installed in .claude/settings.json");
6726
+ console.log(chalk15.dim(" PostToolUse, PostToolUseFailure, and SessionEnd hooks active."));
6727
+ console.log(chalk15.dim(" Session learnings will be written to CLAUDE.md and skills."));
6527
6728
  }
6528
6729
  async function learnRemoveCommand() {
6529
6730
  const result = removeLearningHooks();
6530
6731
  if (result.notFound) {
6531
- console.log(chalk14.dim("Learning hooks not found."));
6732
+ console.log(chalk15.dim("Learning hooks not found."));
6532
6733
  return;
6533
6734
  }
6534
- console.log(chalk14.green("\u2713") + " Learning hooks removed from .claude/settings.json");
6735
+ console.log(chalk15.green("\u2713") + " Learning hooks removed from .claude/settings.json");
6535
6736
  }
6536
6737
  async function learnStatusCommand() {
6537
6738
  const installed = areLearningHooksInstalled();
6538
6739
  const state = readState2();
6539
6740
  const eventCount = getEventCount();
6540
- console.log(chalk14.bold("Session Learning Status"));
6741
+ console.log(chalk15.bold("Session Learning Status"));
6541
6742
  console.log();
6542
6743
  if (installed) {
6543
- console.log(chalk14.green("\u2713") + " Learning hooks are " + chalk14.green("installed"));
6744
+ console.log(chalk15.green("\u2713") + " Learning hooks are " + chalk15.green("installed"));
6544
6745
  } else {
6545
- console.log(chalk14.dim("\u2717") + " Learning hooks are " + chalk14.yellow("not installed"));
6546
- console.log(chalk14.dim(" Run `caliber learn install` to enable session learning."));
6746
+ console.log(chalk15.dim("\u2717") + " Learning hooks are " + chalk15.yellow("not installed"));
6747
+ console.log(chalk15.dim(" Run `caliber learn install` to enable session learning."));
6547
6748
  }
6548
6749
  console.log();
6549
- console.log(`Events recorded: ${chalk14.cyan(String(eventCount))}`);
6550
- console.log(`Total this session: ${chalk14.cyan(String(state.eventCount))}`);
6750
+ console.log(`Events recorded: ${chalk15.cyan(String(eventCount))}`);
6751
+ console.log(`Total this session: ${chalk15.cyan(String(state.eventCount))}`);
6551
6752
  if (state.lastAnalysisTimestamp) {
6552
- console.log(`Last analysis: ${chalk14.cyan(state.lastAnalysisTimestamp)}`);
6753
+ console.log(`Last analysis: ${chalk15.cyan(state.lastAnalysisTimestamp)}`);
6553
6754
  } else {
6554
- console.log(`Last analysis: ${chalk14.dim("none")}`);
6755
+ console.log(`Last analysis: ${chalk15.dim("none")}`);
6555
6756
  }
6556
6757
  const learnedSection = readLearnedSection();
6557
6758
  if (learnedSection) {
6558
6759
  const lineCount = learnedSection.split("\n").filter(Boolean).length;
6559
6760
  console.log(`
6560
- Learned items in CLAUDE.md: ${chalk14.cyan(String(lineCount))}`);
6761
+ Learned items in CLAUDE.md: ${chalk15.cyan(String(lineCount))}`);
6561
6762
  }
6562
6763
  }
6563
6764
 
@@ -6601,7 +6802,7 @@ import fs28 from "fs";
6601
6802
  import path22 from "path";
6602
6803
  import { fileURLToPath as fileURLToPath2 } from "url";
6603
6804
  import { execSync as execSync9 } from "child_process";
6604
- import chalk15 from "chalk";
6805
+ import chalk16 from "chalk";
6605
6806
  import ora6 from "ora";
6606
6807
  import confirm from "@inquirer/confirm";
6607
6808
  var __dirname_vc = path22.dirname(fileURLToPath2(import.meta.url));
@@ -6635,17 +6836,17 @@ async function checkForUpdates() {
6635
6836
  const isInteractive = process.stdin.isTTY === true;
6636
6837
  if (!isInteractive) {
6637
6838
  console.log(
6638
- chalk15.yellow(
6839
+ chalk16.yellow(
6639
6840
  `
6640
6841
  Update available: ${current} -> ${latest}
6641
- Run ${chalk15.bold("npm install -g @rely-ai/caliber")} to upgrade.
6842
+ Run ${chalk16.bold("npm install -g @rely-ai/caliber")} to upgrade.
6642
6843
  `
6643
6844
  )
6644
6845
  );
6645
6846
  return;
6646
6847
  }
6647
6848
  console.log(
6648
- chalk15.yellow(`
6849
+ chalk16.yellow(`
6649
6850
  Update available: ${current} -> ${latest}`)
6650
6851
  );
6651
6852
  const shouldUpdate = await confirm({ message: "Would you like to update now? (Y/n)", default: true });
@@ -6663,13 +6864,13 @@ Update available: ${current} -> ${latest}`)
6663
6864
  const installed = getInstalledVersion();
6664
6865
  if (installed !== latest) {
6665
6866
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
6666
- console.log(chalk15.yellow(`Run ${chalk15.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
6867
+ console.log(chalk16.yellow(`Run ${chalk16.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
6667
6868
  `));
6668
6869
  return;
6669
6870
  }
6670
- spinner.succeed(chalk15.green(`Updated to ${latest}`));
6871
+ spinner.succeed(chalk16.green(`Updated to ${latest}`));
6671
6872
  const args = process.argv.slice(2);
6672
- console.log(chalk15.dim(`
6873
+ console.log(chalk16.dim(`
6673
6874
  Restarting: caliber ${args.join(" ")}
6674
6875
  `));
6675
6876
  execSync9(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
@@ -6682,11 +6883,11 @@ Restarting: caliber ${args.join(" ")}
6682
6883
  if (err instanceof Error) {
6683
6884
  const stderr = err.stderr;
6684
6885
  const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
6685
- if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk15.dim(` ${errMsg}`));
6886
+ if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk16.dim(` ${errMsg}`));
6686
6887
  }
6687
6888
  console.log(
6688
- chalk15.yellow(
6689
- `Run ${chalk15.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
6889
+ chalk16.yellow(
6890
+ `Run ${chalk16.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
6690
6891
  `
6691
6892
  )
6692
6893
  );