@rely-ai/caliber 1.46.3 → 1.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +699 -613
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -1206,14 +1206,14 @@ __export(lock_exports, {
1206
1206
  isCaliberRunning: () => isCaliberRunning,
1207
1207
  releaseLock: () => releaseLock
1208
1208
  });
1209
- import fs41 from "fs";
1210
- import path33 from "path";
1209
+ import fs42 from "fs";
1210
+ import path34 from "path";
1211
1211
  import os8 from "os";
1212
1212
  import crypto5 from "crypto";
1213
1213
  function buildLockPath() {
1214
1214
  const cwd = process.cwd();
1215
1215
  const hash = crypto5.createHash("md5").update(cwd).digest("hex").slice(0, 8);
1216
- return path33.join(os8.tmpdir(), `.caliber-${hash}.lock`);
1216
+ return path34.join(os8.tmpdir(), `.caliber-${hash}.lock`);
1217
1217
  }
1218
1218
  function getLockFile() {
1219
1219
  if (!_lockPath) _lockPath = buildLockPath();
@@ -1222,8 +1222,8 @@ function getLockFile() {
1222
1222
  function isCaliberRunning() {
1223
1223
  try {
1224
1224
  const lockFile = buildLockPath();
1225
- if (!fs41.existsSync(lockFile)) return false;
1226
- const raw = fs41.readFileSync(lockFile, "utf-8").trim();
1225
+ if (!fs42.existsSync(lockFile)) return false;
1226
+ const raw = fs42.readFileSync(lockFile, "utf-8").trim();
1227
1227
  const { pid, ts } = JSON.parse(raw);
1228
1228
  if (pid === process.pid) return false;
1229
1229
  if (Date.now() - ts > STALE_MS) return false;
@@ -1239,14 +1239,14 @@ function isCaliberRunning() {
1239
1239
  }
1240
1240
  function acquireLock() {
1241
1241
  try {
1242
- fs41.writeFileSync(getLockFile(), JSON.stringify({ pid: process.pid, ts: Date.now() }));
1242
+ fs42.writeFileSync(getLockFile(), JSON.stringify({ pid: process.pid, ts: Date.now() }));
1243
1243
  } catch {
1244
1244
  }
1245
1245
  }
1246
1246
  function releaseLock() {
1247
1247
  try {
1248
1248
  const lockFile = getLockFile();
1249
- if (fs41.existsSync(lockFile)) fs41.unlinkSync(lockFile);
1249
+ if (fs42.existsSync(lockFile)) fs42.unlinkSync(lockFile);
1250
1250
  } catch {
1251
1251
  }
1252
1252
  }
@@ -1261,14 +1261,14 @@ var init_lock = __esm({
1261
1261
 
1262
1262
  // src/cli.ts
1263
1263
  import { Command } from "commander";
1264
- import fs52 from "fs";
1265
- import path42 from "path";
1264
+ import fs53 from "fs";
1265
+ import path43 from "path";
1266
1266
  import { fileURLToPath } from "url";
1267
1267
 
1268
1268
  // src/commands/init.ts
1269
- import path28 from "path";
1270
- import chalk13 from "chalk";
1271
- import fs35 from "fs";
1269
+ import path29 from "path";
1270
+ import chalk14 from "chalk";
1271
+ import fs36 from "fs";
1272
1272
 
1273
1273
  // src/fingerprint/index.ts
1274
1274
  import fs9 from "fs";
@@ -2622,6 +2622,13 @@ function estimateTokens(text) {
2622
2622
  return Math.ceil(text.length / 4);
2623
2623
  }
2624
2624
 
2625
+ // src/utils/windows.ts
2626
+ function quoteForWindows(arg) {
2627
+ if (!arg) return '""';
2628
+ if (!/[ \t\n\v"]/.test(arg)) return arg;
2629
+ return '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
2630
+ }
2631
+
2625
2632
  // src/llm/cursor-acp.ts
2626
2633
  var IS_WINDOWS = process.platform === "win32";
2627
2634
  var _agentBin = null;
@@ -2697,10 +2704,14 @@ var CursorAcpProvider = class {
2697
2704
  const targetModel = model || this.defaultModel;
2698
2705
  if (this.warmProcess && !this.warmProcess.killed && this.warmModel === targetModel) return;
2699
2706
  const args = this.buildArgs(targetModel, false);
2700
- this.warmProcess = spawn(resolveAgentBin(), args, {
2707
+ const env = { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } };
2708
+ this.warmProcess = IS_WINDOWS ? spawn([quoteForWindows(resolveAgentBin()), ...args.map(quoteForWindows)].join(" "), {
2701
2709
  stdio: ["pipe", "pipe", "pipe"],
2702
- env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
2703
- ...IS_WINDOWS && { shell: true }
2710
+ env,
2711
+ shell: true
2712
+ }) : spawn(resolveAgentBin(), args, {
2713
+ stdio: ["pipe", "pipe", "pipe"],
2714
+ env
2704
2715
  });
2705
2716
  this.warmModel = targetModel;
2706
2717
  this.warmProcess.on("error", () => {
@@ -2744,10 +2755,14 @@ var CursorAcpProvider = class {
2744
2755
  return { child: warm, stderrChunks: stderrChunks2 };
2745
2756
  }
2746
2757
  const args = this.buildArgs(model, streaming);
2747
- const child = spawn(resolveAgentBin(), args, {
2758
+ const env = { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } };
2759
+ const child = IS_WINDOWS ? spawn([quoteForWindows(resolveAgentBin()), ...args.map(quoteForWindows)].join(" "), {
2760
+ stdio: ["pipe", "pipe", "pipe"],
2761
+ env,
2762
+ shell: true
2763
+ }) : spawn(resolveAgentBin(), args, {
2748
2764
  stdio: ["pipe", "pipe", "pipe"],
2749
- env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
2750
- ...IS_WINDOWS && { shell: true }
2765
+ env
2751
2766
  });
2752
2767
  const stderrChunks = [];
2753
2768
  child.stderr.on("data", (chunk) => {
@@ -5366,15 +5381,15 @@ init_config();
5366
5381
  // src/utils/dependencies.ts
5367
5382
  import { readFileSync as readFileSync2 } from "fs";
5368
5383
  import { join as join2 } from "path";
5369
- function readFileOrNull2(path44) {
5384
+ function readFileOrNull2(path45) {
5370
5385
  try {
5371
- return readFileSync2(path44, "utf-8");
5386
+ return readFileSync2(path45, "utf-8");
5372
5387
  } catch {
5373
5388
  return null;
5374
5389
  }
5375
5390
  }
5376
- function readJsonOrNull(path44) {
5377
- const content = readFileOrNull2(path44);
5391
+ function readJsonOrNull(path45) {
5392
+ const content = readFileOrNull2(path45);
5378
5393
  if (!content) return null;
5379
5394
  try {
5380
5395
  return JSON.parse(content);
@@ -8586,8 +8601,8 @@ function trackInitSkillsSearch(searched, installedCount) {
8586
8601
  function trackInitScoreRegression(oldScore, newScore) {
8587
8602
  trackEvent("init_score_regression", { old_score: oldScore, new_score: newScore });
8588
8603
  }
8589
- function trackInitCompleted(path44, score) {
8590
- trackEvent("init_completed", { path: path44, score });
8604
+ function trackInitCompleted(path45, score) {
8605
+ trackEvent("init_completed", { path: path45, score });
8591
8606
  }
8592
8607
  function trackRegenerateCompleted(action, durationMs) {
8593
8608
  trackEvent("regenerate_completed", { action, duration_ms: durationMs });
@@ -9604,11 +9619,11 @@ async function scoreAndRefine(setup, dir, sessionHistory, callbacks, options) {
9604
9619
  const maxIterations = options?.thorough ? 3 : MAX_REFINE_ITERATIONS;
9605
9620
  const minPoints = options?.thorough ? 1 : MIN_POINTS_TO_REFINE;
9606
9621
  const existsCache = /* @__PURE__ */ new Map();
9607
- const cachedExists = (path44) => {
9608
- const cached = existsCache.get(path44);
9622
+ const cachedExists = (path45) => {
9623
+ const cached = existsCache.get(path45);
9609
9624
  if (cached !== void 0) return cached;
9610
- const result = existsSync9(path44);
9611
- existsCache.set(path44, result);
9625
+ const result = existsSync9(path45);
9626
+ existsCache.set(path45, result);
9612
9627
  return result;
9613
9628
  };
9614
9629
  const projectStructure = collectProjectStructure(dir);
@@ -10953,14 +10968,84 @@ function getScoreTrend(entries) {
10953
10968
  };
10954
10969
  }
10955
10970
 
10971
+ // src/fingerprint/large-file-scan.ts
10972
+ import fs35 from "fs";
10973
+ import path28 from "path";
10974
+ var DEFAULT_THRESHOLD_BYTES = 1048576;
10975
+ var DEFAULT_IGNORE_DIRS = IGNORE_DIRS;
10976
+ function scanLargeFiles(dir, options = {}) {
10977
+ const {
10978
+ thresholdBytes = DEFAULT_THRESHOLD_BYTES,
10979
+ ignoreDirs = DEFAULT_IGNORE_DIRS,
10980
+ statSync: stat = fs35.statSync,
10981
+ readdirSync: readdir = (p) => fs35.readdirSync(p)
10982
+ } = options;
10983
+ const warnings = [];
10984
+ walkDir2(dir, ignoreDirs, thresholdBytes, stat, readdir, warnings);
10985
+ return warnings;
10986
+ }
10987
+ function walkDir2(current, ignoreDirs, thresholdBytes, stat, readdir, out) {
10988
+ let names;
10989
+ try {
10990
+ names = readdir(current);
10991
+ } catch (err) {
10992
+ const code = err.code;
10993
+ if (code === "EACCES" || code === "ENOENT" || code === "ENOTDIR") return;
10994
+ throw err;
10995
+ }
10996
+ for (const name of names) {
10997
+ if (ignoreDirs.has(name)) continue;
10998
+ const fullPath = path28.join(current, name);
10999
+ let entry;
11000
+ try {
11001
+ entry = stat(fullPath);
11002
+ } catch {
11003
+ continue;
11004
+ }
11005
+ if (entry.isDirectory()) {
11006
+ walkDir2(fullPath, ignoreDirs, thresholdBytes, stat, readdir, out);
11007
+ } else if (entry.isFile() && entry.size > thresholdBytes) {
11008
+ out.push({
11009
+ filePath: fullPath,
11010
+ sizeBytes: entry.size,
11011
+ sizeMB: (entry.size / 1048576).toFixed(2)
11012
+ });
11013
+ }
11014
+ }
11015
+ }
11016
+
11017
+ // src/fingerprint/large-file-warn.ts
11018
+ import chalk13 from "chalk";
11019
+ function printLargeFileWarnings(warnings, options = {}) {
11020
+ if (warnings.length === 0) return;
11021
+ const { spinner } = options;
11022
+ const header = chalk13.yellow.bold(
11023
+ `\u26A0 ${warnings.length} large file${warnings.length === 1 ? "" : "s"} may bloat your AI context window`
11024
+ );
11025
+ const fileLines = warnings.map((w) => chalk13.yellow(` \u2022 ${w.filePath} (${w.sizeMB} MB)`)).join("\n");
11026
+ const hint = chalk13.dim(
11027
+ " Add them to .gitignore or .caliberignore to keep context lean."
11028
+ );
11029
+ const block = `
11030
+ ${header}
11031
+ ${fileLines}
11032
+ ${hint}
11033
+ `;
11034
+ if (spinner) {
11035
+ spinner.warn(block);
11036
+ } else {
11037
+ process.stderr.write(block + "\n");
11038
+ }
11039
+ }
11040
+
10956
11041
  // src/commands/init.ts
10957
11042
  var IS_WINDOWS6 = process.platform === "win32";
10958
11043
  function log(verbose, ...args) {
10959
- if (verbose) console.log(chalk13.dim(` [verbose] ${args.map(String).join(" ")}`));
11044
+ if (verbose) console.log(chalk14.dim(` [verbose] ${args.map(String).join(" ")}`));
10960
11045
  }
10961
11046
  async function initCommand(options) {
10962
- const brand = chalk13.hex("#EB9D83");
10963
- const title = chalk13.hex("#83D1EB");
11047
+ const brand = chalk14.hex("#EB9D83");
11048
+ const title = chalk14.hex("#83D1EB");
10964
11049
  const bin = resolveCaliber();
10965
11050
  const firstRun = isFirstRun(process.cwd());
10966
11051
  if (firstRun) {
@@ -10974,23 +11059,23 @@ async function initCommand(options) {
10974
11059
  \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
10975
11060
  `)
10976
11061
  );
10977
- console.log(chalk13.dim(" Keep your AI agent configs in sync \u2014 automatically."));
10978
- console.log(chalk13.dim(" Works across Claude Code, Cursor, Codex, and GitHub Copilot.\n"));
11062
+ console.log(chalk14.dim(" Keep your AI agent configs in sync \u2014 automatically."));
11063
+ console.log(chalk14.dim(" Works across Claude Code, Cursor, Codex, and GitHub Copilot.\n"));
10979
11064
  console.log(title.bold(" How it works:\n"));
10980
- console.log(chalk13.dim(" 1. Connect Link your LLM provider and select your agents"));
10981
- console.log(chalk13.dim(" 2. Setup Detect stack, install sync hooks & skills"));
10982
- console.log(chalk13.dim(" 3. Generate Audit existing config or generate from scratch"));
10983
- console.log(chalk13.dim(" 4. Finalize Review changes and score your setup\n"));
11065
+ console.log(chalk14.dim(" 1. Connect Link your LLM provider and select your agents"));
11066
+ console.log(chalk14.dim(" 2. Setup Detect stack, install sync hooks & skills"));
11067
+ console.log(chalk14.dim(" 3. Generate Audit existing config or generate from scratch"));
11068
+ console.log(chalk14.dim(" 4. Finalize Review changes and score your setup\n"));
10984
11069
  } else {
10985
- console.log(brand.bold("\n CALIBER") + chalk13.dim(" \u2014 setting up continuous sync\n"));
11070
+ console.log(brand.bold("\n CALIBER") + chalk14.dim(" \u2014 setting up continuous sync\n"));
10986
11071
  }
10987
11072
  const platforms = detectPlatforms();
10988
11073
  if (!platforms.claude && !platforms.cursor && !platforms.codex && !platforms.opencode) {
10989
11074
  console.log(
10990
- chalk13.yellow(" \u26A0 No supported AI platforms detected (Claude, Cursor, Codex, OpenCode).")
11075
+ chalk14.yellow(" \u26A0 No supported AI platforms detected (Claude, Cursor, Codex, OpenCode).")
10991
11076
  );
10992
11077
  console.log(
10993
- chalk13.yellow(
11078
+ chalk14.yellow(
10994
11079
  " Caliber will still generate config files, but they won't be auto-installed.\n"
10995
11080
  )
10996
11081
  );
@@ -11000,7 +11085,7 @@ async function initCommand(options) {
11000
11085
  let config = loadConfig();
11001
11086
  if (!config && options.agent?.includes("opencode")) {
11002
11087
  if (isOpenCodeAvailable()) {
11003
- console.log(chalk13.dim(" Detected: OpenCode (uses your existing subscription)\n"));
11088
+ console.log(chalk14.dim(" Detected: OpenCode (uses your existing subscription)\n"));
11004
11089
  const autoConfig = { provider: "opencode", model: DEFAULT_MODELS.opencode };
11005
11090
  writeConfigFile(autoConfig);
11006
11091
  config = autoConfig;
@@ -11008,7 +11093,7 @@ async function initCommand(options) {
11008
11093
  }
11009
11094
  if (!config && !options.autoApprove) {
11010
11095
  if (isClaudeCliAvailable() && isClaudeCliLoggedIn()) {
11011
- console.log(chalk13.dim(" Detected: Claude Code CLI (uses your Pro/Max/Team subscription)\n"));
11096
+ console.log(chalk14.dim(" Detected: Claude Code CLI (uses your Pro/Max/Team subscription)\n"));
11012
11097
  const useIt = await confirm2({ message: "Use Claude Code as your LLM provider?" });
11013
11098
  if (useIt) {
11014
11099
  const autoConfig = { provider: "claude-cli", model: "default" };
@@ -11016,7 +11101,7 @@ async function initCommand(options) {
11016
11101
  config = autoConfig;
11017
11102
  }
11018
11103
  } else if (isCursorAgentAvailable() && isCursorLoggedIn()) {
11019
- console.log(chalk13.dim(" Detected: Cursor (uses your existing subscription)\n"));
11104
+ console.log(chalk14.dim(" Detected: Cursor (uses your existing subscription)\n"));
11020
11105
  const useIt = await confirm2({ message: "Use Cursor as your LLM provider?" });
11021
11106
  if (useIt) {
11022
11107
  const autoConfig = { provider: "cursor", model: "sonnet-4.6" };
@@ -11042,13 +11127,13 @@ async function initCommand(options) {
11042
11127
  }
11043
11128
  }
11044
11129
  if (!config) {
11045
- console.log(chalk13.dim(" No LLM provider detected.\n"));
11130
+ console.log(chalk14.dim(" No LLM provider detected.\n"));
11046
11131
  await runInteractiveProviderSetup({
11047
11132
  selectMessage: "How do you want to use Caliber? (choose LLM provider)"
11048
11133
  });
11049
11134
  config = loadConfig();
11050
11135
  if (!config) {
11051
- console.log(chalk13.red(" Configuration cancelled or failed.\n"));
11136
+ console.log(chalk14.red(" Configuration cancelled or failed.\n"));
11052
11137
  throw new Error("__exit__");
11053
11138
  }
11054
11139
  }
@@ -11057,7 +11142,7 @@ async function initCommand(options) {
11057
11142
  const displayModel = getDisplayModel(config);
11058
11143
  const fastModel = getFastModel();
11059
11144
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
11060
- console.log(chalk13.dim(modelLine + "\n"));
11145
+ console.log(chalk14.dim(modelLine + "\n"));
11061
11146
  if (report) {
11062
11147
  report.markStep("Provider connection");
11063
11148
  report.addSection(
@@ -11076,10 +11161,10 @@ async function initCommand(options) {
11076
11161
  const detected = detectAgents(process.cwd());
11077
11162
  if (detected.length > 0 && (options.autoApprove || firstRun)) {
11078
11163
  targetAgent = detected;
11079
- console.log(chalk13.dim(` Coding agents in this repo: ${detected.join(", ")}
11164
+ console.log(chalk14.dim(` Coding agents in this repo: ${detected.join(", ")}
11080
11165
  `));
11081
11166
  } else if (detected.length > 0) {
11082
- console.log(chalk13.dim(` Coding agents in this repo: ${detected.join(", ")}
11167
+ console.log(chalk14.dim(` Coding agents in this repo: ${detected.join(", ")}
11083
11168
  `));
11084
11169
  const useDetected = await confirm2({ message: "Generate configs for these agents?" });
11085
11170
  targetAgent = useDetected ? detected : await promptAgent();
@@ -11087,69 +11172,69 @@ async function initCommand(options) {
11087
11172
  targetAgent = options.autoApprove ? ["claude"] : await promptAgent();
11088
11173
  }
11089
11174
  }
11090
- console.log(chalk13.dim(` Target: ${targetAgent.join(", ")}
11175
+ console.log(chalk14.dim(` Target: ${targetAgent.join(", ")}
11091
11176
  `));
11092
11177
  trackInitAgentSelected(targetAgent, agentAutoDetected);
11093
11178
  if (targetAgent.length === 1 && targetAgent[0] === "github-copilot") {
11094
11179
  console.log(
11095
- chalk13.yellow(
11180
+ chalk14.yellow(
11096
11181
  " Note: GitHub Copilot is a sync target \u2014 Caliber writes .github/copilot-instructions.md\n but needs an LLM provider (configured above) to power generation.\n For the best experience, also select claude or cursor as a target agent.\n"
11097
11182
  )
11098
11183
  );
11099
11184
  }
11100
11185
  console.log(title.bold(" Step 2/4 \u2014 Setup\n"));
11101
- console.log(chalk13.dim(" Installing sync infrastructure...\n"));
11186
+ console.log(chalk14.dim(" Installing sync infrastructure...\n"));
11102
11187
  const hookResult = installPreCommitHook();
11103
11188
  if (hookResult.installed) {
11104
- console.log(` ${chalk13.green("\u2713")} Pre-commit hook installed \u2014 configs sync on every commit`);
11189
+ console.log(` ${chalk14.green("\u2713")} Pre-commit hook installed \u2014 configs sync on every commit`);
11105
11190
  } else if (hookResult.alreadyInstalled) {
11106
- console.log(` ${chalk13.green("\u2713")} Pre-commit hook \u2014 active`);
11191
+ console.log(` ${chalk14.green("\u2713")} Pre-commit hook \u2014 active`);
11107
11192
  }
11108
11193
  installStopHook();
11109
- console.log(` ${chalk13.green("\u2713")} Onboarding hook \u2014 nudges new team members to set up`);
11194
+ console.log(` ${chalk14.green("\u2713")} Onboarding hook \u2014 nudges new team members to set up`);
11110
11195
  installSessionStartHook();
11111
- console.log(` ${chalk13.green("\u2713")} Freshness hook \u2014 warns when configs are stale`);
11196
+ console.log(` ${chalk14.green("\u2713")} Freshness hook \u2014 warns when configs are stale`);
11112
11197
  if (IS_WINDOWS6) {
11113
11198
  console.log(
11114
- chalk13.yellow(
11199
+ chalk14.yellow(
11115
11200
  "\n Note: hooks use shell syntax and require Git Bash (included with Git for Windows)."
11116
11201
  )
11117
11202
  );
11118
11203
  console.log(
11119
- chalk13.dim(
11204
+ chalk14.dim(
11120
11205
  " If hooks don't run, ensure Git for Windows is installed and git is using its bundled sh."
11121
11206
  )
11122
11207
  );
11123
11208
  }
11124
11209
  const { ensureBuiltinSkills: ensureBuiltinSkills2 } = await Promise.resolve().then(() => (init_builtin_skills(), builtin_skills_exports));
11125
11210
  for (const agent of targetAgent) {
11126
- if (agent === "claude" && !fs35.existsSync(".claude"))
11127
- fs35.mkdirSync(".claude", { recursive: true });
11128
- if (agent === "cursor" && !fs35.existsSync(".cursor"))
11129
- fs35.mkdirSync(".cursor", { recursive: true });
11130
- if (agent === "codex" && !fs35.existsSync(".agents"))
11131
- fs35.mkdirSync(".agents", { recursive: true });
11211
+ if (agent === "claude" && !fs36.existsSync(".claude"))
11212
+ fs36.mkdirSync(".claude", { recursive: true });
11213
+ if (agent === "cursor" && !fs36.existsSync(".cursor"))
11214
+ fs36.mkdirSync(".cursor", { recursive: true });
11215
+ if (agent === "codex" && !fs36.existsSync(".agents"))
11216
+ fs36.mkdirSync(".agents", { recursive: true });
11132
11217
  }
11133
11218
  const skillsWritten = ensureBuiltinSkills2();
11134
11219
  if (skillsWritten.length > 0) {
11135
11220
  console.log(
11136
- ` ${chalk13.green("\u2713")} Agent skills installed \u2014 /setup-caliber, /find-skills, /save-learning`
11221
+ ` ${chalk14.green("\u2713")} Agent skills installed \u2014 /setup-caliber, /find-skills, /save-learning`
11137
11222
  );
11138
11223
  } else {
11139
- console.log(` ${chalk13.green("\u2713")} Agent skills \u2014 already installed`);
11224
+ console.log(` ${chalk14.green("\u2713")} Agent skills \u2014 already installed`);
11140
11225
  }
11141
11226
  const hasLearnableAgent = targetAgent.includes("claude") || targetAgent.includes("cursor");
11142
11227
  if (hasLearnableAgent) {
11143
11228
  if (targetAgent.includes("claude")) installLearningHooks();
11144
11229
  if (targetAgent.includes("cursor")) installCursorLearningHooks();
11145
- console.log(` ${chalk13.green("\u2713")} Session learning enabled`);
11230
+ console.log(` ${chalk14.green("\u2713")} Session learning enabled`);
11146
11231
  trackInitLearnEnabled(true);
11147
11232
  }
11148
11233
  console.log("");
11149
- console.log(chalk13.dim(" New team members can run /setup-caliber inside their coding agent"));
11150
- console.log(chalk13.dim(" (Claude Code or Cursor) to get set up automatically.\n"));
11234
+ console.log(chalk14.dim(" New team members can run /setup-caliber inside their coding agent"));
11235
+ console.log(chalk14.dim(" (Claude Code or Cursor) to get set up automatically.\n"));
11151
11236
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
11152
- console.log(chalk13.dim(" Current config score:"));
11237
+ console.log(chalk14.dim(" Current config score:"));
11153
11238
  displayScoreSummary(baselineScore);
11154
11239
  if (options.verbose) {
11155
11240
  for (const c of baselineScore.checks) {
@@ -11187,20 +11272,20 @@ async function initCommand(options) {
11187
11272
  let skipGeneration = false;
11188
11273
  if (hasExistingConfig && baselineScore.score === 100) {
11189
11274
  trackInitScoreComputed(baselineScore.score, passingCount, failingCount, true);
11190
- console.log(chalk13.bold.green("\n Your config is already optimal.\n"));
11275
+ console.log(chalk14.bold.green("\n Your config is already optimal.\n"));
11191
11276
  skipGeneration = !options.force;
11192
11277
  } else if (hasExistingConfig && !options.force && !options.autoApprove) {
11193
11278
  trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
11194
11279
  console.log(
11195
- chalk13.dim("\n Sync infrastructure is ready. Caliber can also audit your existing")
11280
+ chalk14.dim("\n Sync infrastructure is ready. Caliber can also audit your existing")
11196
11281
  );
11197
- console.log(chalk13.dim(" configs and improve them using AI.\n"));
11282
+ console.log(chalk14.dim(" configs and improve them using AI.\n"));
11198
11283
  const auditAnswer = await promptInput(" Audit and improve your existing config? (Y/n) ");
11199
11284
  skipGeneration = auditAnswer.toLowerCase() === "n";
11200
11285
  } else if (!hasExistingConfig && !options.force && !options.autoApprove) {
11201
11286
  trackInitScoreComputed(baselineScore.score, passingCount, failingCount, false);
11202
- console.log(chalk13.dim("\n Sync infrastructure is ready. Caliber can also generate tailored"));
11203
- console.log(chalk13.dim(" CLAUDE.md, Cursor rules, and Codex configs for your project.\n"));
11287
+ console.log(chalk14.dim("\n Sync infrastructure is ready. Caliber can also generate tailored"));
11288
+ console.log(chalk14.dim(" CLAUDE.md, Cursor rules, and Codex configs for your project.\n"));
11204
11289
  const generateAnswer = await promptInput(" Generate agent configs? (Y/n) ");
11205
11290
  skipGeneration = generateAnswer.toLowerCase() === "n";
11206
11291
  } else {
@@ -11217,47 +11302,47 @@ async function initCommand(options) {
11217
11302
  const claudeMdPath = "CLAUDE.md";
11218
11303
  let claudeContent = "";
11219
11304
  try {
11220
- claudeContent = fs35.readFileSync(claudeMdPath, "utf-8");
11305
+ claudeContent = fs36.readFileSync(claudeMdPath, "utf-8");
11221
11306
  } catch {
11222
11307
  }
11223
11308
  if (!claudeContent) {
11224
- claudeContent = `# ${path28.basename(process.cwd())}
11309
+ claudeContent = `# ${path29.basename(process.cwd())}
11225
11310
  `;
11226
11311
  }
11227
11312
  const updatedClaude = appendManagedBlocks2(claudeContent, "claude");
11228
- if (updatedClaude !== claudeContent || !fs35.existsSync(claudeMdPath)) {
11229
- fs35.writeFileSync(claudeMdPath, updatedClaude);
11230
- console.log(` ${chalk13.green("\u2713")} CLAUDE.md \u2014 added Caliber sync instructions`);
11313
+ if (updatedClaude !== claudeContent || !fs36.existsSync(claudeMdPath)) {
11314
+ fs36.writeFileSync(claudeMdPath, updatedClaude);
11315
+ console.log(` ${chalk14.green("\u2713")} CLAUDE.md \u2014 added Caliber sync instructions`);
11231
11316
  }
11232
11317
  if (targetAgent.includes("cursor")) {
11233
- const rulesDir = path28.join(".cursor", "rules");
11234
- if (!fs35.existsSync(rulesDir)) fs35.mkdirSync(rulesDir, { recursive: true });
11318
+ const rulesDir = path29.join(".cursor", "rules");
11319
+ if (!fs36.existsSync(rulesDir)) fs36.mkdirSync(rulesDir, { recursive: true });
11235
11320
  for (const rule of [
11236
11321
  getCursorPreCommitRule2(),
11237
11322
  getCursorLearningsRule2(),
11238
11323
  getCursorSyncRule2(),
11239
11324
  getCursorSetupRule2()
11240
11325
  ]) {
11241
- fs35.writeFileSync(path28.join(rulesDir, rule.filename), rule.content);
11326
+ fs36.writeFileSync(path29.join(rulesDir, rule.filename), rule.content);
11242
11327
  }
11243
- console.log(` ${chalk13.green("\u2713")} Cursor rules \u2014 added Caliber sync rules`);
11328
+ console.log(` ${chalk14.green("\u2713")} Cursor rules \u2014 added Caliber sync rules`);
11244
11329
  }
11245
11330
  if (targetAgent.includes("github-copilot")) {
11246
- const copilotPath = path28.join(".github", "copilot-instructions.md");
11331
+ const copilotPath = path29.join(".github", "copilot-instructions.md");
11247
11332
  let copilotContent = "";
11248
11333
  try {
11249
- copilotContent = fs35.readFileSync(copilotPath, "utf-8");
11334
+ copilotContent = fs36.readFileSync(copilotPath, "utf-8");
11250
11335
  } catch {
11251
11336
  }
11252
11337
  if (!copilotContent) {
11253
- fs35.mkdirSync(".github", { recursive: true });
11254
- copilotContent = `# ${path28.basename(process.cwd())}
11338
+ fs36.mkdirSync(".github", { recursive: true });
11339
+ copilotContent = `# ${path29.basename(process.cwd())}
11255
11340
  `;
11256
11341
  }
11257
11342
  const updatedCopilot = appendManagedBlocks2(copilotContent, "copilot");
11258
11343
  if (updatedCopilot !== copilotContent) {
11259
- fs35.writeFileSync(copilotPath, updatedCopilot);
11260
- console.log(` ${chalk13.green("\u2713")} Copilot instructions \u2014 added Caliber sync instructions`);
11344
+ fs36.writeFileSync(copilotPath, updatedCopilot);
11345
+ console.log(` ${chalk14.green("\u2713")} Copilot instructions \u2014 added Caliber sync instructions`);
11261
11346
  }
11262
11347
  }
11263
11348
  const sha2 = getCurrentHeadSha();
@@ -11267,16 +11352,16 @@ async function initCommand(options) {
11267
11352
  targetAgent
11268
11353
  });
11269
11354
  trackInitCompleted("sync-only", baselineScore.score);
11270
- console.log(chalk13.bold.green("\n Caliber sync is set up!\n"));
11271
- console.log(chalk13.dim(" Your agent configs will sync automatically on every commit."));
11355
+ console.log(chalk14.bold.green("\n Caliber sync is set up!\n"));
11356
+ console.log(chalk14.dim(" Your agent configs will sync automatically on every commit."));
11272
11357
  console.log(
11273
- chalk13.dim(" Run ") + title(`${bin} init --force`) + chalk13.dim(" anytime to generate or improve configs.\n")
11358
+ chalk14.dim(" Run ") + title(`${bin} init --force`) + chalk14.dim(" anytime to generate or improve configs.\n")
11274
11359
  );
11275
11360
  return;
11276
11361
  }
11277
11362
  console.log(title.bold("\n Step 3/4 \u2014 Generate\n"));
11278
11363
  const genModelInfo = fastModel ? ` Using ${displayModel} for docs, ${fastModel} for skills` : ` Using ${displayModel}`;
11279
- console.log(chalk13.dim(genModelInfo + "\n"));
11364
+ console.log(chalk14.dim(genModelInfo + "\n"));
11280
11365
  if (report) report.markStep("Generation");
11281
11366
  trackInitGenerationStarted(false);
11282
11367
  const genStartTime = Date.now();
@@ -11303,6 +11388,7 @@ async function initCommand(options) {
11303
11388
  try {
11304
11389
  display.update(TASK_STACK, "running");
11305
11390
  fingerprint = await collectFingerprint(process.cwd());
11391
+ printLargeFileWarnings(scanLargeFiles(process.cwd()));
11306
11392
  const stackParts = [...fingerprint.languages, ...fingerprint.frameworks];
11307
11393
  const stackSummary = stackParts.join(", ") || "no languages";
11308
11394
  const largeRepoNote = fingerprint.fileTree.length > 5e3 ? ` (${fingerprint.fileTree.length.toLocaleString()} files, smart sampling active)` : "";
@@ -11405,7 +11491,7 @@ async function initCommand(options) {
11405
11491
  onContent: (text) => {
11406
11492
  const lines = text.split("\n").filter((l) => l.trim()).slice(-8);
11407
11493
  if (lines.length > 0) {
11408
- display.setPreviewContent(lines.map((l) => ` ${chalk13.dim(l.slice(0, 80))}`));
11494
+ display.setPreviewContent(lines.map((l) => ` ${chalk14.dim(l.slice(0, 80))}`));
11409
11495
  }
11410
11496
  }
11411
11497
  },
@@ -11488,7 +11574,7 @@ async function initCommand(options) {
11488
11574
  } catch (err) {
11489
11575
  display.stop();
11490
11576
  const msg = err instanceof Error ? err.message : "Unknown error";
11491
- console.log(chalk13.red(`
11577
+ console.log(chalk14.red(`
11492
11578
  Engine failed: ${msg}
11493
11579
  `));
11494
11580
  writeErrorLog(config, void 0, msg, "exception");
@@ -11500,15 +11586,15 @@ async function initCommand(options) {
11500
11586
  const mins = Math.floor(elapsedMs / 6e4);
11501
11587
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
11502
11588
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
11503
- console.log(chalk13.dim(`
11589
+ console.log(chalk14.dim(`
11504
11590
  Done in ${timeStr}
11505
11591
  `));
11506
11592
  if (!generatedSetup) {
11507
- console.log(chalk13.red(" Failed to generate config."));
11593
+ console.log(chalk14.red(" Failed to generate config."));
11508
11594
  writeErrorLog(config, rawOutput, void 0, genStopReason);
11509
11595
  if (rawOutput) {
11510
- console.log(chalk13.dim("\nRaw LLM output (JSON parse failed):"));
11511
- console.log(chalk13.dim(rawOutput.slice(0, 500)));
11596
+ console.log(chalk14.dim("\nRaw LLM output (JSON parse failed):"));
11597
+ console.log(chalk14.dim(rawOutput.slice(0, 500)));
11512
11598
  }
11513
11599
  throw new Error("__exit__");
11514
11600
  }
@@ -11527,19 +11613,19 @@ async function initCommand(options) {
11527
11613
  const changes = formatWhatChanged(generatedSetup);
11528
11614
  if (changes.length > 0) {
11529
11615
  for (const line of changes) {
11530
- console.log(` ${chalk13.dim("\u2022")} ${line}`);
11616
+ console.log(` ${chalk14.dim("\u2022")} ${line}`);
11531
11617
  }
11532
11618
  console.log("");
11533
11619
  }
11534
11620
  console.log(
11535
- chalk13.dim(
11536
- ` ${chalk13.green(`${staged.newFiles} new`)} / ${chalk13.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}`
11621
+ chalk14.dim(
11622
+ ` ${chalk14.green(`${staged.newFiles} new`)} / ${chalk14.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}`
11537
11623
  )
11538
11624
  );
11539
11625
  if (skillSearchResult.results.length > 0) {
11540
11626
  console.log(
11541
- chalk13.dim(
11542
- ` ${chalk13.cyan(`${skillSearchResult.results.length}`)} community skills available to install
11627
+ chalk14.dim(
11628
+ ` ${chalk14.cyan(`${skillSearchResult.results.length}`)} community skills available to install
11543
11629
  `
11544
11630
  )
11545
11631
  );
@@ -11549,7 +11635,7 @@ async function initCommand(options) {
11549
11635
  const hasSkillResults = skillSearchResult.results.length > 0;
11550
11636
  let action;
11551
11637
  if (totalChanges === 0 && !hasSkillResults) {
11552
- console.log(chalk13.dim(" No changes needed \u2014 your configs are already up to date.\n"));
11638
+ console.log(chalk14.dim(" No changes needed \u2014 your configs are already up to date.\n"));
11553
11639
  cleanupStaging();
11554
11640
  action = "accept";
11555
11641
  } else if (options.autoApprove) {
@@ -11573,14 +11659,14 @@ async function initCommand(options) {
11573
11659
  trackInitRefinementRound(refinementRound, !!generatedSetup);
11574
11660
  if (!generatedSetup) {
11575
11661
  cleanupStaging();
11576
- console.log(chalk13.dim("Refinement cancelled. No files were modified."));
11662
+ console.log(chalk14.dim("Refinement cancelled. No files were modified."));
11577
11663
  return;
11578
11664
  }
11579
11665
  const updatedFiles = collectSetupFiles(generatedSetup, targetAgent);
11580
11666
  const restaged = stageFiles(updatedFiles, process.cwd());
11581
11667
  console.log(
11582
- chalk13.dim(
11583
- ` ${chalk13.green(`${restaged.newFiles} new`)} / ${chalk13.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
11668
+ chalk14.dim(
11669
+ ` ${chalk14.green(`${restaged.newFiles} new`)} / ${chalk14.yellow(`${restaged.modifiedFiles} modified`)} file${restaged.newFiles + restaged.modifiedFiles !== 1 ? "s" : ""}
11584
11670
  `
11585
11671
  )
11586
11672
  );
@@ -11592,18 +11678,18 @@ async function initCommand(options) {
11592
11678
  }
11593
11679
  cleanupStaging();
11594
11680
  if (action === "decline") {
11595
- console.log(chalk13.dim("Declined. No files were modified."));
11681
+ console.log(chalk14.dim("Declined. No files were modified."));
11596
11682
  return;
11597
11683
  }
11598
11684
  if (options.dryRun) {
11599
- console.log(chalk13.yellow("\n[Dry run] Would write the following files:"));
11685
+ console.log(chalk14.yellow("\n[Dry run] Would write the following files:"));
11600
11686
  console.log(JSON.stringify(generatedSetup, null, 2));
11601
11687
  return;
11602
11688
  }
11603
11689
  const { default: ora9 } = await import("ora");
11604
11690
  const writeSpinner = ora9("Writing config files...").start();
11605
11691
  try {
11606
- if (targetAgent.includes("codex") && !fs35.existsSync("AGENTS.md") && !generatedSetup.codex) {
11692
+ if (targetAgent.includes("codex") && !fs36.existsSync("AGENTS.md") && !generatedSetup.codex) {
11607
11693
  const claude = generatedSetup.claude;
11608
11694
  const cursor = generatedSetup.cursor;
11609
11695
  const agentRefs = [];
@@ -11627,23 +11713,23 @@ ${agentRefs.join(" ")}
11627
11713
  0,
11628
11714
  result.deleted.length
11629
11715
  );
11630
- console.log(chalk13.bold("\nFiles created/updated:"));
11716
+ console.log(chalk14.bold("\nFiles created/updated:"));
11631
11717
  for (const file of result.written) {
11632
- console.log(` ${chalk13.green("\u2713")} ${file}`);
11718
+ console.log(` ${chalk14.green("\u2713")} ${file}`);
11633
11719
  }
11634
11720
  if (result.deleted.length > 0) {
11635
- console.log(chalk13.bold("\nFiles removed:"));
11721
+ console.log(chalk14.bold("\nFiles removed:"));
11636
11722
  for (const file of result.deleted) {
11637
- console.log(` ${chalk13.red("\u2717")} ${file}`);
11723
+ console.log(` ${chalk14.red("\u2717")} ${file}`);
11638
11724
  }
11639
11725
  }
11640
11726
  if (result.backupDir) {
11641
- console.log(chalk13.dim(`
11727
+ console.log(chalk14.dim(`
11642
11728
  Backups saved to ${result.backupDir}`));
11643
11729
  }
11644
11730
  } catch (err) {
11645
11731
  writeSpinner.fail("Failed to write files");
11646
- console.error(chalk13.red(err instanceof Error ? err.message : "Unknown error"));
11732
+ console.error(chalk14.red(err instanceof Error ? err.message : "Unknown error"));
11647
11733
  throw new Error("__exit__");
11648
11734
  }
11649
11735
  if (fingerprint) ensurePermissions(fingerprint);
@@ -11658,7 +11744,7 @@ ${agentRefs.join(" ")}
11658
11744
  trackInitScoreRegression(baselineScore.score, afterScore.score);
11659
11745
  console.log("");
11660
11746
  console.log(
11661
- chalk13.yellow(
11747
+ chalk14.yellow(
11662
11748
  ` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`
11663
11749
  )
11664
11750
  );
@@ -11666,7 +11752,7 @@ ${agentRefs.join(" ")}
11666
11752
  const { restored, removed } = undoSetup();
11667
11753
  if (restored.length > 0 || removed.length > 0) {
11668
11754
  console.log(
11669
- chalk13.dim(
11755
+ chalk14.dim(
11670
11756
  ` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`
11671
11757
  )
11672
11758
  );
@@ -11674,7 +11760,7 @@ ${agentRefs.join(" ")}
11674
11760
  } catch {
11675
11761
  }
11676
11762
  console.log(
11677
- chalk13.dim(" Run ") + chalk13.hex("#83D1EB")(`${bin} init --force`) + chalk13.dim(" to override.\n")
11763
+ chalk14.dim(" Run ") + chalk14.hex("#83D1EB")(`${bin} init --force`) + chalk14.dim(" to override.\n")
11678
11764
  );
11679
11765
  return;
11680
11766
  }
@@ -11705,7 +11791,7 @@ ${agentRefs.join(" ")}
11705
11791
  }
11706
11792
  let communitySkillsInstalled = 0;
11707
11793
  if (skillSearchResult.results.length > 0 && !options.autoApprove) {
11708
- console.log(chalk13.dim(" Community skills matched to your project:\n"));
11794
+ console.log(chalk14.dim(" Community skills matched to your project:\n"));
11709
11795
  const selected = await interactiveSelect(skillSearchResult.results);
11710
11796
  if (selected?.length) {
11711
11797
  await installSkills(selected, targetAgent, skillSearchResult.contentMap);
@@ -11714,32 +11800,32 @@ ${agentRefs.join(" ")}
11714
11800
  }
11715
11801
  }
11716
11802
  trackInitHookSelected("config-instructions");
11717
- const done = chalk13.green("\u2713");
11718
- console.log(chalk13.bold.green("\n Caliber is set up!\n"));
11719
- console.log(chalk13.bold(" What's configured:\n"));
11803
+ const done = chalk14.green("\u2713");
11804
+ console.log(chalk14.bold.green("\n Caliber is set up!\n"));
11805
+ console.log(chalk14.bold(" What's configured:\n"));
11720
11806
  console.log(
11721
- ` ${done} Continuous sync ${chalk13.dim("pre-commit hook keeps all agent configs in sync")}`
11807
+ ` ${done} Continuous sync ${chalk14.dim("pre-commit hook keeps all agent configs in sync")}`
11722
11808
  );
11723
11809
  console.log(
11724
- ` ${done} Config generated ${title(`${bin} score`)} ${chalk13.dim("for full breakdown")}`
11810
+ ` ${done} Config generated ${title(`${bin} score`)} ${chalk14.dim("for full breakdown")}`
11725
11811
  );
11726
11812
  console.log(
11727
- ` ${done} Agent skills ${chalk13.dim("/setup-caliber for new team members")}`
11813
+ ` ${done} Agent skills ${chalk14.dim("/setup-caliber for new team members")}`
11728
11814
  );
11729
11815
  if (hasLearnableAgent) {
11730
11816
  console.log(
11731
- ` ${done} Session learning ${chalk13.dim("agent learns from your feedback")}`
11817
+ ` ${done} Session learning ${chalk14.dim("agent learns from your feedback")}`
11732
11818
  );
11733
11819
  }
11734
11820
  if (communitySkillsInstalled > 0) {
11735
11821
  console.log(
11736
- ` ${done} Community skills ${chalk13.dim(`${communitySkillsInstalled} skill${communitySkillsInstalled > 1 ? "s" : ""} installed for your stack`)}`
11822
+ ` ${done} Community skills ${chalk14.dim(`${communitySkillsInstalled} skill${communitySkillsInstalled > 1 ? "s" : ""} installed for your stack`)}`
11737
11823
  );
11738
11824
  }
11739
- console.log(chalk13.bold("\n What happens next:\n"));
11740
- console.log(chalk13.dim(" Every commit will automatically sync your agent configs."));
11741
- console.log(chalk13.dim(" New team members can run /setup-caliber to get set up instantly.\n"));
11742
- console.log(chalk13.bold(" Explore:\n"));
11825
+ console.log(chalk14.bold("\n What happens next:\n"));
11826
+ console.log(chalk14.dim(" Every commit will automatically sync your agent configs."));
11827
+ console.log(chalk14.dim(" New team members can run /setup-caliber to get set up instantly.\n"));
11828
+ console.log(chalk14.bold(" Explore:\n"));
11743
11829
  console.log(` ${title(`${bin} score`)} Full scoring breakdown with improvement tips`);
11744
11830
  console.log(` ${title(`${bin} skills`)} Find community skills for your stack`);
11745
11831
  console.log(` ${title(`${bin} undo`)} Revert all changes from this run`);
@@ -11750,17 +11836,17 @@ ${agentRefs.join(" ")}
11750
11836
  }
11751
11837
  if (report) {
11752
11838
  report.markStep("Finished");
11753
- const reportPath = path28.join(process.cwd(), ".caliber", "debug-report.md");
11839
+ const reportPath = path29.join(process.cwd(), ".caliber", "debug-report.md");
11754
11840
  report.write(reportPath);
11755
11841
  console.log(
11756
- chalk13.dim(` Debug report written to ${path28.relative(process.cwd(), reportPath)}
11842
+ chalk14.dim(` Debug report written to ${path29.relative(process.cwd(), reportPath)}
11757
11843
  `)
11758
11844
  );
11759
11845
  }
11760
11846
  }
11761
11847
 
11762
11848
  // src/commands/undo.ts
11763
- import chalk14 from "chalk";
11849
+ import chalk15 from "chalk";
11764
11850
  import ora4 from "ora";
11765
11851
  function undoCommand() {
11766
11852
  const spinner = ora4("Reverting config changes...").start();
@@ -11773,27 +11859,27 @@ function undoCommand() {
11773
11859
  trackUndoExecuted();
11774
11860
  spinner.succeed("Config reverted successfully.\n");
11775
11861
  if (restored.length > 0) {
11776
- console.log(chalk14.cyan(" Restored from backup:"));
11862
+ console.log(chalk15.cyan(" Restored from backup:"));
11777
11863
  for (const file of restored) {
11778
- console.log(` ${chalk14.green("\u21A9")} ${file}`);
11864
+ console.log(` ${chalk15.green("\u21A9")} ${file}`);
11779
11865
  }
11780
11866
  }
11781
11867
  if (removed.length > 0) {
11782
- console.log(chalk14.cyan(" Removed:"));
11868
+ console.log(chalk15.cyan(" Removed:"));
11783
11869
  for (const file of removed) {
11784
- console.log(` ${chalk14.red("\u2717")} ${file}`);
11870
+ console.log(` ${chalk15.red("\u2717")} ${file}`);
11785
11871
  }
11786
11872
  }
11787
11873
  console.log("");
11788
11874
  } catch (err) {
11789
- spinner.fail(chalk14.red(err instanceof Error ? err.message : "Undo failed"));
11875
+ spinner.fail(chalk15.red(err instanceof Error ? err.message : "Undo failed"));
11790
11876
  throw new Error("__exit__");
11791
11877
  }
11792
11878
  }
11793
11879
 
11794
11880
  // src/commands/status.ts
11795
- import chalk15 from "chalk";
11796
- import fs36 from "fs";
11881
+ import chalk16 from "chalk";
11882
+ import fs37 from "fs";
11797
11883
  init_config();
11798
11884
  init_resolve_caliber();
11799
11885
  async function statusCommand(options) {
@@ -11808,29 +11894,29 @@ async function statusCommand(options) {
11808
11894
  }, null, 2));
11809
11895
  return;
11810
11896
  }
11811
- console.log(chalk15.bold("\nCaliber Status\n"));
11897
+ console.log(chalk16.bold("\nCaliber Status\n"));
11812
11898
  if (config) {
11813
- console.log(` LLM: ${chalk15.green(config.provider)} (${config.model})`);
11899
+ console.log(` LLM: ${chalk16.green(config.provider)} (${config.model})`);
11814
11900
  } else {
11815
11901
  const bin = resolveCaliber();
11816
- console.log(` LLM: ${chalk15.yellow("Not configured")} \u2014 run ${chalk15.hex("#83D1EB")(`${bin} config`)}`);
11902
+ console.log(` LLM: ${chalk16.yellow("Not configured")} \u2014 run ${chalk16.hex("#83D1EB")(`${bin} config`)}`);
11817
11903
  }
11818
11904
  if (!manifest) {
11819
- console.log(` Config: ${chalk15.dim("No config applied")}`);
11820
- console.log(chalk15.dim("\n Run ") + chalk15.hex("#83D1EB")(`${resolveCaliber()} init`) + chalk15.dim(" to get started.\n"));
11905
+ console.log(` Config: ${chalk16.dim("No config applied")}`);
11906
+ console.log(chalk16.dim("\n Run ") + chalk16.hex("#83D1EB")(`${resolveCaliber()} init`) + chalk16.dim(" to get started.\n"));
11821
11907
  return;
11822
11908
  }
11823
- console.log(` Files managed: ${chalk15.cyan(manifest.entries.length.toString())}`);
11909
+ console.log(` Files managed: ${chalk16.cyan(manifest.entries.length.toString())}`);
11824
11910
  for (const entry of manifest.entries) {
11825
- const exists = fs36.existsSync(entry.path);
11826
- const icon = exists ? chalk15.green("\u2713") : chalk15.red("\u2717");
11911
+ const exists = fs37.existsSync(entry.path);
11912
+ const icon = exists ? chalk16.green("\u2713") : chalk16.red("\u2717");
11827
11913
  console.log(` ${icon} ${entry.path} (${entry.action})`);
11828
11914
  }
11829
11915
  console.log("");
11830
11916
  }
11831
11917
 
11832
11918
  // src/commands/regenerate.ts
11833
- import chalk16 from "chalk";
11919
+ import chalk17 from "chalk";
11834
11920
  import ora5 from "ora";
11835
11921
  import select6 from "@inquirer/select";
11836
11922
  init_review();
@@ -11840,12 +11926,12 @@ async function regenerateCommand(options) {
11840
11926
  const bin = resolveCaliber();
11841
11927
  const config = loadConfig();
11842
11928
  if (!config) {
11843
- console.log(chalk16.red("No LLM provider configured. Run ") + chalk16.hex("#83D1EB")(`${bin} config`) + chalk16.red(" first."));
11929
+ console.log(chalk17.red("No LLM provider configured. Run ") + chalk17.hex("#83D1EB")(`${bin} config`) + chalk17.red(" first."));
11844
11930
  throw new Error("__exit__");
11845
11931
  }
11846
11932
  const manifest = readManifest();
11847
11933
  if (!manifest) {
11848
- console.log(chalk16.yellow("No existing config found. Run ") + chalk16.hex("#83D1EB")(`${bin} init`) + chalk16.yellow(" first."));
11934
+ console.log(chalk17.yellow("No existing config found. Run ") + chalk17.hex("#83D1EB")(`${bin} init`) + chalk17.yellow(" first."));
11849
11935
  throw new Error("__exit__");
11850
11936
  }
11851
11937
  const targetAgent = readState()?.targetAgent ?? ["claude", "cursor"];
@@ -11856,7 +11942,7 @@ async function regenerateCommand(options) {
11856
11942
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
11857
11943
  displayScoreSummary(baselineScore);
11858
11944
  if (baselineScore.score === 100) {
11859
- console.log(chalk16.green(" Your config is already at 100/100 \u2014 nothing to regenerate.\n"));
11945
+ console.log(chalk17.green(" Your config is already at 100/100 \u2014 nothing to regenerate.\n"));
11860
11946
  return;
11861
11947
  }
11862
11948
  const genSpinner = ora5("Regenerating config...").start();
@@ -11898,18 +11984,18 @@ async function regenerateCommand(options) {
11898
11984
  const setupFiles = collectSetupFiles(generatedSetup, targetAgent);
11899
11985
  const staged = stageFiles(setupFiles, process.cwd());
11900
11986
  const totalChanges = staged.newFiles + staged.modifiedFiles;
11901
- console.log(chalk16.dim(`
11902
- ${chalk16.green(`${staged.newFiles} new`)} / ${chalk16.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
11987
+ console.log(chalk17.dim(`
11988
+ ${chalk17.green(`${staged.newFiles} new`)} / ${chalk17.yellow(`${staged.modifiedFiles} modified`)} file${totalChanges !== 1 ? "s" : ""}
11903
11989
  `));
11904
11990
  if (totalChanges === 0) {
11905
- console.log(chalk16.dim(" No changes needed \u2014 your configs are already up to date.\n"));
11991
+ console.log(chalk17.dim(" No changes needed \u2014 your configs are already up to date.\n"));
11906
11992
  cleanupStaging();
11907
11993
  return;
11908
11994
  }
11909
11995
  if (options.dryRun) {
11910
- console.log(chalk16.yellow("[Dry run] Would write:"));
11996
+ console.log(chalk17.yellow("[Dry run] Would write:"));
11911
11997
  for (const f of staged.stagedFiles) {
11912
- console.log(` ${f.isNew ? chalk16.green("+") : chalk16.yellow("~")} ${f.relativePath}`);
11998
+ console.log(` ${f.isNew ? chalk17.green("+") : chalk17.yellow("~")} ${f.relativePath}`);
11913
11999
  }
11914
12000
  cleanupStaging();
11915
12001
  return;
@@ -11928,7 +12014,7 @@ async function regenerateCommand(options) {
11928
12014
  });
11929
12015
  cleanupStaging();
11930
12016
  if (action === "decline") {
11931
- console.log(chalk16.dim("Regeneration cancelled. No files were modified."));
12017
+ console.log(chalk17.dim("Regeneration cancelled. No files were modified."));
11932
12018
  return;
11933
12019
  }
11934
12020
  const writeSpinner = ora5("Writing config files...").start();
@@ -11936,20 +12022,20 @@ async function regenerateCommand(options) {
11936
12022
  const result = writeSetup(generatedSetup);
11937
12023
  writeSpinner.succeed("Config files written");
11938
12024
  for (const file of result.written) {
11939
- console.log(` ${chalk16.green("\u2713")} ${file}`);
12025
+ console.log(` ${chalk17.green("\u2713")} ${file}`);
11940
12026
  }
11941
12027
  if (result.deleted.length > 0) {
11942
12028
  for (const file of result.deleted) {
11943
- console.log(` ${chalk16.red("\u2717")} ${file}`);
12029
+ console.log(` ${chalk17.red("\u2717")} ${file}`);
11944
12030
  }
11945
12031
  }
11946
12032
  if (result.backupDir) {
11947
- console.log(chalk16.dim(`
12033
+ console.log(chalk17.dim(`
11948
12034
  Backups saved to ${result.backupDir}`));
11949
12035
  }
11950
12036
  } catch (err) {
11951
12037
  writeSpinner.fail("Failed to write files");
11952
- console.error(chalk16.red(err instanceof Error ? err.message : "Unknown error"));
12038
+ console.error(chalk17.red(err instanceof Error ? err.message : "Unknown error"));
11953
12039
  throw new Error("__exit__");
11954
12040
  }
11955
12041
  const sha = getCurrentHeadSha();
@@ -11961,35 +12047,35 @@ async function regenerateCommand(options) {
11961
12047
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
11962
12048
  if (afterScore.score < baselineScore.score) {
11963
12049
  console.log("");
11964
- console.log(chalk16.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
12050
+ console.log(chalk17.yellow(` Score would drop from ${baselineScore.score} to ${afterScore.score} \u2014 reverting changes.`));
11965
12051
  try {
11966
12052
  const { restored, removed } = undoSetup();
11967
12053
  if (restored.length > 0 || removed.length > 0) {
11968
- console.log(chalk16.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
12054
+ console.log(chalk17.dim(` Reverted ${restored.length + removed.length} file${restored.length + removed.length === 1 ? "" : "s"} from backup.`));
11969
12055
  }
11970
12056
  } catch {
11971
12057
  }
11972
- console.log(chalk16.dim(" Run ") + chalk16.hex("#83D1EB")(`${bin} init --force`) + chalk16.dim(" to override.\n"));
12058
+ console.log(chalk17.dim(" Run ") + chalk17.hex("#83D1EB")(`${bin} init --force`) + chalk17.dim(" to override.\n"));
11973
12059
  return;
11974
12060
  }
11975
12061
  displayScoreDelta(baselineScore, afterScore);
11976
12062
  trackRegenerateCompleted(action, Date.now());
11977
- console.log(chalk16.bold.green(" Regeneration complete!"));
11978
- console.log(chalk16.dim(" Run ") + chalk16.hex("#83D1EB")(`${bin} undo`) + chalk16.dim(" to revert changes.\n"));
12063
+ console.log(chalk17.bold.green(" Regeneration complete!"));
12064
+ console.log(chalk17.dim(" Run ") + chalk17.hex("#83D1EB")(`${bin} undo`) + chalk17.dim(" to revert changes.\n"));
11979
12065
  }
11980
12066
 
11981
12067
  // src/commands/score.ts
11982
- import fs37 from "fs";
12068
+ import fs38 from "fs";
11983
12069
  import os7 from "os";
11984
- import path29 from "path";
12070
+ import path30 from "path";
11985
12071
  import { execFileSync as execFileSync4 } from "child_process";
11986
- import chalk17 from "chalk";
12072
+ import chalk18 from "chalk";
11987
12073
  init_resolve_caliber();
11988
12074
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".cursorrules", "CALIBER_LEARNINGS.md"];
11989
12075
  var CONFIG_DIRS = [".claude", ".cursor"];
11990
12076
  function scoreBaseRef(ref, target) {
11991
12077
  if (!/^[\w.\-/~^@{}]+$/.test(ref)) return null;
11992
- const tmpDir = fs37.mkdtempSync(path29.join(os7.tmpdir(), "caliber-compare-"));
12078
+ const tmpDir = fs38.mkdtempSync(path30.join(os7.tmpdir(), "caliber-compare-"));
11993
12079
  try {
11994
12080
  for (const file of CONFIG_FILES) {
11995
12081
  try {
@@ -11997,7 +12083,7 @@ function scoreBaseRef(ref, target) {
11997
12083
  encoding: "utf-8",
11998
12084
  stdio: ["pipe", "pipe", "pipe"]
11999
12085
  });
12000
- fs37.writeFileSync(path29.join(tmpDir, file), content);
12086
+ fs38.writeFileSync(path30.join(tmpDir, file), content);
12001
12087
  } catch {
12002
12088
  }
12003
12089
  }
@@ -12008,13 +12094,13 @@ function scoreBaseRef(ref, target) {
12008
12094
  stdio: ["pipe", "pipe", "pipe"]
12009
12095
  }).trim().split("\n").filter(Boolean);
12010
12096
  for (const file of files) {
12011
- const filePath = path29.join(tmpDir, file);
12012
- fs37.mkdirSync(path29.dirname(filePath), { recursive: true });
12097
+ const filePath = path30.join(tmpDir, file);
12098
+ fs38.mkdirSync(path30.dirname(filePath), { recursive: true });
12013
12099
  const content = execFileSync4("git", ["show", `${ref}:${file}`], {
12014
12100
  encoding: "utf-8",
12015
12101
  stdio: ["pipe", "pipe", "pipe"]
12016
12102
  });
12017
- fs37.writeFileSync(filePath, content);
12103
+ fs38.writeFileSync(filePath, content);
12018
12104
  }
12019
12105
  } catch {
12020
12106
  }
@@ -12024,7 +12110,7 @@ function scoreBaseRef(ref, target) {
12024
12110
  } catch {
12025
12111
  return null;
12026
12112
  } finally {
12027
- fs37.rmSync(tmpDir, { recursive: true, force: true });
12113
+ fs38.rmSync(tmpDir, { recursive: true, force: true });
12028
12114
  }
12029
12115
  }
12030
12116
  async function scoreCommand(options) {
@@ -12037,7 +12123,7 @@ async function scoreCommand(options) {
12037
12123
  const baseResult = scoreBaseRef(options.compare, target);
12038
12124
  if (!baseResult) {
12039
12125
  console.error(
12040
- chalk17.red(`Could not score ref "${options.compare}" \u2014 branch or ref not found.`)
12126
+ chalk18.red(`Could not score ref "${options.compare}" \u2014 branch or ref not found.`)
12041
12127
  );
12042
12128
  process.exitCode = 1;
12043
12129
  return;
@@ -12063,18 +12149,18 @@ async function scoreCommand(options) {
12063
12149
  return;
12064
12150
  }
12065
12151
  displayScore(result);
12066
- const separator2 = chalk17.gray(" " + "\u2500".repeat(53));
12152
+ const separator2 = chalk18.gray(" " + "\u2500".repeat(53));
12067
12153
  console.log(separator2);
12068
12154
  if (delta > 0) {
12069
12155
  console.log(
12070
- chalk17.green(` +${delta}`) + chalk17.gray(` from ${options.compare} (${baseResult.score}/100)`)
12156
+ chalk18.green(` +${delta}`) + chalk18.gray(` from ${options.compare} (${baseResult.score}/100)`)
12071
12157
  );
12072
12158
  } else if (delta < 0) {
12073
12159
  console.log(
12074
- chalk17.red(` ${delta}`) + chalk17.gray(` from ${options.compare} (${baseResult.score}/100)`)
12160
+ chalk18.red(` ${delta}`) + chalk18.gray(` from ${options.compare} (${baseResult.score}/100)`)
12075
12161
  );
12076
12162
  } else {
12077
- console.log(chalk17.gray(` No change from ${options.compare} (${baseResult.score}/100)`));
12163
+ console.log(chalk18.gray(` No change from ${options.compare} (${baseResult.score}/100)`));
12078
12164
  }
12079
12165
  console.log("");
12080
12166
  return;
@@ -12088,7 +12174,7 @@ async function scoreCommand(options) {
12088
12174
  return;
12089
12175
  }
12090
12176
  displayScore(result);
12091
- const separator = chalk17.gray(" " + "\u2500".repeat(53));
12177
+ const separator = chalk18.gray(" " + "\u2500".repeat(53));
12092
12178
  console.log(separator);
12093
12179
  const bin = resolveCaliber();
12094
12180
  const failing = result.checks.filter((c) => !c.passed && c.maxPoints > 0).sort((a, b) => b.maxPoints - b.earnedPoints - (a.maxPoints - a.earnedPoints));
@@ -12096,30 +12182,30 @@ async function scoreCommand(options) {
12096
12182
  const topFix = failing[0];
12097
12183
  const pts = topFix.maxPoints - topFix.earnedPoints;
12098
12184
  console.log(
12099
- chalk17.gray(" Biggest gain: ") + chalk17.yellow(`+${pts} pts`) + chalk17.gray(` from "${topFix.name}"`) + (topFix.suggestion ? chalk17.gray(` \u2014 ${topFix.suggestion}`) : "")
12185
+ chalk18.gray(" Biggest gain: ") + chalk18.yellow(`+${pts} pts`) + chalk18.gray(` from "${topFix.name}"`) + (topFix.suggestion ? chalk18.gray(` \u2014 ${topFix.suggestion}`) : "")
12100
12186
  );
12101
12187
  console.log(
12102
- chalk17.gray(" Run ") + chalk17.hex("#83D1EB")(`${bin} init`) + chalk17.gray(" to generate or update your agent config files.")
12188
+ chalk18.gray(" Run ") + chalk18.hex("#83D1EB")(`${bin} init`) + chalk18.gray(" to generate or update your agent config files.")
12103
12189
  );
12104
12190
  } else if (failing.length > 0) {
12105
12191
  console.log(
12106
- chalk17.green(" Looking good!") + chalk17.gray(
12192
+ chalk18.green(" Looking good!") + chalk18.gray(
12107
12193
  ` ${failing.length} optional improvement${failing.length === 1 ? "" : "s"} available.`
12108
12194
  )
12109
12195
  );
12110
12196
  console.log(
12111
- chalk17.gray(" Run ") + chalk17.hex("#83D1EB")(`${bin} init`) + chalk17.gray(" to improve, or ") + chalk17.hex("#83D1EB")(`${bin} regenerate`) + chalk17.gray(" to rebuild from scratch.")
12197
+ chalk18.gray(" Run ") + chalk18.hex("#83D1EB")(`${bin} init`) + chalk18.gray(" to improve, or ") + chalk18.hex("#83D1EB")(`${bin} regenerate`) + chalk18.gray(" to rebuild from scratch.")
12112
12198
  );
12113
12199
  } else {
12114
- console.log(chalk17.green(" Perfect score! Your agent configs are fully optimized."));
12200
+ console.log(chalk18.green(" Perfect score! Your agent configs are fully optimized."));
12115
12201
  }
12116
12202
  console.log("");
12117
12203
  }
12118
12204
 
12119
12205
  // src/commands/refresh.ts
12120
- import fs42 from "fs";
12121
- import path34 from "path";
12122
- import chalk18 from "chalk";
12206
+ import fs43 from "fs";
12207
+ import path35 from "path";
12208
+ import chalk19 from "chalk";
12123
12209
  import ora6 from "ora";
12124
12210
  import pLimit from "p-limit";
12125
12211
 
@@ -12233,62 +12319,62 @@ function scopeDiffToDir(diff, dir, allConfigDirs) {
12233
12319
 
12234
12320
  // src/writers/refresh.ts
12235
12321
  init_pre_commit_block();
12236
- import fs38 from "fs";
12237
- import path30 from "path";
12322
+ import fs39 from "fs";
12323
+ import path31 from "path";
12238
12324
  function writeFileGroup(groupDir, files) {
12239
- fs38.mkdirSync(groupDir, { recursive: true });
12325
+ fs39.mkdirSync(groupDir, { recursive: true });
12240
12326
  return files.map((file) => {
12241
- const filePath = path30.join(groupDir, file.filename);
12242
- fs38.writeFileSync(filePath, file.content);
12327
+ const filePath = path31.join(groupDir, file.filename);
12328
+ fs39.writeFileSync(filePath, file.content);
12243
12329
  return filePath.replace(/\\/g, "/");
12244
12330
  });
12245
12331
  }
12246
12332
  function writeRefreshDocs(docs, dir = ".") {
12247
12333
  const written = [];
12248
- const p = (relPath) => (dir === "." ? relPath : path30.join(dir, relPath)).replace(/\\/g, "/");
12334
+ const p = (relPath) => (dir === "." ? relPath : path31.join(dir, relPath)).replace(/\\/g, "/");
12249
12335
  const ensureParent = (filePath) => {
12250
- const parent = path30.dirname(filePath);
12251
- if (parent !== "." && !fs38.existsSync(parent)) fs38.mkdirSync(parent, { recursive: true });
12336
+ const parent = path31.dirname(filePath);
12337
+ if (parent !== "." && !fs39.existsSync(parent)) fs39.mkdirSync(parent, { recursive: true });
12252
12338
  };
12253
12339
  if (docs.agentsMd) {
12254
12340
  const filePath = p("AGENTS.md");
12255
12341
  ensureParent(filePath);
12256
- fs38.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex"));
12342
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.agentsMd, "codex"));
12257
12343
  written.push(filePath);
12258
12344
  }
12259
12345
  if (docs.claudeMd) {
12260
12346
  const filePath = p("CLAUDE.md");
12261
12347
  ensureParent(filePath);
12262
- fs38.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd));
12348
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.claudeMd));
12263
12349
  written.push(filePath);
12264
12350
  }
12265
12351
  if (docs.claudeRules) {
12266
- written.push(...writeFileGroup(p(path30.join(".claude", "rules")), docs.claudeRules));
12352
+ written.push(...writeFileGroup(p(path31.join(".claude", "rules")), docs.claudeRules));
12267
12353
  }
12268
12354
  if (docs.readmeMd) {
12269
12355
  const filePath = p("README.md");
12270
12356
  ensureParent(filePath);
12271
- fs38.writeFileSync(filePath, docs.readmeMd);
12357
+ fs39.writeFileSync(filePath, docs.readmeMd);
12272
12358
  written.push(filePath);
12273
12359
  }
12274
12360
  if (docs.cursorrules) {
12275
12361
  const filePath = p(".cursorrules");
12276
12362
  ensureParent(filePath);
12277
- fs38.writeFileSync(filePath, docs.cursorrules);
12363
+ fs39.writeFileSync(filePath, docs.cursorrules);
12278
12364
  written.push(filePath);
12279
12365
  }
12280
12366
  if (docs.cursorRules) {
12281
- written.push(...writeFileGroup(p(path30.join(".cursor", "rules")), docs.cursorRules));
12367
+ written.push(...writeFileGroup(p(path31.join(".cursor", "rules")), docs.cursorRules));
12282
12368
  }
12283
12369
  if (docs.copilotInstructions) {
12284
- const filePath = p(path30.join(".github", "copilot-instructions.md"));
12370
+ const filePath = p(path31.join(".github", "copilot-instructions.md"));
12285
12371
  ensureParent(filePath);
12286
- fs38.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot"));
12372
+ fs39.writeFileSync(filePath, appendManagedBlocks(docs.copilotInstructions, "copilot"));
12287
12373
  written.push(filePath);
12288
12374
  }
12289
12375
  if (docs.copilotInstructionFiles) {
12290
12376
  written.push(
12291
- ...writeFileGroup(p(path30.join(".github", "instructions")), docs.copilotInstructionFiles)
12377
+ ...writeFileGroup(p(path31.join(".github", "instructions")), docs.copilotInstructionFiles)
12292
12378
  );
12293
12379
  }
12294
12380
  return written;
@@ -12442,8 +12528,8 @@ Changed files: ${diff.changedFiles.join(", ")}`);
12442
12528
  }
12443
12529
 
12444
12530
  // src/learner/writer.ts
12445
- import fs39 from "fs";
12446
- import path31 from "path";
12531
+ import fs40 from "fs";
12532
+ import path32 from "path";
12447
12533
 
12448
12534
  // src/learner/utils.ts
12449
12535
  var TYPE_PREFIX_RE = /^\*\*\[[^\]]+\]\*\*\s*/;
@@ -12560,20 +12646,20 @@ function deduplicateLearnedItems(existing, incoming) {
12560
12646
  }
12561
12647
  function writeLearnedSectionTo(filePath, header, existing, incoming, mode) {
12562
12648
  const { merged, newCount, newItems } = deduplicateLearnedItems(existing, incoming);
12563
- fs39.writeFileSync(filePath, header + merged + "\n");
12564
- if (mode) fs39.chmodSync(filePath, mode);
12649
+ fs40.writeFileSync(filePath, header + merged + "\n");
12650
+ if (mode) fs40.chmodSync(filePath, mode);
12565
12651
  return { newCount, newItems };
12566
12652
  }
12567
12653
  function writeLearnedSection(content) {
12568
12654
  return writeLearnedSectionTo(LEARNINGS_FILE, LEARNINGS_HEADER, readLearnedSection(), content);
12569
12655
  }
12570
12656
  function writeLearnedSkill(skill) {
12571
- const skillDir = path31.join(".claude", "skills", skill.name);
12572
- if (!fs39.existsSync(skillDir)) fs39.mkdirSync(skillDir, { recursive: true });
12573
- const skillPath = path31.join(skillDir, "SKILL.md");
12574
- if (!skill.isNew && fs39.existsSync(skillPath)) {
12575
- const existing = fs39.readFileSync(skillPath, "utf-8");
12576
- fs39.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
12657
+ const skillDir = path32.join(".claude", "skills", skill.name);
12658
+ if (!fs40.existsSync(skillDir)) fs40.mkdirSync(skillDir, { recursive: true });
12659
+ const skillPath = path32.join(skillDir, "SKILL.md");
12660
+ if (!skill.isNew && fs40.existsSync(skillPath)) {
12661
+ const existing = fs40.readFileSync(skillPath, "utf-8");
12662
+ fs40.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
12577
12663
  } else {
12578
12664
  const frontmatter = [
12579
12665
  "---",
@@ -12582,12 +12668,12 @@ function writeLearnedSkill(skill) {
12582
12668
  "---",
12583
12669
  ""
12584
12670
  ].join("\n");
12585
- fs39.writeFileSync(skillPath, frontmatter + skill.content);
12671
+ fs40.writeFileSync(skillPath, frontmatter + skill.content);
12586
12672
  }
12587
12673
  return skillPath;
12588
12674
  }
12589
12675
  function writePersonalLearnedSection(content) {
12590
- if (!fs39.existsSync(AUTH_DIR)) fs39.mkdirSync(AUTH_DIR, { recursive: true });
12676
+ if (!fs40.existsSync(AUTH_DIR)) fs40.mkdirSync(AUTH_DIR, { recursive: true });
12591
12677
  return writeLearnedSectionTo(PERSONAL_LEARNINGS_FILE, PERSONAL_LEARNINGS_HEADER, readPersonalLearnings(), content, 384);
12592
12678
  }
12593
12679
  function addLearning(bullet, scope = "project") {
@@ -12600,38 +12686,38 @@ function addLearning(bullet, scope = "project") {
12600
12686
  return { file: LEARNINGS_FILE, added: result.newCount > 0 };
12601
12687
  }
12602
12688
  function readPersonalLearnings() {
12603
- if (!fs39.existsSync(PERSONAL_LEARNINGS_FILE)) return null;
12604
- const content = fs39.readFileSync(PERSONAL_LEARNINGS_FILE, "utf-8");
12689
+ if (!fs40.existsSync(PERSONAL_LEARNINGS_FILE)) return null;
12690
+ const content = fs40.readFileSync(PERSONAL_LEARNINGS_FILE, "utf-8");
12605
12691
  const bullets = content.split("\n").filter((l) => l.startsWith("- ")).join("\n");
12606
12692
  return bullets || null;
12607
12693
  }
12608
12694
  function readLearnedSection() {
12609
- if (fs39.existsSync(LEARNINGS_FILE)) {
12610
- const content2 = fs39.readFileSync(LEARNINGS_FILE, "utf-8");
12695
+ if (fs40.existsSync(LEARNINGS_FILE)) {
12696
+ const content2 = fs40.readFileSync(LEARNINGS_FILE, "utf-8");
12611
12697
  const bullets = content2.split("\n").filter((l) => l.startsWith("- ")).join("\n");
12612
12698
  return bullets || null;
12613
12699
  }
12614
12700
  const claudeMdPath = "CLAUDE.md";
12615
- if (!fs39.existsSync(claudeMdPath)) return null;
12616
- const content = fs39.readFileSync(claudeMdPath, "utf-8");
12701
+ if (!fs40.existsSync(claudeMdPath)) return null;
12702
+ const content = fs40.readFileSync(claudeMdPath, "utf-8");
12617
12703
  const startIdx = content.indexOf(LEARNED_START);
12618
12704
  const endIdx = content.indexOf(LEARNED_END);
12619
12705
  if (startIdx === -1 || endIdx === -1) return null;
12620
12706
  return content.slice(startIdx + LEARNED_START.length, endIdx).trim() || null;
12621
12707
  }
12622
12708
  function migrateInlineLearnings() {
12623
- if (fs39.existsSync(LEARNINGS_FILE)) return false;
12709
+ if (fs40.existsSync(LEARNINGS_FILE)) return false;
12624
12710
  const claudeMdPath = "CLAUDE.md";
12625
- if (!fs39.existsSync(claudeMdPath)) return false;
12626
- const content = fs39.readFileSync(claudeMdPath, "utf-8");
12711
+ if (!fs40.existsSync(claudeMdPath)) return false;
12712
+ const content = fs40.readFileSync(claudeMdPath, "utf-8");
12627
12713
  const startIdx = content.indexOf(LEARNED_START);
12628
12714
  const endIdx = content.indexOf(LEARNED_END);
12629
12715
  if (startIdx === -1 || endIdx === -1) return false;
12630
12716
  const section = content.slice(startIdx + LEARNED_START.length, endIdx).trim();
12631
12717
  if (!section) return false;
12632
- fs39.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + section + "\n");
12718
+ fs40.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + section + "\n");
12633
12719
  const cleaned = content.slice(0, startIdx) + content.slice(endIdx + LEARNED_END.length);
12634
- fs39.writeFileSync(claudeMdPath, cleaned.replace(/\n{3,}/g, "\n\n").trim() + "\n");
12720
+ fs40.writeFileSync(claudeMdPath, cleaned.replace(/\n{3,}/g, "\n\n").trim() + "\n");
12635
12721
  return true;
12636
12722
  }
12637
12723
 
@@ -12641,8 +12727,8 @@ init_resolve_caliber();
12641
12727
  init_builtin_skills();
12642
12728
 
12643
12729
  // src/lib/config-discovery.ts
12644
- import fs40 from "fs";
12645
- import path32 from "path";
12730
+ import fs41 from "fs";
12731
+ import path33 from "path";
12646
12732
  var CONFIG_FILE_MARKERS = [
12647
12733
  "CLAUDE.md",
12648
12734
  "AGENTS.md",
@@ -12668,11 +12754,11 @@ var IGNORE_DIRS3 = /* @__PURE__ */ new Set([
12668
12754
  var MAX_DEPTH = 4;
12669
12755
  function hasConfigFiles(dir) {
12670
12756
  for (const marker of CONFIG_FILE_MARKERS) {
12671
- if (fs40.existsSync(path32.join(dir, marker))) return true;
12757
+ if (fs41.existsSync(path33.join(dir, marker))) return true;
12672
12758
  }
12673
12759
  for (const marker of CONFIG_DIR_MARKERS) {
12674
- const markerPath = path32.join(dir, marker);
12675
- if (fs40.existsSync(markerPath) && fs40.statSync(markerPath).isDirectory()) return true;
12760
+ const markerPath = path33.join(dir, marker);
12761
+ if (fs41.existsSync(markerPath) && fs41.statSync(markerPath).isDirectory()) return true;
12676
12762
  }
12677
12763
  return false;
12678
12764
  }
@@ -12689,15 +12775,15 @@ function walkForConfigs(baseDir, currentDir, depth, result) {
12689
12775
  if (depth >= MAX_DEPTH) return;
12690
12776
  let entries;
12691
12777
  try {
12692
- entries = fs40.readdirSync(currentDir, { withFileTypes: true });
12778
+ entries = fs41.readdirSync(currentDir, { withFileTypes: true });
12693
12779
  } catch {
12694
12780
  return;
12695
12781
  }
12696
12782
  for (const entry of entries) {
12697
12783
  if (!entry.isDirectory()) continue;
12698
12784
  if (entry.name.startsWith(".") || IGNORE_DIRS3.has(entry.name)) continue;
12699
- const fullPath = path32.join(currentDir, entry.name);
12700
- const relPath = path32.relative(baseDir, fullPath).replace(/\\/g, "/");
12785
+ const fullPath = path33.join(currentDir, entry.name);
12786
+ const relPath = path33.relative(baseDir, fullPath).replace(/\\/g, "/");
12701
12787
  if (hasConfigFiles(fullPath)) {
12702
12788
  result.push(relPath);
12703
12789
  }
@@ -12708,8 +12794,8 @@ function walkForConfigs(baseDir, currentDir, depth, result) {
12708
12794
  // src/commands/refresh.ts
12709
12795
  function writeRefreshError(error) {
12710
12796
  try {
12711
- if (!fs42.existsSync(CALIBER_DIR)) fs42.mkdirSync(CALIBER_DIR, { recursive: true });
12712
- fs42.writeFileSync(
12797
+ if (!fs43.existsSync(CALIBER_DIR)) fs43.mkdirSync(CALIBER_DIR, { recursive: true });
12798
+ fs43.writeFileSync(
12713
12799
  REFRESH_LAST_ERROR_FILE,
12714
12800
  JSON.stringify(
12715
12801
  {
@@ -12728,15 +12814,15 @@ function writeRefreshError(error) {
12728
12814
  }
12729
12815
  function readRefreshError() {
12730
12816
  try {
12731
- if (!fs42.existsSync(REFRESH_LAST_ERROR_FILE)) return null;
12732
- return JSON.parse(fs42.readFileSync(REFRESH_LAST_ERROR_FILE, "utf-8"));
12817
+ if (!fs43.existsSync(REFRESH_LAST_ERROR_FILE)) return null;
12818
+ return JSON.parse(fs43.readFileSync(REFRESH_LAST_ERROR_FILE, "utf-8"));
12733
12819
  } catch {
12734
12820
  return null;
12735
12821
  }
12736
12822
  }
12737
12823
  function clearRefreshError() {
12738
12824
  try {
12739
- if (fs42.existsSync(REFRESH_LAST_ERROR_FILE)) fs42.unlinkSync(REFRESH_LAST_ERROR_FILE);
12825
+ if (fs43.existsSync(REFRESH_LAST_ERROR_FILE)) fs43.unlinkSync(REFRESH_LAST_ERROR_FILE);
12740
12826
  } catch {
12741
12827
  }
12742
12828
  }
@@ -12756,11 +12842,11 @@ function log2(quiet, ...args) {
12756
12842
  function discoverGitRepos(parentDir) {
12757
12843
  const repos = [];
12758
12844
  try {
12759
- const entries = fs42.readdirSync(parentDir, { withFileTypes: true });
12845
+ const entries = fs43.readdirSync(parentDir, { withFileTypes: true });
12760
12846
  for (const entry of entries) {
12761
12847
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
12762
- const childPath = path34.join(parentDir, entry.name);
12763
- if (fs42.existsSync(path34.join(childPath, ".git"))) {
12848
+ const childPath = path35.join(parentDir, entry.name);
12849
+ if (fs43.existsSync(path35.join(childPath, ".git"))) {
12764
12850
  repos.push(childPath);
12765
12851
  }
12766
12852
  }
@@ -12770,7 +12856,7 @@ function discoverGitRepos(parentDir) {
12770
12856
  }
12771
12857
  function collectFilesToWrite(updatedDocs, dir = ".") {
12772
12858
  const files = [];
12773
- const p = (relPath) => (dir === "." ? relPath : path34.join(dir, relPath)).replace(/\\/g, "/");
12859
+ const p = (relPath) => (dir === "." ? relPath : path35.join(dir, relPath)).replace(/\\/g, "/");
12774
12860
  if (updatedDocs.agentsMd) files.push(p("AGENTS.md"));
12775
12861
  if (updatedDocs.claudeMd) files.push(p("CLAUDE.md"));
12776
12862
  if (Array.isArray(updatedDocs.claudeRules)) {
@@ -12796,12 +12882,13 @@ async function refreshDir(repoDir, dir, diff, options) {
12796
12882
  const quiet = !!options.quiet;
12797
12883
  const suppress = !!options.suppressSpinner;
12798
12884
  const effectiveQuiet = quiet || suppress;
12799
- const prefix = options.label ? `${chalk18.bold(options.label)} ` : "";
12800
- const absDir = dir === "." ? repoDir : path34.resolve(repoDir, dir);
12885
+ const prefix = options.label ? `${chalk19.bold(options.label)} ` : "";
12886
+ const absDir = dir === "." ? repoDir : path35.resolve(repoDir, dir);
12801
12887
  const scope = dir === "." ? void 0 : dir;
12802
12888
  const spinner = effectiveQuiet ? null : ora6(`${prefix}Analyzing changes...`).start();
12803
12889
  const learnedSection = readLearnedSection();
12804
12890
  const fingerprint = await collectFingerprint(absDir);
12891
+ printLargeFileWarnings(scanLargeFiles(absDir), { spinner: spinner ?? void 0 });
12805
12892
  const existingDocs = fingerprint.existingConfigs;
12806
12893
  const projectContext = {
12807
12894
  languages: fingerprint.languages,
@@ -12853,10 +12940,10 @@ async function refreshDir(repoDir, dir, diff, options) {
12853
12940
  if (options.dryRun) {
12854
12941
  spinner?.info(`${prefix}Dry run \u2014 would update:`);
12855
12942
  for (const doc of response.docsUpdated) {
12856
- console.log(` ${chalk18.yellow("~")} ${doc}`);
12943
+ console.log(` ${chalk19.yellow("~")} ${doc}`);
12857
12944
  }
12858
12945
  if (response.changesSummary) {
12859
- console.log(chalk18.dim(`
12946
+ console.log(chalk19.dim(`
12860
12947
  ${response.changesSummary}`));
12861
12948
  }
12862
12949
  return { written: [], fileChanges: [], syncedAgents: [], changesSummary: null };
@@ -12864,9 +12951,9 @@ async function refreshDir(repoDir, dir, diff, options) {
12864
12951
  const allFilesToWrite = collectFilesToWrite(response.updatedDocs, dir);
12865
12952
  const preRefreshContents = /* @__PURE__ */ new Map();
12866
12953
  for (const filePath of allFilesToWrite) {
12867
- const fullPath = path34.resolve(repoDir, filePath);
12954
+ const fullPath = path35.resolve(repoDir, filePath);
12868
12955
  try {
12869
- preRefreshContents.set(filePath, fs42.readFileSync(fullPath, "utf-8"));
12956
+ preRefreshContents.set(filePath, fs43.readFileSync(fullPath, "utf-8"));
12870
12957
  } catch {
12871
12958
  preRefreshContents.set(filePath, null);
12872
12959
  }
@@ -12882,14 +12969,14 @@ async function refreshDir(repoDir, dir, diff, options) {
12882
12969
  const postScore = computeLocalScore(absDir, targetAgent);
12883
12970
  if (postScore.score < preScore.score) {
12884
12971
  for (const [filePath, content] of preRefreshContents) {
12885
- const fullPath = path34.resolve(repoDir, filePath);
12972
+ const fullPath = path35.resolve(repoDir, filePath);
12886
12973
  if (content === null) {
12887
12974
  try {
12888
- fs42.unlinkSync(fullPath);
12975
+ fs43.unlinkSync(fullPath);
12889
12976
  } catch {
12890
12977
  }
12891
12978
  } else {
12892
- fs42.writeFileSync(fullPath, content);
12979
+ fs43.writeFileSync(fullPath, content);
12893
12980
  }
12894
12981
  }
12895
12982
  spinner?.warn(
@@ -12897,7 +12984,7 @@ async function refreshDir(repoDir, dir, diff, options) {
12897
12984
  );
12898
12985
  log2(
12899
12986
  effectiveQuiet,
12900
- chalk18.dim(` Config quality gate prevented a regression. No files were changed.`)
12987
+ chalk19.dim(` Config quality gate prevented a regression. No files were changed.`)
12901
12988
  );
12902
12989
  return { written: [], fileChanges: [], syncedAgents: [], changesSummary: null };
12903
12990
  }
@@ -12910,18 +12997,18 @@ async function refreshDir(repoDir, dir, diff, options) {
12910
12997
  if (!suppress) {
12911
12998
  for (const file of written) {
12912
12999
  const desc = fileChangesMap.get(file);
12913
- const suffix = desc ? chalk18.dim(` \u2014 ${desc}`) : "";
12914
- log2(effectiveQuiet, ` ${chalk18.green("\u2713")} ${file}${suffix}`);
13000
+ const suffix = desc ? chalk19.dim(` \u2014 ${desc}`) : "";
13001
+ log2(effectiveQuiet, ` ${chalk19.green("\u2713")} ${file}${suffix}`);
12915
13002
  }
12916
13003
  if (syncedAgents.length > 1) {
12917
13004
  log2(
12918
13005
  effectiveQuiet,
12919
- chalk18.cyan(`
13006
+ chalk19.cyan(`
12920
13007
  ${syncedAgents.length} agent formats in sync (${syncedAgents.join(", ")})`)
12921
13008
  );
12922
13009
  }
12923
13010
  if (response.changesSummary) {
12924
- log2(effectiveQuiet, chalk18.dim(`
13011
+ log2(effectiveQuiet, chalk19.dim(`
12925
13012
  ${response.changesSummary}`));
12926
13013
  }
12927
13014
  }
@@ -12929,7 +13016,7 @@ async function refreshDir(repoDir, dir, diff, options) {
12929
13016
  }
12930
13017
  async function refreshSingleRepo(repoDir, options) {
12931
13018
  const quiet = !!options.quiet;
12932
- const prefix = options.label ? `${chalk18.bold(options.label)} ` : "";
13019
+ const prefix = options.label ? `${chalk19.bold(options.label)} ` : "";
12933
13020
  const state = readState();
12934
13021
  const lastSha = state?.lastRefreshSha ?? null;
12935
13022
  const currentSha = getCurrentHeadSha();
@@ -12938,7 +13025,7 @@ async function refreshSingleRepo(repoDir, options) {
12938
13025
  if (elapsed < REFRESH_COOLDOWN_MS && elapsed > 0) {
12939
13026
  log2(
12940
13027
  quiet,
12941
- chalk18.dim(`${prefix}Skipped \u2014 last refresh was ${Math.round(elapsed / 1e3)}s ago.`)
13028
+ chalk19.dim(`${prefix}Skipped \u2014 last refresh was ${Math.round(elapsed / 1e3)}s ago.`)
12942
13029
  );
12943
13030
  return;
12944
13031
  }
@@ -12948,14 +13035,14 @@ async function refreshSingleRepo(repoDir, options) {
12948
13035
  if (currentSha) {
12949
13036
  writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
12950
13037
  }
12951
- log2(quiet, chalk18.dim(`${prefix}No changes since last refresh.`));
13038
+ log2(quiet, chalk19.dim(`${prefix}No changes since last refresh.`));
12952
13039
  return;
12953
13040
  }
12954
13041
  const configDirs = discoverConfigDirs(repoDir);
12955
13042
  if (configDirs.length <= 1) {
12956
13043
  await refreshDir(repoDir, ".", diff, options);
12957
13044
  } else {
12958
- log2(quiet, chalk18.dim(`${prefix}Found configs in ${configDirs.length} directories
13045
+ log2(quiet, chalk19.dim(`${prefix}Found configs in ${configDirs.length} directories
12959
13046
  `));
12960
13047
  const dirsWithChanges = configDirs.map((dir) => ({ dir, scopedDiff: scopeDiffToDir(diff, dir, configDirs) })).filter(({ scopedDiff }) => scopedDiff.hasChanges);
12961
13048
  const parallelSpinner = quiet ? null : ora6(
@@ -12983,7 +13070,7 @@ async function refreshSingleRepo(repoDir, options) {
12983
13070
  hadFailure = true;
12984
13071
  log2(
12985
13072
  quiet,
12986
- chalk18.yellow(
13073
+ chalk19.yellow(
12987
13074
  ` ${dirLabel}: refresh failed \u2014 ${result.reason instanceof Error ? result.reason.message : "unknown error"}`
12988
13075
  )
12989
13076
  );
@@ -12992,20 +13079,20 @@ async function refreshSingleRepo(repoDir, options) {
12992
13079
  const fileChangesMap = new Map(fileChanges.map((fc) => [fc.file, fc.description]));
12993
13080
  for (const file of written) {
12994
13081
  const desc = fileChangesMap.get(file);
12995
- const suffix = desc ? chalk18.dim(` \u2014 ${desc}`) : "";
12996
- log2(quiet, ` ${chalk18.green("\u2713")} ${dirLabel}/${file}${suffix}`);
13082
+ const suffix = desc ? chalk19.dim(` \u2014 ${desc}`) : "";
13083
+ log2(quiet, ` ${chalk19.green("\u2713")} ${dirLabel}/${file}${suffix}`);
12997
13084
  }
12998
13085
  if (syncedAgents.length > 1) {
12999
13086
  log2(
13000
13087
  quiet,
13001
- chalk18.cyan(
13088
+ chalk19.cyan(
13002
13089
  `
13003
13090
  ${syncedAgents.length} agent formats in sync (${syncedAgents.join(", ")})`
13004
13091
  )
13005
13092
  );
13006
13093
  }
13007
13094
  if (changesSummary) {
13008
- log2(quiet, chalk18.dim(`
13095
+ log2(quiet, chalk19.dim(`
13009
13096
  ${changesSummary}`));
13010
13097
  }
13011
13098
  }
@@ -13016,7 +13103,7 @@ async function refreshSingleRepo(repoDir, options) {
13016
13103
  }
13017
13104
  const builtinWritten = ensureBuiltinSkills();
13018
13105
  for (const file of builtinWritten) {
13019
- log2(quiet, ` ${chalk18.green("\u2713")} ${file} ${chalk18.dim("(built-in)")}`);
13106
+ log2(quiet, ` ${chalk19.green("\u2713")} ${file} ${chalk19.dim("(built-in)")}`);
13020
13107
  }
13021
13108
  clearRefreshError();
13022
13109
  if (currentSha) {
@@ -13033,11 +13120,11 @@ async function refreshCommand(options) {
13033
13120
  if (!quiet) {
13034
13121
  const lastError = readRefreshError();
13035
13122
  if (lastError) {
13036
- console.log(chalk18.yellow(`
13123
+ console.log(chalk19.yellow(`
13037
13124
  \u26A0 Last refresh failed (${lastError.timestamp}):`));
13038
- console.log(chalk18.dim(` ${lastError.error}`));
13125
+ console.log(chalk19.dim(` ${lastError.error}`));
13039
13126
  console.log(
13040
- chalk18.dim(
13127
+ chalk19.dim(
13041
13128
  ` Run with --debug for full details, or report at https://github.com/caliber-ai-org/ai-setup/issues
13042
13129
  `
13043
13130
  )
@@ -13050,7 +13137,7 @@ async function refreshCommand(options) {
13050
13137
  if (!config) {
13051
13138
  if (quiet) return;
13052
13139
  console.log(
13053
- chalk18.red("No LLM provider configured. Run ") + chalk18.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk18.red(" (e.g. choose Cursor) or set an API key.")
13140
+ chalk19.red("No LLM provider configured. Run ") + chalk19.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk19.red(" (e.g. choose Cursor) or set an API key.")
13054
13141
  );
13055
13142
  throw new Error("__exit__");
13056
13143
  }
@@ -13063,15 +13150,15 @@ async function refreshCommand(options) {
13063
13150
  if (repos.length === 0) {
13064
13151
  if (quiet) return;
13065
13152
  console.log(
13066
- chalk18.red("Not inside a git repository and no git repos found in child directories.")
13153
+ chalk19.red("Not inside a git repository and no git repos found in child directories.")
13067
13154
  );
13068
13155
  throw new Error("__exit__");
13069
13156
  }
13070
- log2(quiet, chalk18.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
13157
+ log2(quiet, chalk19.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
13071
13158
  `));
13072
13159
  const originalDir = process.cwd();
13073
13160
  for (const repo of repos) {
13074
- const repoName = path34.basename(repo);
13161
+ const repoName = path35.basename(repo);
13075
13162
  try {
13076
13163
  process.chdir(repo);
13077
13164
  await refreshSingleRepo(repo, { ...options, label: repoName });
@@ -13080,7 +13167,7 @@ async function refreshCommand(options) {
13080
13167
  writeRefreshError(err);
13081
13168
  log2(
13082
13169
  quiet,
13083
- chalk18.yellow(
13170
+ chalk19.yellow(
13084
13171
  `${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`
13085
13172
  )
13086
13173
  );
@@ -13093,14 +13180,14 @@ async function refreshCommand(options) {
13093
13180
  writeRefreshError(err);
13094
13181
  if (quiet) return;
13095
13182
  const msg = err instanceof Error ? err.message : "Unknown error";
13096
- console.log(chalk18.red(`Refresh failed: ${msg}`));
13183
+ console.log(chalk19.red(`Refresh failed: ${msg}`));
13097
13184
  throw new Error("__exit__");
13098
13185
  }
13099
13186
  }
13100
13187
 
13101
13188
  // src/commands/hooks.ts
13102
- import chalk19 from "chalk";
13103
- import fs43 from "fs";
13189
+ import chalk20 from "chalk";
13190
+ import fs44 from "fs";
13104
13191
  var HOOKS = [
13105
13192
  {
13106
13193
  id: "session-end",
@@ -13136,41 +13223,41 @@ var HOOKS = [
13136
13223
  }
13137
13224
  ];
13138
13225
  function printStatus() {
13139
- console.log(chalk19.bold("\n Hooks\n"));
13226
+ console.log(chalk20.bold("\n Hooks\n"));
13140
13227
  for (const hook of HOOKS) {
13141
13228
  const installed = hook.isInstalled();
13142
- const icon = installed ? chalk19.green("\u2713") : chalk19.dim("\u2717");
13143
- const state = installed ? chalk19.green("enabled") : chalk19.dim("disabled");
13229
+ const icon = installed ? chalk20.green("\u2713") : chalk20.dim("\u2717");
13230
+ const state = installed ? chalk20.green("enabled") : chalk20.dim("disabled");
13144
13231
  console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
13145
- console.log(chalk19.dim(` ${hook.description}`));
13232
+ console.log(chalk20.dim(` ${hook.description}`));
13146
13233
  }
13147
13234
  console.log("");
13148
13235
  }
13149
13236
  async function hooksCommand(options) {
13150
13237
  if (!options.install && !options.remove) {
13151
13238
  console.log(
13152
- chalk19.dim("\n Note: caliber now adds refresh instructions directly to config files.")
13239
+ chalk20.dim("\n Note: caliber now adds refresh instructions directly to config files.")
13153
13240
  );
13154
13241
  console.log(
13155
- chalk19.dim(" These hooks are available for non-agent workflows (manual commits).\n")
13242
+ chalk20.dim(" These hooks are available for non-agent workflows (manual commits).\n")
13156
13243
  );
13157
13244
  }
13158
13245
  if (options.install) {
13159
13246
  for (const hook of HOOKS) {
13160
13247
  const result = hook.install();
13161
13248
  if (result.alreadyInstalled) {
13162
- console.log(chalk19.dim(` ${hook.label} already enabled.`));
13249
+ console.log(chalk20.dim(` ${hook.label} already enabled.`));
13163
13250
  } else {
13164
- console.log(chalk19.green(" \u2713") + ` ${hook.label} enabled`);
13251
+ console.log(chalk20.green(" \u2713") + ` ${hook.label} enabled`);
13165
13252
  }
13166
13253
  }
13167
- if (fs43.existsSync(".claude")) {
13254
+ if (fs44.existsSync(".claude")) {
13168
13255
  const r = installLearningHooks();
13169
- if (r.installed) console.log(chalk19.green(" \u2713") + " Claude Code learning hooks enabled");
13256
+ if (r.installed) console.log(chalk20.green(" \u2713") + " Claude Code learning hooks enabled");
13170
13257
  }
13171
- if (fs43.existsSync(".cursor")) {
13258
+ if (fs44.existsSync(".cursor")) {
13172
13259
  const r = installCursorLearningHooks();
13173
- if (r.installed) console.log(chalk19.green(" \u2713") + " Cursor learning hooks enabled");
13260
+ if (r.installed) console.log(chalk20.green(" \u2713") + " Cursor learning hooks enabled");
13174
13261
  }
13175
13262
  return;
13176
13263
  }
@@ -13178,9 +13265,9 @@ async function hooksCommand(options) {
13178
13265
  for (const hook of HOOKS) {
13179
13266
  const result = hook.remove();
13180
13267
  if (result.notFound) {
13181
- console.log(chalk19.dim(` ${hook.label} already disabled.`));
13268
+ console.log(chalk20.dim(` ${hook.label} already disabled.`));
13182
13269
  } else {
13183
- console.log(chalk19.green(" \u2713") + ` ${hook.label} removed`);
13270
+ console.log(chalk20.green(" \u2713") + ` ${hook.label} removed`);
13184
13271
  }
13185
13272
  }
13186
13273
  return;
@@ -13195,18 +13282,18 @@ async function hooksCommand(options) {
13195
13282
  const states = HOOKS.map((h) => h.isInstalled());
13196
13283
  function render() {
13197
13284
  const lines = [];
13198
- lines.push(chalk19.bold(" Hooks"));
13285
+ lines.push(chalk20.bold(" Hooks"));
13199
13286
  lines.push("");
13200
13287
  for (let i = 0; i < HOOKS.length; i++) {
13201
13288
  const hook = HOOKS[i];
13202
13289
  const enabled = states[i];
13203
- const toggle = enabled ? chalk19.green("[on] ") : chalk19.dim("[off]");
13204
- const ptr = i === cursor ? chalk19.cyan(">") : " ";
13290
+ const toggle = enabled ? chalk20.green("[on] ") : chalk20.dim("[off]");
13291
+ const ptr = i === cursor ? chalk20.cyan(">") : " ";
13205
13292
  lines.push(` ${ptr} ${toggle} ${hook.label}`);
13206
- lines.push(chalk19.dim(` ${hook.description}`));
13293
+ lines.push(chalk20.dim(` ${hook.description}`));
13207
13294
  }
13208
13295
  lines.push("");
13209
- lines.push(chalk19.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
13296
+ lines.push(chalk20.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
13210
13297
  return lines.join("\n");
13211
13298
  }
13212
13299
  function draw(initial) {
@@ -13237,16 +13324,16 @@ async function hooksCommand(options) {
13237
13324
  const wantEnabled = states[i];
13238
13325
  if (wantEnabled && !wasInstalled) {
13239
13326
  hook.install();
13240
- console.log(chalk19.green(" \u2713") + ` ${hook.label} enabled`);
13327
+ console.log(chalk20.green(" \u2713") + ` ${hook.label} enabled`);
13241
13328
  changed++;
13242
13329
  } else if (!wantEnabled && wasInstalled) {
13243
13330
  hook.remove();
13244
- console.log(chalk19.green(" \u2713") + ` ${hook.label} disabled`);
13331
+ console.log(chalk20.green(" \u2713") + ` ${hook.label} disabled`);
13245
13332
  changed++;
13246
13333
  }
13247
13334
  }
13248
13335
  if (changed === 0) {
13249
- console.log(chalk19.dim(" No changes."));
13336
+ console.log(chalk20.dim(" No changes."));
13250
13337
  }
13251
13338
  console.log("");
13252
13339
  }
@@ -13282,7 +13369,7 @@ async function hooksCommand(options) {
13282
13369
  case "\x1B":
13283
13370
  case "":
13284
13371
  cleanup();
13285
- console.log(chalk19.dim("\n Cancelled.\n"));
13372
+ console.log(chalk20.dim("\n Cancelled.\n"));
13286
13373
  resolve3();
13287
13374
  break;
13288
13375
  }
@@ -13293,52 +13380,52 @@ async function hooksCommand(options) {
13293
13380
 
13294
13381
  // src/commands/config.ts
13295
13382
  init_config();
13296
- import chalk20 from "chalk";
13383
+ import chalk21 from "chalk";
13297
13384
  async function configCommand() {
13298
13385
  const existing = loadConfig();
13299
13386
  if (existing) {
13300
13387
  const displayModel = getDisplayModel(existing);
13301
13388
  const fastModel = getFastModel();
13302
- console.log(chalk20.bold("\nCurrent Configuration\n"));
13303
- console.log(` Provider: ${chalk20.cyan(existing.provider)}`);
13304
- console.log(` Model: ${chalk20.cyan(displayModel)}`);
13389
+ console.log(chalk21.bold("\nCurrent Configuration\n"));
13390
+ console.log(` Provider: ${chalk21.cyan(existing.provider)}`);
13391
+ console.log(` Model: ${chalk21.cyan(displayModel)}`);
13305
13392
  if (fastModel) {
13306
- console.log(` Scan: ${chalk20.cyan(fastModel)}`);
13393
+ console.log(` Scan: ${chalk21.cyan(fastModel)}`);
13307
13394
  }
13308
13395
  if (existing.apiKey) {
13309
13396
  const masked = existing.apiKey.slice(0, 8) + "..." + existing.apiKey.slice(-4);
13310
- console.log(` API Key: ${chalk20.dim(masked)}`);
13397
+ console.log(` API Key: ${chalk21.dim(masked)}`);
13311
13398
  }
13312
13399
  if (existing.provider === "cursor") {
13313
- console.log(` Seat: ${chalk20.dim("Cursor (agent acp)")}`);
13400
+ console.log(` Seat: ${chalk21.dim("Cursor (agent acp)")}`);
13314
13401
  }
13315
13402
  if (existing.provider === "claude-cli") {
13316
- console.log(` Seat: ${chalk20.dim("Claude Code (claude -p)")}`);
13403
+ console.log(` Seat: ${chalk21.dim("Claude Code (claude -p)")}`);
13317
13404
  }
13318
13405
  if (existing.baseUrl) {
13319
- console.log(` Base URL: ${chalk20.dim(existing.baseUrl)}`);
13406
+ console.log(` Base URL: ${chalk21.dim(existing.baseUrl)}`);
13320
13407
  }
13321
13408
  if (existing.vertexProjectId) {
13322
- console.log(` Vertex Project: ${chalk20.dim(existing.vertexProjectId)}`);
13323
- console.log(` Vertex Region: ${chalk20.dim(existing.vertexRegion || "us-east5")}`);
13409
+ console.log(` Vertex Project: ${chalk21.dim(existing.vertexProjectId)}`);
13410
+ console.log(` Vertex Region: ${chalk21.dim(existing.vertexRegion || "us-east5")}`);
13324
13411
  }
13325
- console.log(` Source: ${chalk20.dim(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY || process.env.VERTEX_PROJECT_ID || process.env.CALIBER_USE_CURSOR_SEAT || process.env.CALIBER_USE_CLAUDE_CLI ? "environment variables" : getConfigFilePath())}`);
13412
+ console.log(` Source: ${chalk21.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())}`);
13326
13413
  console.log("");
13327
13414
  }
13328
13415
  await runInteractiveProviderSetup();
13329
13416
  const updated = loadConfig();
13330
13417
  if (updated) trackConfigProviderSet(updated.provider);
13331
- console.log(chalk20.green("\n\u2713 Configuration saved"));
13332
- console.log(chalk20.dim(` ${getConfigFilePath()}
13418
+ console.log(chalk21.green("\n\u2713 Configuration saved"));
13419
+ console.log(chalk21.dim(` ${getConfigFilePath()}
13333
13420
  `));
13334
- console.log(chalk20.dim(" You can also set environment variables instead:"));
13335
- console.log(chalk20.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
13421
+ console.log(chalk21.dim(" You can also set environment variables instead:"));
13422
+ console.log(chalk21.dim(" ANTHROPIC_API_KEY, OPENAI_API_KEY, VERTEX_PROJECT_ID, CALIBER_USE_CURSOR_SEAT=1, or CALIBER_USE_CLAUDE_CLI=1\n"));
13336
13423
  }
13337
13424
 
13338
13425
  // src/commands/learn.ts
13339
- import fs47 from "fs";
13340
- import path38 from "path";
13341
- import chalk22 from "chalk";
13426
+ import fs48 from "fs";
13427
+ import path39 from "path";
13428
+ import chalk23 from "chalk";
13342
13429
 
13343
13430
  // src/learner/stdin.ts
13344
13431
  var STDIN_TIMEOUT_MS = 5e3;
@@ -13368,8 +13455,8 @@ function readStdin() {
13368
13455
  }
13369
13456
 
13370
13457
  // src/learner/storage.ts
13371
- import fs44 from "fs";
13372
- import path35 from "path";
13458
+ import fs45 from "fs";
13459
+ import path36 from "path";
13373
13460
  var MAX_RESPONSE_LENGTH = 2e3;
13374
13461
  var MAX_PROMPT_LENGTH = 2e3;
13375
13462
  var MAX_SESSION_FILE_BYTES = 10 * 1024 * 1024;
@@ -13380,15 +13467,15 @@ var DEFAULT_STATE = {
13380
13467
  lastAnalysisEventCount: 0
13381
13468
  };
13382
13469
  function ensureLearningDir() {
13383
- if (!fs44.existsSync(getLearningDir())) {
13384
- fs44.mkdirSync(getLearningDir(), { recursive: true });
13470
+ if (!fs45.existsSync(getLearningDir())) {
13471
+ fs45.mkdirSync(getLearningDir(), { recursive: true });
13385
13472
  }
13386
13473
  }
13387
13474
  function sessionFilePath() {
13388
- return path35.join(getLearningDir(), LEARNING_SESSION_FILE);
13475
+ return path36.join(getLearningDir(), LEARNING_SESSION_FILE);
13389
13476
  }
13390
13477
  function stateFilePath() {
13391
- return path35.join(getLearningDir(), LEARNING_STATE_FILE);
13478
+ return path36.join(getLearningDir(), LEARNING_STATE_FILE);
13392
13479
  }
13393
13480
  function truncateResponse(response) {
13394
13481
  const str = JSON.stringify(response);
@@ -13397,9 +13484,9 @@ function truncateResponse(response) {
13397
13484
  }
13398
13485
  function trimSessionFileIfNeeded(filePath) {
13399
13486
  try {
13400
- const stat = fs44.statSync(filePath);
13487
+ const stat = fs45.statSync(filePath);
13401
13488
  if (stat.size > MAX_SESSION_FILE_BYTES) {
13402
- fs44.writeFileSync(filePath, "");
13489
+ fs45.writeFileSync(filePath, "");
13403
13490
  resetState();
13404
13491
  return;
13405
13492
  }
@@ -13408,10 +13495,10 @@ function trimSessionFileIfNeeded(filePath) {
13408
13495
  }
13409
13496
  const state = readState2();
13410
13497
  if (state.eventCount + 1 > LEARNING_MAX_EVENTS) {
13411
- const lines = fs44.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
13498
+ const lines = fs45.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
13412
13499
  if (lines.length > LEARNING_MAX_EVENTS) {
13413
13500
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
13414
- fs44.writeFileSync(filePath, kept.join("\n") + "\n");
13501
+ fs45.writeFileSync(filePath, kept.join("\n") + "\n");
13415
13502
  }
13416
13503
  }
13417
13504
  }
@@ -13419,7 +13506,7 @@ function appendEvent(event) {
13419
13506
  ensureLearningDir();
13420
13507
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
13421
13508
  const filePath = sessionFilePath();
13422
- fs44.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
13509
+ fs45.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
13423
13510
  trimSessionFileIfNeeded(filePath);
13424
13511
  }
13425
13512
  function appendPromptEvent(event) {
@@ -13429,22 +13516,22 @@ function appendPromptEvent(event) {
13429
13516
  prompt_content: event.prompt_content.length > MAX_PROMPT_LENGTH ? event.prompt_content.slice(0, MAX_PROMPT_LENGTH) : event.prompt_content
13430
13517
  };
13431
13518
  const filePath = sessionFilePath();
13432
- fs44.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
13519
+ fs45.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
13433
13520
  trimSessionFileIfNeeded(filePath);
13434
13521
  }
13435
13522
  function readAllEvents() {
13436
13523
  const filePath = sessionFilePath();
13437
13524
  try {
13438
- const stat = fs44.statSync(filePath);
13525
+ const stat = fs45.statSync(filePath);
13439
13526
  if (stat.size > MAX_SESSION_FILE_BYTES) {
13440
- fs44.writeFileSync(filePath, "");
13527
+ fs45.writeFileSync(filePath, "");
13441
13528
  resetState();
13442
13529
  return [];
13443
13530
  }
13444
13531
  } catch {
13445
13532
  return [];
13446
13533
  }
13447
- const lines = fs44.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
13534
+ const lines = fs45.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
13448
13535
  const events = [];
13449
13536
  for (const line of lines) {
13450
13537
  try {
@@ -13457,33 +13544,33 @@ function readAllEvents() {
13457
13544
  function getEventCount() {
13458
13545
  const filePath = sessionFilePath();
13459
13546
  try {
13460
- const stat = fs44.statSync(filePath);
13547
+ const stat = fs45.statSync(filePath);
13461
13548
  if (stat.size > MAX_SESSION_FILE_BYTES) return 0;
13462
13549
  } catch {
13463
13550
  return 0;
13464
13551
  }
13465
- const content = fs44.readFileSync(filePath, "utf-8");
13552
+ const content = fs45.readFileSync(filePath, "utf-8");
13466
13553
  return content.split("\n").filter(Boolean).length;
13467
13554
  }
13468
13555
  function clearSession() {
13469
13556
  const filePath = sessionFilePath();
13470
13557
  try {
13471
- fs44.writeFileSync(filePath, "");
13558
+ fs45.writeFileSync(filePath, "");
13472
13559
  } catch {
13473
13560
  }
13474
13561
  }
13475
13562
  function readState2() {
13476
13563
  const filePath = stateFilePath();
13477
- if (!fs44.existsSync(filePath)) return { ...DEFAULT_STATE };
13564
+ if (!fs45.existsSync(filePath)) return { ...DEFAULT_STATE };
13478
13565
  try {
13479
- return JSON.parse(fs44.readFileSync(filePath, "utf-8"));
13566
+ return JSON.parse(fs45.readFileSync(filePath, "utf-8"));
13480
13567
  } catch {
13481
13568
  return { ...DEFAULT_STATE };
13482
13569
  }
13483
13570
  }
13484
13571
  function writeState2(state) {
13485
13572
  ensureLearningDir();
13486
- fs44.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
13573
+ fs45.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
13487
13574
  }
13488
13575
  function resetState() {
13489
13576
  writeState2({ ...DEFAULT_STATE });
@@ -13491,16 +13578,16 @@ function resetState() {
13491
13578
  var LOCK_FILE = "finalize.lock";
13492
13579
  var LOCK_STALE_MS = 5 * 60 * 1e3;
13493
13580
  function lockFilePath() {
13494
- return path35.join(getLearningDir(), LOCK_FILE);
13581
+ return path36.join(getLearningDir(), LOCK_FILE);
13495
13582
  }
13496
13583
  function acquireFinalizeLock() {
13497
13584
  ensureLearningDir();
13498
13585
  const lockPath = lockFilePath();
13499
- if (fs44.existsSync(lockPath)) {
13586
+ if (fs45.existsSync(lockPath)) {
13500
13587
  try {
13501
- const stat = fs44.statSync(lockPath);
13588
+ const stat = fs45.statSync(lockPath);
13502
13589
  if (Date.now() - stat.mtimeMs < LOCK_STALE_MS) {
13503
- const pid = parseInt(fs44.readFileSync(lockPath, "utf-8").trim(), 10);
13590
+ const pid = parseInt(fs45.readFileSync(lockPath, "utf-8").trim(), 10);
13504
13591
  if (!isNaN(pid) && isProcessAlive(pid)) {
13505
13592
  return false;
13506
13593
  }
@@ -13508,12 +13595,12 @@ function acquireFinalizeLock() {
13508
13595
  } catch {
13509
13596
  }
13510
13597
  try {
13511
- fs44.unlinkSync(lockPath);
13598
+ fs45.unlinkSync(lockPath);
13512
13599
  } catch {
13513
13600
  }
13514
13601
  }
13515
13602
  try {
13516
- fs44.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
13603
+ fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
13517
13604
  return true;
13518
13605
  } catch {
13519
13606
  return false;
@@ -13530,46 +13617,46 @@ function isProcessAlive(pid) {
13530
13617
  function releaseFinalizeLock() {
13531
13618
  const lockPath = lockFilePath();
13532
13619
  try {
13533
- if (fs44.existsSync(lockPath)) fs44.unlinkSync(lockPath);
13620
+ if (fs45.existsSync(lockPath)) fs45.unlinkSync(lockPath);
13534
13621
  } catch {
13535
13622
  }
13536
13623
  }
13537
13624
 
13538
13625
  // src/lib/notifications.ts
13539
- import fs45 from "fs";
13540
- import path36 from "path";
13541
- import chalk21 from "chalk";
13626
+ import fs46 from "fs";
13627
+ import path37 from "path";
13628
+ import chalk22 from "chalk";
13542
13629
  function notificationFilePath() {
13543
- return path36.join(getLearningDir(), "last-finalize-summary.json");
13630
+ return path37.join(getLearningDir(), "last-finalize-summary.json");
13544
13631
  }
13545
13632
  function writeFinalizeSummary(summary) {
13546
13633
  try {
13547
13634
  ensureLearningDir();
13548
- fs45.writeFileSync(notificationFilePath(), JSON.stringify(summary, null, 2));
13635
+ fs46.writeFileSync(notificationFilePath(), JSON.stringify(summary, null, 2));
13549
13636
  } catch {
13550
13637
  }
13551
13638
  }
13552
13639
  function checkPendingNotifications() {
13553
13640
  try {
13554
- if (!fs45.existsSync(notificationFilePath())) return;
13555
- const raw = fs45.readFileSync(notificationFilePath(), "utf-8");
13556
- fs45.unlinkSync(notificationFilePath());
13641
+ if (!fs46.existsSync(notificationFilePath())) return;
13642
+ const raw = fs46.readFileSync(notificationFilePath(), "utf-8");
13643
+ fs46.unlinkSync(notificationFilePath());
13557
13644
  const summary = JSON.parse(raw);
13558
13645
  if (!summary.newItemCount || summary.newItemCount === 0) return;
13559
13646
  const wasteLabel = summary.wasteTokens > 0 ? ` (~${summary.wasteTokens.toLocaleString()} wasted tokens captured)` : "";
13560
13647
  console.log(
13561
- chalk21.dim(`caliber: learned ${summary.newItemCount} new pattern${summary.newItemCount === 1 ? "" : "s"} from your last session${wasteLabel}`)
13648
+ chalk22.dim(`caliber: learned ${summary.newItemCount} new pattern${summary.newItemCount === 1 ? "" : "s"} from your last session${wasteLabel}`)
13562
13649
  );
13563
13650
  for (const item of summary.newItems.slice(0, 3)) {
13564
- console.log(chalk21.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
13651
+ console.log(chalk22.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
13565
13652
  }
13566
13653
  if (summary.newItems.length > 3) {
13567
- console.log(chalk21.dim(` ... and ${summary.newItems.length - 3} more`));
13654
+ console.log(chalk22.dim(` ... and ${summary.newItems.length - 3} more`));
13568
13655
  }
13569
13656
  console.log("");
13570
13657
  } catch {
13571
13658
  try {
13572
- fs45.unlinkSync(notificationFilePath());
13659
+ fs46.unlinkSync(notificationFilePath());
13573
13660
  } catch {
13574
13661
  }
13575
13662
  }
@@ -13721,8 +13808,8 @@ function calculateSessionWaste(events) {
13721
13808
  init_config();
13722
13809
 
13723
13810
  // src/learner/roi.ts
13724
- import fs46 from "fs";
13725
- import path37 from "path";
13811
+ import fs47 from "fs";
13812
+ import path38 from "path";
13726
13813
  var DEFAULT_TOTALS = {
13727
13814
  totalWasteTokens: 0,
13728
13815
  totalWasteSeconds: 0,
@@ -13736,19 +13823,19 @@ var DEFAULT_TOTALS = {
13736
13823
  lastSessionTimestamp: ""
13737
13824
  };
13738
13825
  function roiFilePath() {
13739
- return path37.join(getLearningDir(), LEARNING_ROI_FILE);
13826
+ return path38.join(getLearningDir(), LEARNING_ROI_FILE);
13740
13827
  }
13741
13828
  function readROIStats() {
13742
13829
  const filePath = roiFilePath();
13743
- if (!fs46.existsSync(filePath)) {
13830
+ if (!fs47.existsSync(filePath)) {
13744
13831
  return { learnings: [], sessions: [], totals: { ...DEFAULT_TOTALS } };
13745
13832
  }
13746
13833
  try {
13747
- return JSON.parse(fs46.readFileSync(filePath, "utf-8"));
13834
+ return JSON.parse(fs47.readFileSync(filePath, "utf-8"));
13748
13835
  } catch {
13749
13836
  try {
13750
13837
  const corruptPath = filePath + ".corrupt";
13751
- fs46.renameSync(filePath, corruptPath);
13838
+ fs47.renameSync(filePath, corruptPath);
13752
13839
  console.error(`caliber: roi-stats.json was corrupt \u2014 renamed to ${corruptPath}`);
13753
13840
  } catch {
13754
13841
  }
@@ -13757,7 +13844,7 @@ function readROIStats() {
13757
13844
  }
13758
13845
  function writeROIStats(stats) {
13759
13846
  ensureLearningDir();
13760
- fs46.writeFileSync(roiFilePath(), JSON.stringify(stats, null, 2));
13847
+ fs47.writeFileSync(roiFilePath(), JSON.stringify(stats, null, 2));
13761
13848
  }
13762
13849
  function recalculateTotals(stats) {
13763
13850
  const totals = stats.totals;
@@ -13966,9 +14053,9 @@ var AUTO_SETTLE_MS = 200;
13966
14053
  var INCREMENTAL_INTERVAL = 50;
13967
14054
  function writeFinalizeError(message) {
13968
14055
  try {
13969
- const errorPath = path38.join(getLearningDir(), LEARNING_LAST_ERROR_FILE);
13970
- if (!fs47.existsSync(getLearningDir())) fs47.mkdirSync(getLearningDir(), { recursive: true });
13971
- fs47.writeFileSync(
14056
+ const errorPath = path39.join(getLearningDir(), LEARNING_LAST_ERROR_FILE);
14057
+ if (!fs48.existsSync(getLearningDir())) fs48.mkdirSync(getLearningDir(), { recursive: true });
14058
+ fs48.writeFileSync(
13972
14059
  errorPath,
13973
14060
  JSON.stringify(
13974
14061
  {
@@ -13985,9 +14072,9 @@ function writeFinalizeError(message) {
13985
14072
  }
13986
14073
  function readFinalizeError() {
13987
14074
  try {
13988
- const errorPath = path38.join(getLearningDir(), LEARNING_LAST_ERROR_FILE);
13989
- if (!fs47.existsSync(errorPath)) return null;
13990
- return JSON.parse(fs47.readFileSync(errorPath, "utf-8"));
14075
+ const errorPath = path39.join(getLearningDir(), LEARNING_LAST_ERROR_FILE);
14076
+ if (!fs48.existsSync(errorPath)) return null;
14077
+ return JSON.parse(fs48.readFileSync(errorPath, "utf-8"));
13991
14078
  } catch {
13992
14079
  return null;
13993
14080
  }
@@ -14039,22 +14126,21 @@ async function learnObserveCommand(options) {
14039
14126
  const { resolveCaliber: resolveCaliber2, isNpxResolution: isNpxResolution2 } = await Promise.resolve().then(() => (init_resolve_caliber(), resolve_caliber_exports));
14040
14127
  const bin = resolveCaliber2();
14041
14128
  const { spawn: spawn5 } = await import("child_process");
14042
- const logPath = path38.join(getLearningDir(), LEARNING_FINALIZE_LOG);
14043
- if (!fs47.existsSync(getLearningDir())) fs47.mkdirSync(getLearningDir(), { recursive: true });
14044
- const logFd = fs47.openSync(logPath, "a");
14129
+ const logPath = path39.join(getLearningDir(), LEARNING_FINALIZE_LOG);
14130
+ if (!fs48.existsSync(getLearningDir())) fs48.mkdirSync(getLearningDir(), { recursive: true });
14131
+ const logFd = fs48.openSync(logPath, "a");
14045
14132
  const NPX_SUFFIX = " --yes @rely-ai/caliber";
14046
14133
  const [exe, binArgs] = isNpxResolution2() ? [bin.slice(0, -NPX_SUFFIX.length) || "npx", ["--yes", "@rely-ai/caliber"]] : [bin, []];
14047
14134
  const isWin = process.platform === "win32";
14048
- const spawnExe = isWin ? `"${exe}"` : exe;
14049
- const child = spawn5(
14050
- spawnExe,
14051
- [...binArgs, "learn", "finalize", "--auto", "--incremental"],
14052
- {
14053
- detached: true,
14054
- stdio: ["ignore", logFd, logFd],
14055
- ...isWin && { shell: true }
14056
- }
14057
- );
14135
+ const argsArray = [...binArgs, "learn", "finalize", "--auto", "--incremental"];
14136
+ const child = isWin ? spawn5([`"${exe}"`, ...argsArray.map(quoteForWindows)].join(" "), {
14137
+ detached: true,
14138
+ stdio: ["ignore", logFd, logFd],
14139
+ shell: true
14140
+ }) : spawn5(exe, argsArray, {
14141
+ detached: true,
14142
+ stdio: ["ignore", logFd, logFd]
14143
+ });
14058
14144
  child.on("error", () => {
14059
14145
  try {
14060
14146
  const s = readState2();
@@ -14064,7 +14150,7 @@ async function learnObserveCommand(options) {
14064
14150
  }
14065
14151
  });
14066
14152
  child.unref();
14067
- fs47.closeSync(logFd);
14153
+ fs48.closeSync(logFd);
14068
14154
  } catch {
14069
14155
  }
14070
14156
  }
@@ -14079,7 +14165,7 @@ async function learnFinalizeCommand(options) {
14079
14165
  const { isCaliberRunning: isCaliberRunning2 } = await Promise.resolve().then(() => (init_lock(), lock_exports));
14080
14166
  if (isCaliberRunning2()) {
14081
14167
  if (!isAuto)
14082
- console.log(chalk22.dim("caliber: skipping finalize \u2014 another caliber process is running"));
14168
+ console.log(chalk23.dim("caliber: skipping finalize \u2014 another caliber process is running"));
14083
14169
  return;
14084
14170
  }
14085
14171
  }
@@ -14088,7 +14174,7 @@ async function learnFinalizeCommand(options) {
14088
14174
  }
14089
14175
  if (!acquireFinalizeLock()) {
14090
14176
  if (!isAuto)
14091
- console.log(chalk22.dim("caliber: skipping finalize \u2014 another finalize is in progress"));
14177
+ console.log(chalk23.dim("caliber: skipping finalize \u2014 another finalize is in progress"));
14092
14178
  return;
14093
14179
  }
14094
14180
  let analyzed = false;
@@ -14097,7 +14183,7 @@ async function learnFinalizeCommand(options) {
14097
14183
  if (!config) {
14098
14184
  if (isAuto) return;
14099
14185
  console.log(
14100
- chalk22.yellow(
14186
+ chalk23.yellow(
14101
14187
  `caliber: no LLM provider configured \u2014 run \`${resolveCaliber()} config\` first`
14102
14188
  )
14103
14189
  );
@@ -14110,7 +14196,7 @@ async function learnFinalizeCommand(options) {
14110
14196
  if (allEvents.length < threshold) {
14111
14197
  if (!isAuto)
14112
14198
  console.log(
14113
- chalk22.dim(
14199
+ chalk23.dim(
14114
14200
  `caliber: ${allEvents.length}/${threshold} events recorded \u2014 need more before analysis`
14115
14201
  )
14116
14202
  );
@@ -14124,7 +14210,7 @@ async function learnFinalizeCommand(options) {
14124
14210
  if (events.length < threshold) {
14125
14211
  if (!isAuto)
14126
14212
  console.log(
14127
- chalk22.dim(
14213
+ chalk23.dim(
14128
14214
  `caliber: ${events.length}/${threshold} new events since last analysis \u2014 need more`
14129
14215
  )
14130
14216
  );
@@ -14164,12 +14250,12 @@ async function learnFinalizeCommand(options) {
14164
14250
  } else {
14165
14251
  const wasteLabel = waste.totalWasteTokens > 0 ? ` (~${waste.totalWasteTokens.toLocaleString()} wasted tokens captured)` : "";
14166
14252
  console.log(
14167
- chalk22.dim(
14253
+ chalk23.dim(
14168
14254
  `caliber: learned ${result.newItemCount} new pattern${result.newItemCount === 1 ? "" : "s"}${wasteLabel}`
14169
14255
  )
14170
14256
  );
14171
14257
  for (const item of result.newItems) {
14172
- console.log(chalk22.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
14258
+ console.log(chalk23.dim(` + ${item.replace(/^- /, "").slice(0, 80)}`));
14173
14259
  }
14174
14260
  }
14175
14261
  const wastePerLearning = Math.round(waste.totalWasteTokens / result.newItemCount);
@@ -14263,7 +14349,7 @@ async function learnFinalizeCommand(options) {
14263
14349
  const staleLearnings = findStaleLearnings(roiStats);
14264
14350
  if (staleLearnings.length > 0 && !isAuto) {
14265
14351
  console.log(
14266
- chalk22.yellow(
14352
+ chalk23.yellow(
14267
14353
  `caliber: ${staleLearnings.length} learning${staleLearnings.length === 1 ? "" : "s"} never activated \u2014 run \`${resolveCaliber()} learn list --verbose\` to review`
14268
14354
  )
14269
14355
  );
@@ -14272,7 +14358,7 @@ async function learnFinalizeCommand(options) {
14272
14358
  if (!isAuto && t.estimatedSavingsTokens > 0) {
14273
14359
  const totalLearnings = existingLearnedItems + newLearningsProduced;
14274
14360
  console.log(
14275
- chalk22.dim(
14361
+ chalk23.dim(
14276
14362
  `caliber: ${totalLearnings} learnings active \u2014 est. ~${t.estimatedSavingsTokens.toLocaleString()} tokens saved across ${t.totalSessionsWithLearnings} sessions`
14277
14363
  )
14278
14364
  );
@@ -14280,7 +14366,7 @@ async function learnFinalizeCommand(options) {
14280
14366
  } catch (err) {
14281
14367
  const errorMsg = err instanceof Error ? err.message : String(err);
14282
14368
  if (options?.force && !isAuto) {
14283
- console.error(chalk22.red("caliber: finalize failed \u2014"), errorMsg);
14369
+ console.error(chalk23.red("caliber: finalize failed \u2014"), errorMsg);
14284
14370
  }
14285
14371
  writeFinalizeError(errorMsg);
14286
14372
  } finally {
@@ -14300,54 +14386,54 @@ async function learnFinalizeCommand(options) {
14300
14386
  }
14301
14387
  async function learnInstallCommand() {
14302
14388
  let anyInstalled = false;
14303
- if (fs47.existsSync(".claude")) {
14389
+ if (fs48.existsSync(".claude")) {
14304
14390
  const r = installLearningHooks();
14305
14391
  if (r.installed) {
14306
- console.log(chalk22.green("\u2713") + " Claude Code learning hooks installed");
14392
+ console.log(chalk23.green("\u2713") + " Claude Code learning hooks installed");
14307
14393
  anyInstalled = true;
14308
14394
  } else if (r.alreadyInstalled) {
14309
- console.log(chalk22.dim(" Claude Code hooks already installed"));
14395
+ console.log(chalk23.dim(" Claude Code hooks already installed"));
14310
14396
  }
14311
14397
  }
14312
- if (fs47.existsSync(".cursor")) {
14398
+ if (fs48.existsSync(".cursor")) {
14313
14399
  const r = installCursorLearningHooks();
14314
14400
  if (r.installed) {
14315
- console.log(chalk22.green("\u2713") + " Cursor learning hooks installed");
14401
+ console.log(chalk23.green("\u2713") + " Cursor learning hooks installed");
14316
14402
  anyInstalled = true;
14317
14403
  } else if (r.alreadyInstalled) {
14318
- console.log(chalk22.dim(" Cursor hooks already installed"));
14404
+ console.log(chalk23.dim(" Cursor hooks already installed"));
14319
14405
  }
14320
14406
  }
14321
- if (!fs47.existsSync(".claude") && !fs47.existsSync(".cursor")) {
14322
- console.log(chalk22.yellow("No .claude/ or .cursor/ directory found."));
14407
+ if (!fs48.existsSync(".claude") && !fs48.existsSync(".cursor")) {
14408
+ console.log(chalk23.yellow("No .claude/ or .cursor/ directory found."));
14323
14409
  console.log(
14324
- chalk22.dim(` Run \`${resolveCaliber()} init\` first, or create the directory manually.`)
14410
+ chalk23.dim(` Run \`${resolveCaliber()} init\` first, or create the directory manually.`)
14325
14411
  );
14326
14412
  return;
14327
14413
  }
14328
14414
  if (anyInstalled) {
14329
14415
  console.log(
14330
- chalk22.dim(
14416
+ chalk23.dim(
14331
14417
  ` Tool usage will be recorded and learnings extracted after \u2265${MIN_EVENTS_FOR_ANALYSIS} events.`
14332
14418
  )
14333
14419
  );
14334
- console.log(chalk22.dim(" Learnings written to CALIBER_LEARNINGS.md."));
14420
+ console.log(chalk23.dim(" Learnings written to CALIBER_LEARNINGS.md."));
14335
14421
  }
14336
14422
  }
14337
14423
  async function learnRemoveCommand() {
14338
14424
  let anyRemoved = false;
14339
14425
  const r1 = removeLearningHooks();
14340
14426
  if (r1.removed) {
14341
- console.log(chalk22.green("\u2713") + " Claude Code learning hooks removed");
14427
+ console.log(chalk23.green("\u2713") + " Claude Code learning hooks removed");
14342
14428
  anyRemoved = true;
14343
14429
  }
14344
14430
  const r2 = removeCursorLearningHooks();
14345
14431
  if (r2.removed) {
14346
- console.log(chalk22.green("\u2713") + " Cursor learning hooks removed");
14432
+ console.log(chalk23.green("\u2713") + " Cursor learning hooks removed");
14347
14433
  anyRemoved = true;
14348
14434
  }
14349
14435
  if (!anyRemoved) {
14350
- console.log(chalk22.dim("No learning hooks found."));
14436
+ console.log(chalk23.dim("No learning hooks found."));
14351
14437
  }
14352
14438
  }
14353
14439
  async function learnStatusCommand() {
@@ -14355,51 +14441,51 @@ async function learnStatusCommand() {
14355
14441
  const cursorInstalled = areCursorLearningHooksInstalled();
14356
14442
  const state = readState2();
14357
14443
  const eventCount = getEventCount();
14358
- console.log(chalk22.bold("Session Learning Status"));
14444
+ console.log(chalk23.bold("Session Learning Status"));
14359
14445
  console.log();
14360
14446
  if (claudeInstalled) {
14361
- console.log(chalk22.green("\u2713") + " Claude Code hooks " + chalk22.green("installed"));
14447
+ console.log(chalk23.green("\u2713") + " Claude Code hooks " + chalk23.green("installed"));
14362
14448
  } else {
14363
- console.log(chalk22.dim("\u2717") + " Claude Code hooks " + chalk22.dim("not installed"));
14449
+ console.log(chalk23.dim("\u2717") + " Claude Code hooks " + chalk23.dim("not installed"));
14364
14450
  }
14365
14451
  if (cursorInstalled) {
14366
- console.log(chalk22.green("\u2713") + " Cursor hooks " + chalk22.green("installed"));
14452
+ console.log(chalk23.green("\u2713") + " Cursor hooks " + chalk23.green("installed"));
14367
14453
  } else {
14368
- console.log(chalk22.dim("\u2717") + " Cursor hooks " + chalk22.dim("not installed"));
14454
+ console.log(chalk23.dim("\u2717") + " Cursor hooks " + chalk23.dim("not installed"));
14369
14455
  }
14370
14456
  if (!claudeInstalled && !cursorInstalled) {
14371
14457
  console.log(
14372
- chalk22.dim(` Run \`${resolveCaliber()} learn install\` to enable session learning.`)
14458
+ chalk23.dim(` Run \`${resolveCaliber()} learn install\` to enable session learning.`)
14373
14459
  );
14374
14460
  }
14375
14461
  console.log();
14376
- console.log(`Events recorded: ${chalk22.cyan(String(eventCount))}`);
14377
- console.log(`Threshold for analysis: ${chalk22.cyan(String(MIN_EVENTS_FOR_ANALYSIS))}`);
14462
+ console.log(`Events recorded: ${chalk23.cyan(String(eventCount))}`);
14463
+ console.log(`Threshold for analysis: ${chalk23.cyan(String(MIN_EVENTS_FOR_ANALYSIS))}`);
14378
14464
  if (state.lastAnalysisTimestamp) {
14379
- console.log(`Last analysis: ${chalk22.cyan(state.lastAnalysisTimestamp)}`);
14465
+ console.log(`Last analysis: ${chalk23.cyan(state.lastAnalysisTimestamp)}`);
14380
14466
  } else {
14381
- console.log(`Last analysis: ${chalk22.dim("none")}`);
14467
+ console.log(`Last analysis: ${chalk23.dim("none")}`);
14382
14468
  }
14383
14469
  const lastError = readFinalizeError();
14384
14470
  if (lastError) {
14385
- console.log(`Last error: ${chalk22.red(lastError.error)}`);
14386
- console.log(chalk22.dim(` at ${lastError.timestamp}`));
14387
- const logPath = path38.join(getLearningDir(), LEARNING_FINALIZE_LOG);
14388
- if (fs47.existsSync(logPath)) {
14389
- console.log(chalk22.dim(` Full log: ${logPath}`));
14471
+ console.log(`Last error: ${chalk23.red(lastError.error)}`);
14472
+ console.log(chalk23.dim(` at ${lastError.timestamp}`));
14473
+ const logPath = path39.join(getLearningDir(), LEARNING_FINALIZE_LOG);
14474
+ if (fs48.existsSync(logPath)) {
14475
+ console.log(chalk23.dim(` Full log: ${logPath}`));
14390
14476
  }
14391
14477
  }
14392
14478
  const learnedSection = readLearnedSection();
14393
14479
  if (learnedSection) {
14394
14480
  const lineCount = learnedSection.split("\n").filter(Boolean).length;
14395
14481
  console.log(`
14396
- Learned items in CALIBER_LEARNINGS.md: ${chalk22.cyan(String(lineCount))}`);
14482
+ Learned items in CALIBER_LEARNINGS.md: ${chalk23.cyan(String(lineCount))}`);
14397
14483
  }
14398
14484
  const roiStats = readROIStats();
14399
14485
  const roiSummary = formatROISummary(roiStats);
14400
14486
  if (roiSummary) {
14401
14487
  console.log();
14402
- console.log(chalk22.bold(roiSummary.split("\n")[0]));
14488
+ console.log(chalk23.bold(roiSummary.split("\n")[0]));
14403
14489
  for (const line of roiSummary.split("\n").slice(1)) {
14404
14490
  console.log(line);
14405
14491
  }
@@ -14425,26 +14511,26 @@ function getAllLearnings() {
14425
14511
  async function learnListCommand(options) {
14426
14512
  const items = getAllLearnings();
14427
14513
  if (items.length === 0) {
14428
- console.log(chalk22.dim(`No learnings yet. Run \`${resolveCaliber()} learn install\` to start.`));
14514
+ console.log(chalk23.dim(`No learnings yet. Run \`${resolveCaliber()} learn install\` to start.`));
14429
14515
  return;
14430
14516
  }
14431
14517
  const roiStats = options?.verbose ? readROIStats() : null;
14432
- console.log(chalk22.bold(`
14518
+ console.log(chalk23.bold(`
14433
14519
  Learnings (${items.length})
14434
14520
  `));
14435
14521
  for (const item of items) {
14436
- const tag = item.source === "personal" ? chalk22.magenta("[personal]") : chalk22.blue("[project]");
14522
+ const tag = item.source === "personal" ? chalk23.magenta("[personal]") : chalk23.blue("[project]");
14437
14523
  const display = item.text.replace(/^- /, "").slice(0, 100);
14438
- console.log(` ${chalk22.dim(String(item.index + 1).padStart(2, " "))}. ${tag} ${display}`);
14524
+ console.log(` ${chalk23.dim(String(item.index + 1).padStart(2, " "))}. ${tag} ${display}`);
14439
14525
  if (options?.verbose && roiStats) {
14440
14526
  const match = roiStats.learnings.find((l) => display.includes(l.summary.slice(0, 40)));
14441
14527
  if (match) {
14442
14528
  const activations = match.activationCount ?? 0;
14443
14529
  const stale = activations === 0 && roiStats.sessions.length >= 10;
14444
- const activationLabel = stale ? chalk22.yellow(`${activations} activations [stale]`) : chalk22.dim(`${activations} activation${activations === 1 ? "" : "s"}`);
14530
+ const activationLabel = stale ? chalk23.yellow(`${activations} activations [stale]`) : chalk23.dim(`${activations} activation${activations === 1 ? "" : "s"}`);
14445
14531
  console.log(` ${activationLabel}`);
14446
14532
  if (match.explanation) {
14447
- console.log(` ${chalk22.dim("Why: " + match.explanation.slice(0, 80))}`);
14533
+ console.log(` ${chalk23.dim("Why: " + match.explanation.slice(0, 80))}`);
14448
14534
  }
14449
14535
  }
14450
14536
  }
@@ -14455,7 +14541,7 @@ async function learnDeleteCommand(indexStr) {
14455
14541
  const index = parseInt(indexStr, 10);
14456
14542
  if (isNaN(index) || index < 1) {
14457
14543
  console.log(
14458
- chalk22.red(
14544
+ chalk23.red(
14459
14545
  `Invalid index: "${indexStr}". Use a number from \`${resolveCaliber()} learn list\`.`
14460
14546
  )
14461
14547
  );
@@ -14464,16 +14550,16 @@ async function learnDeleteCommand(indexStr) {
14464
14550
  const items = getAllLearnings();
14465
14551
  const targetIdx = index - 1;
14466
14552
  if (targetIdx >= items.length) {
14467
- console.log(chalk22.red(`Index ${index} is out of range. You have ${items.length} learnings.`));
14553
+ console.log(chalk23.red(`Index ${index} is out of range. You have ${items.length} learnings.`));
14468
14554
  return;
14469
14555
  }
14470
14556
  const item = items[targetIdx];
14471
14557
  const filePath = item.source === "personal" ? PERSONAL_LEARNINGS_FILE : "CALIBER_LEARNINGS.md";
14472
- if (!fs47.existsSync(filePath)) {
14473
- console.log(chalk22.red("Learnings file not found."));
14558
+ if (!fs48.existsSync(filePath)) {
14559
+ console.log(chalk23.red("Learnings file not found."));
14474
14560
  return;
14475
14561
  }
14476
- const content = fs47.readFileSync(filePath, "utf-8");
14562
+ const content = fs48.readFileSync(filePath, "utf-8");
14477
14563
  const lines = content.split("\n");
14478
14564
  const bulletsOfSource = items.filter((i) => i.source === item.source);
14479
14565
  const posInFile = bulletsOfSource.indexOf(item);
@@ -14489,14 +14575,14 @@ async function learnDeleteCommand(indexStr) {
14489
14575
  }
14490
14576
  }
14491
14577
  if (lineToRemove === -1) {
14492
- console.log(chalk22.red("Could not locate learning in file."));
14578
+ console.log(chalk23.red("Could not locate learning in file."));
14493
14579
  return;
14494
14580
  }
14495
14581
  const bulletToRemove = lines[lineToRemove];
14496
14582
  const newLines = lines.filter((_, i) => i !== lineToRemove);
14497
- fs47.writeFileSync(filePath, newLines.join("\n"));
14583
+ fs48.writeFileSync(filePath, newLines.join("\n"));
14498
14584
  if (item.source === "personal") {
14499
- fs47.chmodSync(filePath, 384);
14585
+ fs48.chmodSync(filePath, 384);
14500
14586
  }
14501
14587
  const roiStats = readROIStats();
14502
14588
  const cleanText = bulletToRemove.replace(/^- /, "").replace(/^\*\*\[[^\]]+\]\*\*\s*/, "").trim();
@@ -14505,24 +14591,24 @@ async function learnDeleteCommand(indexStr) {
14505
14591
  roiStats.learnings.splice(roiIdx, 1);
14506
14592
  writeROIStats(roiStats);
14507
14593
  }
14508
- console.log(chalk22.green("\u2713") + ` Removed: ${bulletToRemove.replace(/^- /, "").slice(0, 80)}`);
14594
+ console.log(chalk23.green("\u2713") + ` Removed: ${bulletToRemove.replace(/^- /, "").slice(0, 80)}`);
14509
14595
  }
14510
14596
  async function learnAddCommand(content, options) {
14511
14597
  if (!content.trim()) {
14512
- console.log(chalk22.yellow("Please provide learning content."));
14598
+ console.log(chalk23.yellow("Please provide learning content."));
14513
14599
  throw new Error("__exit__");
14514
14600
  }
14515
14601
  const scope = options.personal ? "personal" : "project";
14516
14602
  const result = addLearning(content.trim(), scope);
14517
14603
  if (result.added) {
14518
- console.log(chalk22.green("\u2713") + ` Learning saved to ${result.file}`);
14604
+ console.log(chalk23.green("\u2713") + ` Learning saved to ${result.file}`);
14519
14605
  } else {
14520
- console.log(chalk22.dim(" Similar learning already exists \u2014 skipped."));
14606
+ console.log(chalk23.dim(" Similar learning already exists \u2014 skipped."));
14521
14607
  }
14522
14608
  }
14523
14609
 
14524
14610
  // src/commands/insights.ts
14525
- import chalk23 from "chalk";
14611
+ import chalk24 from "chalk";
14526
14612
  init_resolve_caliber();
14527
14613
  var MIN_SESSIONS_FULL = 20;
14528
14614
  function buildInsightsData(stats) {
@@ -14563,85 +14649,85 @@ function buildInsightsData(stats) {
14563
14649
  };
14564
14650
  }
14565
14651
  function displayColdStart(score) {
14566
- console.log(chalk23.bold("\n Agent Insights\n"));
14652
+ console.log(chalk24.bold("\n Agent Insights\n"));
14567
14653
  const hooksInstalled = areLearningHooksInstalled() || areCursorLearningHooksInstalled();
14568
14654
  if (!hooksInstalled) {
14569
- console.log(chalk23.yellow(" Learning hooks not installed."));
14570
- console.log(chalk23.dim(" Session learning captures patterns from your AI coding sessions \u2014 what"));
14571
- console.log(chalk23.dim(" fails, what works, corrections you make \u2014 so your agents improve over time.\n"));
14572
- console.log(chalk23.dim(" Run ") + chalk23.cyan(`${resolveCaliber()} learn install`) + chalk23.dim(" to enable."));
14655
+ console.log(chalk24.yellow(" Learning hooks not installed."));
14656
+ console.log(chalk24.dim(" Session learning captures patterns from your AI coding sessions \u2014 what"));
14657
+ console.log(chalk24.dim(" fails, what works, corrections you make \u2014 so your agents improve over time.\n"));
14658
+ console.log(chalk24.dim(" Run ") + chalk24.cyan(`${resolveCaliber()} learn install`) + chalk24.dim(" to enable."));
14573
14659
  } else {
14574
- console.log(chalk23.dim(" Learning hooks are active. Use your AI agent and insights"));
14575
- console.log(chalk23.dim(" will appear automatically after each session.\n"));
14576
- console.log(chalk23.dim(` Progress: 0/${MIN_SESSIONS_FULL} sessions \u2014 full insights unlock at ${MIN_SESSIONS_FULL}`));
14660
+ console.log(chalk24.dim(" Learning hooks are active. Use your AI agent and insights"));
14661
+ console.log(chalk24.dim(" will appear automatically after each session.\n"));
14662
+ console.log(chalk24.dim(` Progress: 0/${MIN_SESSIONS_FULL} sessions \u2014 full insights unlock at ${MIN_SESSIONS_FULL}`));
14577
14663
  }
14578
- console.log(chalk23.dim(`
14664
+ console.log(chalk24.dim(`
14579
14665
  Config score: ${score.score}/100 (${score.grade})`));
14580
14666
  console.log("");
14581
14667
  }
14582
14668
  function displayEarlyData(data, score) {
14583
- console.log(chalk23.bold("\n Agent Insights") + chalk23.yellow(" (early data)\n"));
14669
+ console.log(chalk24.bold("\n Agent Insights") + chalk24.yellow(" (early data)\n"));
14584
14670
  const remaining = MIN_SESSIONS_FULL - data.totalSessions;
14585
- console.log(chalk23.dim(` ${data.totalSessions}/${MIN_SESSIONS_FULL} sessions tracked \u2014 ${remaining} more for full insights.
14671
+ console.log(chalk24.dim(` ${data.totalSessions}/${MIN_SESSIONS_FULL} sessions tracked \u2014 ${remaining} more for full insights.
14586
14672
  `));
14587
- console.log(` Sessions tracked: ${chalk23.cyan(String(data.totalSessions))}`);
14588
- console.log(` Learnings accumulated: ${chalk23.cyan(String(data.learningCount))}`);
14673
+ console.log(` Sessions tracked: ${chalk24.cyan(String(data.totalSessions))}`);
14674
+ console.log(` Learnings accumulated: ${chalk24.cyan(String(data.learningCount))}`);
14589
14675
  if (data.totalWasteTokens > 0) {
14590
- console.log(` Waste captured: ${chalk23.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
14676
+ console.log(` Waste captured: ${chalk24.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
14591
14677
  }
14592
14678
  if (data.failureRateImprovement !== null && data.failureRateImprovement > 0) {
14593
- console.log(` Failure rate trend: ${chalk23.green(`${data.failureRateImprovement}% fewer`)} failures with learnings ${chalk23.dim("(early signal)")}`);
14679
+ console.log(` Failure rate trend: ${chalk24.green(`${data.failureRateImprovement}% fewer`)} failures with learnings ${chalk24.dim("(early signal)")}`);
14594
14680
  } else if (data.totalSessions > 0 && data.failureRateImprovement === null) {
14595
- console.log(` Failure rate trend: ${chalk23.dim("collecting data (need 3+ sessions in each group)")}`);
14681
+ console.log(` Failure rate trend: ${chalk24.dim("collecting data (need 3+ sessions in each group)")}`);
14596
14682
  }
14597
14683
  if (data.taskSuccessRate !== null) {
14598
- console.log(` Task success rate: ${chalk23.cyan(`${data.taskSuccessRate}%`)} ${chalk23.dim(`(${data.taskCount} tasks)`)}`);
14684
+ console.log(` Task success rate: ${chalk24.cyan(`${data.taskSuccessRate}%`)} ${chalk24.dim(`(${data.taskCount} tasks)`)}`);
14599
14685
  }
14600
- console.log(` Config score: ${chalk23.cyan(`${score.score}/100`)} (${score.grade})`);
14686
+ console.log(` Config score: ${chalk24.cyan(`${score.score}/100`)} (${score.grade})`);
14601
14687
  console.log("");
14602
14688
  }
14603
14689
  function displayFullInsights(data, score) {
14604
- console.log(chalk23.bold("\n Agent Insights\n"));
14605
- console.log(chalk23.bold(" Agent Health"));
14690
+ console.log(chalk24.bold("\n Agent Insights\n"));
14691
+ console.log(chalk24.bold(" Agent Health"));
14606
14692
  if (data.taskSuccessRate !== null) {
14607
- const color = data.taskSuccessRate >= 80 ? chalk23.green : data.taskSuccessRate >= 60 ? chalk23.yellow : chalk23.red;
14693
+ const color = data.taskSuccessRate >= 80 ? chalk24.green : data.taskSuccessRate >= 60 ? chalk24.yellow : chalk24.red;
14608
14694
  console.log(` Task success rate: ${color(`${data.taskSuccessRate}%`)} across ${data.taskCount} tasks`);
14609
14695
  if (data.taskCorrectionCount > 0) {
14610
- console.log(` Corrections needed: ${chalk23.yellow(String(data.taskCorrectionCount))} tasks required user correction`);
14696
+ console.log(` Corrections needed: ${chalk24.yellow(String(data.taskCorrectionCount))} tasks required user correction`);
14611
14697
  }
14612
14698
  }
14613
- console.log(` Sessions tracked: ${chalk23.cyan(String(data.totalSessions))}`);
14614
- console.log(chalk23.bold("\n Learning Impact"));
14615
- console.log(` Learnings active: ${chalk23.cyan(String(data.learningCount))}`);
14699
+ console.log(` Sessions tracked: ${chalk24.cyan(String(data.totalSessions))}`);
14700
+ console.log(chalk24.bold("\n Learning Impact"));
14701
+ console.log(` Learnings active: ${chalk24.cyan(String(data.learningCount))}`);
14616
14702
  if (data.failureRateWith !== null && data.failureRateWithout !== null) {
14617
- console.log(` Failure rate: ${chalk23.red(data.failureRateWithout.toFixed(1))}/session ${chalk23.dim("\u2192")} ${chalk23.green(data.failureRateWith.toFixed(1))}/session with learnings`);
14703
+ console.log(` Failure rate: ${chalk24.red(data.failureRateWithout.toFixed(1))}/session ${chalk24.dim("\u2192")} ${chalk24.green(data.failureRateWith.toFixed(1))}/session with learnings`);
14618
14704
  if (data.failureRateImprovement !== null && data.failureRateImprovement > 0) {
14619
- console.log(` Improvement: ${chalk23.green(`${data.failureRateImprovement}%`)} fewer failures`);
14705
+ console.log(` Improvement: ${chalk24.green(`${data.failureRateImprovement}%`)} fewer failures`);
14620
14706
  } else if (data.failureRateImprovement === null) {
14621
- console.log(` Improvement: ${chalk23.dim("collecting data (need 3+ sessions in each group)")}`);
14707
+ console.log(` Improvement: ${chalk24.dim("collecting data (need 3+ sessions in each group)")}`);
14622
14708
  }
14623
14709
  }
14624
14710
  if (data.totalWasteTokens > 0 || data.estimatedSavingsTokens > 0) {
14625
- console.log(chalk23.bold("\n Efficiency"));
14711
+ console.log(chalk24.bold("\n Efficiency"));
14626
14712
  if (data.totalWasteTokens > 0) {
14627
- console.log(` Waste captured: ${chalk23.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
14713
+ console.log(` Waste captured: ${chalk24.cyan(data.totalWasteTokens.toLocaleString())} tokens`);
14628
14714
  }
14629
14715
  if (data.estimatedSavingsTokens > 0) {
14630
- console.log(` Estimated savings: ~${chalk23.green(data.estimatedSavingsTokens.toLocaleString())} tokens`);
14716
+ console.log(` Estimated savings: ~${chalk24.green(data.estimatedSavingsTokens.toLocaleString())} tokens`);
14631
14717
  }
14632
14718
  if (data.estimatedSavingsSeconds > 0) {
14633
- console.log(` Time saved: ~${chalk23.green(formatDuration(data.estimatedSavingsSeconds))}`);
14719
+ console.log(` Time saved: ~${chalk24.green(formatDuration(data.estimatedSavingsSeconds))}`);
14634
14720
  }
14635
14721
  }
14636
- console.log(chalk23.bold("\n Config Quality"));
14637
- console.log(` Score: ${chalk23.cyan(`${score.score}/100`)} (${score.grade})`);
14722
+ console.log(chalk24.bold("\n Config Quality"));
14723
+ console.log(` Score: ${chalk24.cyan(`${score.score}/100`)} (${score.grade})`);
14638
14724
  const history = readScoreHistory();
14639
14725
  const trend = getScoreTrend(history);
14640
14726
  if (trend) {
14641
- const trendColor = trend.direction === "up" ? chalk23.green : trend.direction === "down" ? chalk23.red : chalk23.gray;
14727
+ const trendColor = trend.direction === "up" ? chalk24.green : trend.direction === "down" ? chalk24.red : chalk24.gray;
14642
14728
  const arrow = trend.direction === "up" ? "\u2191" : trend.direction === "down" ? "\u2193" : "\u2192";
14643
14729
  const sign = trend.delta > 0 ? "+" : "";
14644
- console.log(` Trend: ${trendColor(`${arrow} ${sign}${trend.delta} pts`)} ${chalk23.dim(`over ${trend.entries} checks`)}`);
14730
+ console.log(` Trend: ${trendColor(`${arrow} ${sign}${trend.delta} pts`)} ${chalk24.dim(`over ${trend.entries} checks`)}`);
14645
14731
  }
14646
14732
  console.log("");
14647
14733
  }
@@ -14669,64 +14755,64 @@ async function insightsCommand(options) {
14669
14755
  }
14670
14756
 
14671
14757
  // src/commands/sources.ts
14672
- import fs48 from "fs";
14673
- import path39 from "path";
14674
- import chalk24 from "chalk";
14758
+ import fs49 from "fs";
14759
+ import path40 from "path";
14760
+ import chalk25 from "chalk";
14675
14761
  init_resolve_caliber();
14676
14762
  async function sourcesListCommand() {
14677
14763
  const dir = process.cwd();
14678
14764
  const configSources = loadSourcesConfig(dir);
14679
14765
  const workspaces = getDetectedWorkspaces(dir);
14680
14766
  if (configSources.length === 0 && workspaces.length === 0) {
14681
- console.log(chalk24.dim("\n No sources configured.\n"));
14682
- console.log(chalk24.dim(" Add a source: ") + chalk24.hex("#83D1EB")(`${resolveCaliber()} sources add <path>`));
14683
- console.log(chalk24.dim(" Or add to .caliber/sources.json manually.\n"));
14767
+ console.log(chalk25.dim("\n No sources configured.\n"));
14768
+ console.log(chalk25.dim(" Add a source: ") + chalk25.hex("#83D1EB")(`${resolveCaliber()} sources add <path>`));
14769
+ console.log(chalk25.dim(" Or add to .caliber/sources.json manually.\n"));
14684
14770
  return;
14685
14771
  }
14686
- console.log(chalk24.bold("\n External Sources\n"));
14772
+ console.log(chalk25.bold("\n External Sources\n"));
14687
14773
  if (configSources.length > 0) {
14688
14774
  for (const source of configSources) {
14689
14775
  const sourcePath = source.path || source.url || "";
14690
- const exists = source.path ? fs48.existsSync(path39.resolve(dir, source.path)) : false;
14691
- const status = exists ? chalk24.green("reachable") : chalk24.red("not found");
14692
- const hasSummary = source.path && fs48.existsSync(path39.join(path39.resolve(dir, source.path), ".caliber", "summary.json"));
14693
- console.log(` ${chalk24.bold(source.role || source.type)} ${chalk24.dim(sourcePath)}`);
14694
- console.log(` Type: ${source.type} Status: ${status}${hasSummary ? " " + chalk24.cyan("has summary.json") : ""}`);
14695
- if (source.description) console.log(` ${chalk24.dim(source.description)}`);
14776
+ const exists = source.path ? fs49.existsSync(path40.resolve(dir, source.path)) : false;
14777
+ const status = exists ? chalk25.green("reachable") : chalk25.red("not found");
14778
+ const hasSummary = source.path && fs49.existsSync(path40.join(path40.resolve(dir, source.path), ".caliber", "summary.json"));
14779
+ console.log(` ${chalk25.bold(source.role || source.type)} ${chalk25.dim(sourcePath)}`);
14780
+ console.log(` Type: ${source.type} Status: ${status}${hasSummary ? " " + chalk25.cyan("has summary.json") : ""}`);
14781
+ if (source.description) console.log(` ${chalk25.dim(source.description)}`);
14696
14782
  console.log("");
14697
14783
  }
14698
14784
  }
14699
14785
  if (workspaces.length > 0) {
14700
- console.log(chalk24.dim(" Auto-detected workspaces:"));
14786
+ console.log(chalk25.dim(" Auto-detected workspaces:"));
14701
14787
  for (const ws of workspaces) {
14702
- const exists = fs48.existsSync(path39.resolve(dir, ws));
14703
- console.log(` ${exists ? chalk24.green("\u25CF") : chalk24.red("\u25CF")} ${ws}`);
14788
+ const exists = fs49.existsSync(path40.resolve(dir, ws));
14789
+ console.log(` ${exists ? chalk25.green("\u25CF") : chalk25.red("\u25CF")} ${ws}`);
14704
14790
  }
14705
14791
  console.log("");
14706
14792
  }
14707
14793
  }
14708
14794
  async function sourcesAddCommand(sourcePath) {
14709
14795
  const dir = process.cwd();
14710
- const absPath = path39.resolve(dir, sourcePath);
14711
- if (!fs48.existsSync(absPath)) {
14712
- console.log(chalk24.red(`
14796
+ const absPath = path40.resolve(dir, sourcePath);
14797
+ if (!fs49.existsSync(absPath)) {
14798
+ console.log(chalk25.red(`
14713
14799
  Path not found: ${sourcePath}
14714
14800
  `));
14715
14801
  throw new Error("__exit__");
14716
14802
  }
14717
14803
  const type = detectSourceType(absPath);
14718
14804
  if (isInsideDir(absPath, dir)) {
14719
- console.log(chalk24.red(`
14805
+ console.log(chalk25.red(`
14720
14806
  Cannot add a path inside the current project as a source.
14721
14807
  `));
14722
14808
  throw new Error("__exit__");
14723
14809
  }
14724
14810
  const existing = loadSourcesConfig(dir);
14725
14811
  const alreadyConfigured = existing.some(
14726
- (s) => s.path && path39.resolve(dir, s.path) === absPath
14812
+ (s) => s.path && path40.resolve(dir, s.path) === absPath
14727
14813
  );
14728
14814
  if (alreadyConfigured) {
14729
- console.log(chalk24.yellow(`
14815
+ console.log(chalk25.yellow(`
14730
14816
  Already configured: ${sourcePath}
14731
14817
  `));
14732
14818
  return;
@@ -14743,7 +14829,7 @@ async function sourcesAddCommand(sourcePath) {
14743
14829
  };
14744
14830
  existing.push(newSource);
14745
14831
  writeSourcesConfig(dir, existing);
14746
- console.log(chalk24.green(`
14832
+ console.log(chalk25.green(`
14747
14833
  \u2713 Added ${sourcePath} as ${type} source (${role})
14748
14834
  `));
14749
14835
  }
@@ -14754,26 +14840,26 @@ async function sourcesRemoveCommand(name) {
14754
14840
  (s) => s.path?.includes(name) || s.role === name
14755
14841
  );
14756
14842
  if (idx === -1) {
14757
- console.log(chalk24.red(`
14843
+ console.log(chalk25.red(`
14758
14844
  Source not found: ${name}
14759
14845
  `));
14760
- console.log(chalk24.dim(" Available sources:"));
14846
+ console.log(chalk25.dim(" Available sources:"));
14761
14847
  for (const s of existing) {
14762
- console.log(chalk24.dim(` ${s.path || s.url} (${s.role || s.type})`));
14848
+ console.log(chalk25.dim(` ${s.path || s.url} (${s.role || s.type})`));
14763
14849
  }
14764
14850
  throw new Error("__exit__");
14765
14851
  }
14766
14852
  const removed = existing.splice(idx, 1)[0];
14767
14853
  writeSourcesConfig(dir, existing);
14768
- console.log(chalk24.green(`
14854
+ console.log(chalk25.green(`
14769
14855
  \u2713 Removed ${removed.path || removed.url} (${removed.role || removed.type})
14770
14856
  `));
14771
14857
  }
14772
14858
 
14773
14859
  // src/commands/publish.ts
14774
- import fs49 from "fs";
14775
- import path40 from "path";
14776
- import chalk25 from "chalk";
14860
+ import fs50 from "fs";
14861
+ import path41 from "path";
14862
+ import chalk26 from "chalk";
14777
14863
  import ora7 from "ora";
14778
14864
  init_config();
14779
14865
  init_resolve_caliber();
@@ -14781,16 +14867,16 @@ async function publishCommand() {
14781
14867
  const dir = process.cwd();
14782
14868
  const config = loadConfig();
14783
14869
  if (!config) {
14784
- console.log(chalk25.red("No LLM provider configured. Run ") + chalk25.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk25.red(" first."));
14870
+ console.log(chalk26.red("No LLM provider configured. Run ") + chalk26.hex("#83D1EB")(`${resolveCaliber()} config`) + chalk26.red(" first."));
14785
14871
  throw new Error("__exit__");
14786
14872
  }
14787
14873
  const spinner = ora7("Generating project summary...").start();
14788
14874
  try {
14789
14875
  const fingerprint = await collectFingerprint(dir);
14790
- const claudeMd = readFileOrNull(path40.join(dir, "CLAUDE.md"));
14876
+ const claudeMd = readFileOrNull(path41.join(dir, "CLAUDE.md"));
14791
14877
  const topLevelDirs = fingerprint.fileTree.filter((f) => f.endsWith("/") && !f.includes("/")).map((f) => f.replace(/\/$/, ""));
14792
14878
  const summary = {
14793
- name: fingerprint.packageName || path40.basename(dir),
14879
+ name: fingerprint.packageName || path41.basename(dir),
14794
14880
  version: "1.0.0",
14795
14881
  description: fingerprint.description || "",
14796
14882
  languages: fingerprint.languages,
@@ -14802,7 +14888,7 @@ async function publishCommand() {
14802
14888
  summary.conventions = claudeMd.slice(0, 2e3);
14803
14889
  }
14804
14890
  try {
14805
- const pkgContent = readFileOrNull(path40.join(dir, "package.json"));
14891
+ const pkgContent = readFileOrNull(path41.join(dir, "package.json"));
14806
14892
  if (pkgContent) {
14807
14893
  const pkg3 = JSON.parse(pkgContent);
14808
14894
  if (pkg3.scripts) {
@@ -14815,28 +14901,28 @@ async function publishCommand() {
14815
14901
  }
14816
14902
  } catch {
14817
14903
  }
14818
- const outputDir = path40.join(dir, ".caliber");
14819
- if (!fs49.existsSync(outputDir)) {
14820
- fs49.mkdirSync(outputDir, { recursive: true });
14904
+ const outputDir = path41.join(dir, ".caliber");
14905
+ if (!fs50.existsSync(outputDir)) {
14906
+ fs50.mkdirSync(outputDir, { recursive: true });
14821
14907
  }
14822
- const outputPath = path40.join(outputDir, "summary.json");
14823
- fs49.writeFileSync(outputPath, JSON.stringify(summary, null, 2) + "\n", "utf-8");
14908
+ const outputPath = path41.join(outputDir, "summary.json");
14909
+ fs50.writeFileSync(outputPath, JSON.stringify(summary, null, 2) + "\n", "utf-8");
14824
14910
  spinner.succeed("Project summary published");
14825
- console.log(` ${chalk25.green("\u2713")} ${path40.relative(dir, outputPath)}`);
14826
- console.log(chalk25.dim("\n Other projects can now reference this repo as a source."));
14827
- console.log(chalk25.dim(" When they run `caliber init`, they'll read this summary automatically.\n"));
14911
+ console.log(` ${chalk26.green("\u2713")} ${path41.relative(dir, outputPath)}`);
14912
+ console.log(chalk26.dim("\n Other projects can now reference this repo as a source."));
14913
+ console.log(chalk26.dim(" When they run `caliber init`, they'll read this summary automatically.\n"));
14828
14914
  } catch (err) {
14829
14915
  spinner.fail("Failed to generate summary");
14830
14916
  if (err instanceof Error && err.message === "__exit__") throw err;
14831
- console.error(chalk25.red(err instanceof Error ? err.message : "Unknown error"));
14917
+ console.error(chalk26.red(err instanceof Error ? err.message : "Unknown error"));
14832
14918
  throw new Error("__exit__");
14833
14919
  }
14834
14920
  }
14835
14921
 
14836
14922
  // src/commands/bootstrap.ts
14837
14923
  init_builtin_skills();
14838
- import fs50 from "fs";
14839
- import chalk26 from "chalk";
14924
+ import fs51 from "fs";
14925
+ import chalk27 from "chalk";
14840
14926
  var PLATFORM_SKILL_DIRS = {
14841
14927
  claude: ".claude/skills",
14842
14928
  cursor: ".cursor/skills",
@@ -14856,46 +14942,46 @@ async function bootstrapCommand() {
14856
14942
  for (const skill of BUILTIN_SKILLS) {
14857
14943
  const skillDir = `${skillsDir}/${skill.name}`;
14858
14944
  const skillPath = `${skillDir}/SKILL.md`;
14859
- fs50.mkdirSync(skillDir, { recursive: true });
14860
- fs50.writeFileSync(skillPath, buildSkillContent(skill));
14945
+ fs51.mkdirSync(skillDir, { recursive: true });
14946
+ fs51.writeFileSync(skillPath, buildSkillContent(skill));
14861
14947
  written.push(skillPath);
14862
14948
  }
14863
14949
  }
14864
14950
  if (written.length === 0) {
14865
- console.log(chalk26.yellow("No skills were written."));
14951
+ console.log(chalk27.yellow("No skills were written."));
14866
14952
  return;
14867
14953
  }
14868
- console.log(chalk26.bold.green("\n Caliber skills installed!\n"));
14954
+ console.log(chalk27.bold.green("\n Caliber skills installed!\n"));
14869
14955
  for (const file of written) {
14870
- console.log(` ${chalk26.green("\u2713")} ${file}`);
14956
+ console.log(` ${chalk27.green("\u2713")} ${file}`);
14871
14957
  }
14872
- console.log(chalk26.dim("\n Your agent can now run /setup-caliber to complete the setup."));
14873
- console.log(chalk26.dim(' Just tell your agent: "Run /setup-caliber"\n'));
14958
+ console.log(chalk27.dim("\n Your agent can now run /setup-caliber to complete the setup."));
14959
+ console.log(chalk27.dim(' Just tell your agent: "Run /setup-caliber"\n'));
14874
14960
  }
14875
14961
 
14876
14962
  // src/commands/uninstall.ts
14877
- import fs51 from "fs";
14878
- import path41 from "path";
14879
- import chalk27 from "chalk";
14963
+ import fs52 from "fs";
14964
+ import path42 from "path";
14965
+ import chalk28 from "chalk";
14880
14966
  import confirm3 from "@inquirer/confirm";
14881
14967
  init_pre_commit_block();
14882
14968
  init_builtin_skills();
14883
14969
  init_config();
14884
14970
  var MANAGED_DOC_FILES = [
14885
14971
  "CLAUDE.md",
14886
- path41.join(".github", "copilot-instructions.md"),
14972
+ path42.join(".github", "copilot-instructions.md"),
14887
14973
  "AGENTS.md"
14888
14974
  ];
14889
14975
  var SKILL_DIRS = PLATFORM_CONFIGS.map((c) => c.skillsDir);
14890
- var CURSOR_RULES_DIR = path41.join(".cursor", "rules");
14891
- var CLAUDE_RULES_DIR = path41.join(".claude", "rules");
14976
+ var CURSOR_RULES_DIR = path42.join(".cursor", "rules");
14977
+ var CLAUDE_RULES_DIR = path42.join(".claude", "rules");
14892
14978
  function removeCaliberManagedFiles(dir, extension) {
14893
14979
  const removed = [];
14894
- if (!fs51.existsSync(dir)) return removed;
14895
- for (const file of fs51.readdirSync(dir)) {
14980
+ if (!fs52.existsSync(dir)) return removed;
14981
+ for (const file of fs52.readdirSync(dir)) {
14896
14982
  if (file.startsWith(CALIBER_MANAGED_PREFIX) && file.endsWith(extension)) {
14897
- const fullPath = path41.join(dir, file);
14898
- fs51.unlinkSync(fullPath);
14983
+ const fullPath = path42.join(dir, file);
14984
+ fs52.unlinkSync(fullPath);
14899
14985
  removed.push(fullPath);
14900
14986
  }
14901
14987
  }
@@ -14904,11 +14990,11 @@ function removeCaliberManagedFiles(dir, extension) {
14904
14990
  function removeBuiltinSkills() {
14905
14991
  const removed = [];
14906
14992
  for (const skillsDir of SKILL_DIRS) {
14907
- if (!fs51.existsSync(skillsDir)) continue;
14993
+ if (!fs52.existsSync(skillsDir)) continue;
14908
14994
  for (const name of BUILTIN_SKILL_NAMES) {
14909
- const skillDir = path41.join(skillsDir, name);
14910
- if (fs51.existsSync(skillDir)) {
14911
- fs51.rmSync(skillDir, { recursive: true });
14995
+ const skillDir = path42.join(skillsDir, name);
14996
+ if (fs52.existsSync(skillDir)) {
14997
+ fs52.rmSync(skillDir, { recursive: true });
14912
14998
  removed.push(skillDir);
14913
14999
  }
14914
15000
  }
@@ -14918,15 +15004,15 @@ function removeBuiltinSkills() {
14918
15004
  function stripManagedBlocksFromFiles() {
14919
15005
  const modified = [];
14920
15006
  for (const filePath of MANAGED_DOC_FILES) {
14921
- if (!fs51.existsSync(filePath)) continue;
14922
- const original = fs51.readFileSync(filePath, "utf-8");
15007
+ if (!fs52.existsSync(filePath)) continue;
15008
+ const original = fs52.readFileSync(filePath, "utf-8");
14923
15009
  const stripped = stripManagedBlocks(original);
14924
15010
  if (stripped !== original) {
14925
15011
  const trimmed = stripped.trim();
14926
15012
  if (!trimmed || /^#\s*\S*$/.test(trimmed)) {
14927
- fs51.unlinkSync(filePath);
15013
+ fs52.unlinkSync(filePath);
14928
15014
  } else {
14929
- fs51.writeFileSync(filePath, stripped);
15015
+ fs52.writeFileSync(filePath, stripped);
14930
15016
  }
14931
15017
  modified.push(filePath);
14932
15018
  }
@@ -14934,24 +15020,24 @@ function stripManagedBlocksFromFiles() {
14934
15020
  return modified;
14935
15021
  }
14936
15022
  function removeDirectory(dir) {
14937
- if (!fs51.existsSync(dir)) return false;
14938
- fs51.rmSync(dir, { recursive: true });
15023
+ if (!fs52.existsSync(dir)) return false;
15024
+ fs52.rmSync(dir, { recursive: true });
14939
15025
  return true;
14940
15026
  }
14941
15027
  async function uninstallCommand(options) {
14942
- console.log(chalk27.bold("\n Caliber Uninstall\n"));
14943
- console.log(chalk27.dim(" This will remove all Caliber resources from this project:\n"));
14944
- console.log(chalk27.dim(" \u2022 Pre-commit hook"));
14945
- console.log(chalk27.dim(" \u2022 Session learning hooks"));
14946
- console.log(chalk27.dim(" \u2022 Managed blocks in CLAUDE.md, AGENTS.md, copilot-instructions.md"));
14947
- console.log(chalk27.dim(" \u2022 Cursor rules (caliber-*.mdc)"));
14948
- console.log(chalk27.dim(" \u2022 Built-in skills (setup-caliber, find-skills, save-learning)"));
14949
- console.log(chalk27.dim(" \u2022 CALIBER_LEARNINGS.md"));
14950
- console.log(chalk27.dim(" \u2022 .caliber/ directory (backups, cache, state)\n"));
15028
+ console.log(chalk28.bold("\n Caliber Uninstall\n"));
15029
+ console.log(chalk28.dim(" This will remove all Caliber resources from this project:\n"));
15030
+ console.log(chalk28.dim(" \u2022 Pre-commit hook"));
15031
+ console.log(chalk28.dim(" \u2022 Session learning hooks"));
15032
+ console.log(chalk28.dim(" \u2022 Managed blocks in CLAUDE.md, AGENTS.md, copilot-instructions.md"));
15033
+ console.log(chalk28.dim(" \u2022 Cursor rules (caliber-*.mdc)"));
15034
+ console.log(chalk28.dim(" \u2022 Built-in skills (setup-caliber, find-skills, save-learning)"));
15035
+ console.log(chalk28.dim(" \u2022 CALIBER_LEARNINGS.md"));
15036
+ console.log(chalk28.dim(" \u2022 .caliber/ directory (backups, cache, state)\n"));
14951
15037
  if (!options.force) {
14952
15038
  const proceed = await confirm3({ message: "Continue with uninstall?" });
14953
15039
  if (!proceed) {
14954
- console.log(chalk27.dim("\n Cancelled.\n"));
15040
+ console.log(chalk28.dim("\n Cancelled.\n"));
14955
15041
  return;
14956
15042
  }
14957
15043
  }
@@ -14959,93 +15045,93 @@ async function uninstallCommand(options) {
14959
15045
  const actions = [];
14960
15046
  const hookResult = removePreCommitHook();
14961
15047
  if (hookResult.removed) {
14962
- console.log(` ${chalk27.red("\u2717")} Pre-commit hook removed`);
15048
+ console.log(` ${chalk28.red("\u2717")} Pre-commit hook removed`);
14963
15049
  actions.push("pre-commit hook");
14964
15050
  }
14965
15051
  const stopHookResult = removeStopHook();
14966
15052
  if (stopHookResult.removed) {
14967
- console.log(` ${chalk27.red("\u2717")} Onboarding hook removed`);
15053
+ console.log(` ${chalk28.red("\u2717")} Onboarding hook removed`);
14968
15054
  actions.push("onboarding hook");
14969
15055
  }
14970
15056
  const notificationHookResult = removeNotificationHook();
14971
15057
  if (notificationHookResult.removed) {
14972
- console.log(` ${chalk27.red("\u2717")} Notification hook removed`);
15058
+ console.log(` ${chalk28.red("\u2717")} Notification hook removed`);
14973
15059
  actions.push("notification hook");
14974
15060
  }
14975
15061
  const sessionStartResult = removeSessionStartHook();
14976
15062
  if (sessionStartResult.removed) {
14977
- console.log(` ${chalk27.red("\u2717")} SessionStart hook removed`);
15063
+ console.log(` ${chalk28.red("\u2717")} SessionStart hook removed`);
14978
15064
  actions.push("session-start hook");
14979
15065
  }
14980
15066
  const learnResult = removeLearningHooks();
14981
15067
  if (learnResult.removed) {
14982
- console.log(` ${chalk27.red("\u2717")} Claude Code learning hooks removed`);
15068
+ console.log(` ${chalk28.red("\u2717")} Claude Code learning hooks removed`);
14983
15069
  actions.push("claude learning hooks");
14984
15070
  }
14985
15071
  const cursorLearnResult = removeCursorLearningHooks();
14986
15072
  if (cursorLearnResult.removed) {
14987
- console.log(` ${chalk27.red("\u2717")} Cursor learning hooks removed`);
15073
+ console.log(` ${chalk28.red("\u2717")} Cursor learning hooks removed`);
14988
15074
  actions.push("cursor learning hooks");
14989
15075
  }
14990
15076
  const strippedFiles = stripManagedBlocksFromFiles();
14991
15077
  for (const file of strippedFiles) {
14992
- console.log(` ${chalk27.yellow("~")} ${file} \u2014 managed blocks removed`);
15078
+ console.log(` ${chalk28.yellow("~")} ${file} \u2014 managed blocks removed`);
14993
15079
  actions.push(file);
14994
15080
  }
14995
15081
  const removedCursorRules = removeCaliberManagedFiles(CURSOR_RULES_DIR, ".mdc");
14996
15082
  for (const rule of removedCursorRules) {
14997
- console.log(` ${chalk27.red("\u2717")} ${rule}`);
15083
+ console.log(` ${chalk28.red("\u2717")} ${rule}`);
14998
15084
  }
14999
15085
  if (removedCursorRules.length > 0) actions.push("cursor rules");
15000
15086
  const removedClaudeRules = removeCaliberManagedFiles(CLAUDE_RULES_DIR, ".md");
15001
15087
  for (const rule of removedClaudeRules) {
15002
- console.log(` ${chalk27.red("\u2717")} ${rule}`);
15088
+ console.log(` ${chalk28.red("\u2717")} ${rule}`);
15003
15089
  }
15004
15090
  if (removedClaudeRules.length > 0) actions.push("claude rules");
15005
15091
  const removedSkills = removeBuiltinSkills();
15006
15092
  for (const skill of removedSkills) {
15007
- console.log(` ${chalk27.red("\u2717")} ${skill}/`);
15093
+ console.log(` ${chalk28.red("\u2717")} ${skill}/`);
15008
15094
  }
15009
15095
  if (removedSkills.length > 0) actions.push("builtin skills");
15010
- if (fs51.existsSync("CALIBER_LEARNINGS.md")) {
15011
- fs51.unlinkSync("CALIBER_LEARNINGS.md");
15012
- console.log(` ${chalk27.red("\u2717")} CALIBER_LEARNINGS.md`);
15096
+ if (fs52.existsSync("CALIBER_LEARNINGS.md")) {
15097
+ fs52.unlinkSync("CALIBER_LEARNINGS.md");
15098
+ console.log(` ${chalk28.red("\u2717")} CALIBER_LEARNINGS.md`);
15013
15099
  actions.push("learnings file");
15014
15100
  }
15015
15101
  if (removeDirectory(CALIBER_DIR)) {
15016
- console.log(` ${chalk27.red("\u2717")} .caliber/ directory`);
15102
+ console.log(` ${chalk28.red("\u2717")} .caliber/ directory`);
15017
15103
  actions.push(".caliber directory");
15018
15104
  }
15019
15105
  if (actions.length === 0) {
15020
- console.log(chalk27.dim(" Nothing to remove \u2014 Caliber is not installed in this project.\n"));
15106
+ console.log(chalk28.dim(" Nothing to remove \u2014 Caliber is not installed in this project.\n"));
15021
15107
  return;
15022
15108
  }
15023
15109
  trackUninstallExecuted();
15024
15110
  const configPath = getConfigFilePath();
15025
- if (fs51.existsSync(configPath)) {
15111
+ if (fs52.existsSync(configPath)) {
15026
15112
  console.log("");
15027
15113
  const removeConfig = options.force || await confirm3({
15028
15114
  message: `Remove global config (~/.caliber/config.json)? This affects all projects.`
15029
15115
  });
15030
15116
  if (removeConfig) {
15031
- fs51.unlinkSync(configPath);
15032
- console.log(` ${chalk27.red("\u2717")} ${configPath}`);
15033
- const configDir = path41.dirname(configPath);
15117
+ fs52.unlinkSync(configPath);
15118
+ console.log(` ${chalk28.red("\u2717")} ${configPath}`);
15119
+ const configDir = path42.dirname(configPath);
15034
15120
  try {
15035
- const remaining = fs51.readdirSync(configDir);
15036
- if (remaining.length === 0) fs51.rmdirSync(configDir);
15121
+ const remaining = fs52.readdirSync(configDir);
15122
+ if (remaining.length === 0) fs52.rmdirSync(configDir);
15037
15123
  } catch {
15038
15124
  }
15039
15125
  }
15040
15126
  }
15041
- console.log(chalk27.bold.green(`
15127
+ console.log(chalk28.bold.green(`
15042
15128
  Caliber has been removed from this project.`));
15043
- console.log(chalk27.dim(" Your code is untouched \u2014 only Caliber config files were removed.\n"));
15129
+ console.log(chalk28.dim(" Your code is untouched \u2014 only Caliber config files were removed.\n"));
15044
15130
  }
15045
15131
 
15046
15132
  // src/cli.ts
15047
- var __dirname = path42.dirname(fileURLToPath(import.meta.url));
15048
- var pkg = JSON.parse(fs52.readFileSync(path42.resolve(__dirname, "..", "package.json"), "utf-8"));
15133
+ var __dirname = path43.dirname(fileURLToPath(import.meta.url));
15134
+ var pkg = JSON.parse(fs53.readFileSync(path43.resolve(__dirname, "..", "package.json"), "utf-8"));
15049
15135
  var program = new Command();
15050
15136
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
15051
15137
  program.name(process.env.CALIBER_LOCAL ? "caloc" : "caliber").description("AI context infrastructure for coding agents").version(displayVersion).option("--no-traces", "Disable anonymous telemetry for this run");
@@ -15156,15 +15242,15 @@ learn.command("delete <index>").description("Delete a learning by its index numb
15156
15242
  learn.command("add <content>").description("Add a learning directly (used by agent skills)").option("--personal", "Save as a personal learning instead of project-level").action(tracked("learn:add", learnAddCommand));
15157
15243
 
15158
15244
  // src/utils/version-check.ts
15159
- import fs53 from "fs";
15160
- import path43 from "path";
15245
+ import fs54 from "fs";
15246
+ import path44 from "path";
15161
15247
  import { fileURLToPath as fileURLToPath2 } from "url";
15162
15248
  import { execSync as execSync18, execFileSync as execFileSync5 } from "child_process";
15163
- import chalk28 from "chalk";
15249
+ import chalk29 from "chalk";
15164
15250
  import ora8 from "ora";
15165
15251
  import confirm4 from "@inquirer/confirm";
15166
- var __dirname_vc = path43.dirname(fileURLToPath2(import.meta.url));
15167
- var pkg2 = JSON.parse(fs53.readFileSync(path43.resolve(__dirname_vc, "..", "package.json"), "utf-8"));
15252
+ var __dirname_vc = path44.dirname(fileURLToPath2(import.meta.url));
15253
+ var pkg2 = JSON.parse(fs54.readFileSync(path44.resolve(__dirname_vc, "..", "package.json"), "utf-8"));
15168
15254
  function getChannel(version) {
15169
15255
  const match = version.match(/-(dev|next)\./);
15170
15256
  return match ? match[1] : "latest";
@@ -15191,8 +15277,8 @@ function getInstalledVersion() {
15191
15277
  encoding: "utf-8",
15192
15278
  stdio: ["pipe", "pipe", "pipe"]
15193
15279
  }).trim();
15194
- const pkgPath = path43.join(globalRoot, "@rely-ai", "caliber", "package.json");
15195
- return JSON.parse(fs53.readFileSync(pkgPath, "utf-8")).version;
15280
+ const pkgPath = path44.join(globalRoot, "@rely-ai", "caliber", "package.json");
15281
+ return JSON.parse(fs54.readFileSync(pkgPath, "utf-8")).version;
15196
15282
  } catch {
15197
15283
  return null;
15198
15284
  }
@@ -15217,16 +15303,16 @@ async function checkForUpdates() {
15217
15303
  if (!isInteractive) {
15218
15304
  const installTag = channel === "latest" ? "" : `@${channel}`;
15219
15305
  console.log(
15220
- chalk28.yellow(
15306
+ chalk29.yellow(
15221
15307
  `
15222
15308
  Update available: ${current} -> ${latest}
15223
- Run ${chalk28.bold(`npm install -g @rely-ai/caliber${installTag}`)} to upgrade.
15309
+ Run ${chalk29.bold(`npm install -g @rely-ai/caliber${installTag}`)} to upgrade.
15224
15310
  `
15225
15311
  )
15226
15312
  );
15227
15313
  return;
15228
15314
  }
15229
- console.log(chalk28.yellow(`
15315
+ console.log(chalk29.yellow(`
15230
15316
  Update available: ${current} -> ${latest}`));
15231
15317
  const shouldUpdate = await confirm4({
15232
15318
  message: "Would you like to update now? (Y/n)",
@@ -15249,14 +15335,14 @@ Update available: ${current} -> ${latest}`));
15249
15335
  if (installed !== latest) {
15250
15336
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
15251
15337
  console.log(
15252
- chalk28.yellow(`Run ${chalk28.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually.
15338
+ chalk29.yellow(`Run ${chalk29.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually.
15253
15339
  `)
15254
15340
  );
15255
15341
  return;
15256
15342
  }
15257
- spinner.succeed(chalk28.green(`Updated to ${latest}`));
15343
+ spinner.succeed(chalk29.green(`Updated to ${latest}`));
15258
15344
  const args = process.argv.slice(2);
15259
- console.log(chalk28.dim(`
15345
+ console.log(chalk29.dim(`
15260
15346
  Restarting: caliber ${args.join(" ")}
15261
15347
  `));
15262
15348
  execFileSync5("caliber", args, {
@@ -15269,11 +15355,11 @@ Restarting: caliber ${args.join(" ")}
15269
15355
  if (err instanceof Error) {
15270
15356
  const stderr = err.stderr;
15271
15357
  const errMsg = stderr ? String(stderr).trim().split("\n").pop() : err.message.split("\n")[0];
15272
- if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk28.dim(` ${errMsg}`));
15358
+ if (errMsg && !errMsg.includes("SIGTERM")) console.log(chalk29.dim(` ${errMsg}`));
15273
15359
  }
15274
15360
  console.log(
15275
- chalk28.yellow(
15276
- `Run ${chalk28.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually to upgrade.
15361
+ chalk29.yellow(
15362
+ `Run ${chalk29.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually to upgrade.
15277
15363
  `
15278
15364
  )
15279
15365
  );