@rely-ai/caliber 1.20.0-dev.1773685636 → 1.20.0-dev.1773686430

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 +262 -230
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -177,13 +177,13 @@ __export(lock_exports, {
177
177
  isCaliberRunning: () => isCaliberRunning,
178
178
  releaseLock: () => releaseLock
179
179
  });
180
- import fs28 from "fs";
181
- import path22 from "path";
182
- import os4 from "os";
180
+ import fs29 from "fs";
181
+ import path23 from "path";
182
+ import os5 from "os";
183
183
  function isCaliberRunning() {
184
184
  try {
185
- if (!fs28.existsSync(LOCK_FILE)) return false;
186
- const raw = fs28.readFileSync(LOCK_FILE, "utf-8").trim();
185
+ if (!fs29.existsSync(LOCK_FILE)) return false;
186
+ const raw = fs29.readFileSync(LOCK_FILE, "utf-8").trim();
187
187
  const { pid, ts } = JSON.parse(raw);
188
188
  if (Date.now() - ts > STALE_MS) return false;
189
189
  try {
@@ -198,13 +198,13 @@ function isCaliberRunning() {
198
198
  }
199
199
  function acquireLock() {
200
200
  try {
201
- fs28.writeFileSync(LOCK_FILE, JSON.stringify({ pid: process.pid, ts: Date.now() }));
201
+ fs29.writeFileSync(LOCK_FILE, JSON.stringify({ pid: process.pid, ts: Date.now() }));
202
202
  } catch {
203
203
  }
204
204
  }
205
205
  function releaseLock() {
206
206
  try {
207
- if (fs28.existsSync(LOCK_FILE)) fs28.unlinkSync(LOCK_FILE);
207
+ if (fs29.existsSync(LOCK_FILE)) fs29.unlinkSync(LOCK_FILE);
208
208
  } catch {
209
209
  }
210
210
  }
@@ -212,24 +212,24 @@ var LOCK_FILE, STALE_MS;
212
212
  var init_lock = __esm({
213
213
  "src/lib/lock.ts"() {
214
214
  "use strict";
215
- LOCK_FILE = path22.join(os4.tmpdir(), ".caliber.lock");
215
+ LOCK_FILE = path23.join(os5.tmpdir(), ".caliber.lock");
216
216
  STALE_MS = 10 * 60 * 1e3;
217
217
  }
218
218
  });
219
219
 
220
220
  // src/cli.ts
221
221
  import { Command } from "commander";
222
- import fs32 from "fs";
223
- import path25 from "path";
222
+ import fs33 from "fs";
223
+ import path26 from "path";
224
224
  import { fileURLToPath } from "url";
225
225
 
226
226
  // src/commands/init.ts
227
- import path19 from "path";
227
+ import path20 from "path";
228
228
  import chalk10 from "chalk";
229
229
  import ora2 from "ora";
230
230
  import select5 from "@inquirer/select";
231
231
  import checkbox from "@inquirer/checkbox";
232
- import fs24 from "fs";
232
+ import fs25 from "fs";
233
233
 
234
234
  // src/fingerprint/index.ts
235
235
  import fs6 from "fs";
@@ -2262,15 +2262,15 @@ init_config();
2262
2262
  // src/utils/dependencies.ts
2263
2263
  import { readFileSync } from "fs";
2264
2264
  import { join } from "path";
2265
- function readFileOrNull(path27) {
2265
+ function readFileOrNull(path28) {
2266
2266
  try {
2267
- return readFileSync(path27, "utf-8");
2267
+ return readFileSync(path28, "utf-8");
2268
2268
  } catch {
2269
2269
  return null;
2270
2270
  }
2271
2271
  }
2272
- function readJsonOrNull(path27) {
2273
- const content = readFileOrNull(path27);
2272
+ function readJsonOrNull(path28) {
2273
+ const content = readFileOrNull(path28);
2274
2274
  if (!content) return null;
2275
2275
  try {
2276
2276
  return JSON.parse(content);
@@ -3236,13 +3236,23 @@ function cleanupStaging() {
3236
3236
 
3237
3237
  // src/utils/review.ts
3238
3238
  import chalk2 from "chalk";
3239
- import fs14 from "fs";
3239
+ import fs15 from "fs";
3240
3240
  import select2 from "@inquirer/select";
3241
3241
  import { createTwoFilesPatch } from "diff";
3242
3242
 
3243
3243
  // src/utils/editor.ts
3244
3244
  import { execSync as execSync5, spawn as spawn3 } from "child_process";
3245
+ import fs14 from "fs";
3246
+ import path12 from "path";
3247
+ import os3 from "os";
3245
3248
  var IS_WINDOWS3 = process.platform === "win32";
3249
+ var DIFF_TEMP_DIR = path12.join(os3.tmpdir(), "caliber-diff");
3250
+ function getEmptyFilePath(proposedPath) {
3251
+ fs14.mkdirSync(DIFF_TEMP_DIR, { recursive: true });
3252
+ const tempPath = path12.join(DIFF_TEMP_DIR, path12.basename(proposedPath));
3253
+ fs14.writeFileSync(tempPath, "");
3254
+ return tempPath;
3255
+ }
3246
3256
  function commandExists(cmd) {
3247
3257
  try {
3248
3258
  const check = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
@@ -3263,13 +3273,12 @@ function openDiffsInEditor(editor, files) {
3263
3273
  const cmd = editor === "cursor" ? "cursor" : "code";
3264
3274
  for (const file of files) {
3265
3275
  try {
3276
+ const leftPath = file.originalPath ?? getEmptyFilePath(file.proposedPath);
3266
3277
  if (IS_WINDOWS3) {
3267
3278
  const quote = (s) => `"${s}"`;
3268
- const parts = file.originalPath ? [cmd, "--diff", quote(file.originalPath), quote(file.proposedPath)] : [cmd, quote(file.proposedPath)];
3269
- spawn3(parts.join(" "), { shell: true, stdio: "ignore", detached: true }).unref();
3279
+ spawn3([cmd, "--diff", quote(leftPath), quote(file.proposedPath)].join(" "), { shell: true, stdio: "ignore", detached: true }).unref();
3270
3280
  } else {
3271
- const args = file.originalPath ? ["--diff", file.originalPath, file.proposedPath] : [file.proposedPath];
3272
- spawn3(cmd, args, { stdio: "ignore", detached: true }).unref();
3281
+ spawn3(cmd, ["--diff", leftPath, file.proposedPath], { stdio: "ignore", detached: true }).unref();
3273
3282
  }
3274
3283
  } catch {
3275
3284
  continue;
@@ -3312,8 +3321,8 @@ async function openReview(method, stagedFiles) {
3312
3321
  return;
3313
3322
  }
3314
3323
  const fileInfos = stagedFiles.map((file) => {
3315
- const proposed = fs14.readFileSync(file.proposedPath, "utf-8");
3316
- const current = file.currentPath ? fs14.readFileSync(file.currentPath, "utf-8") : "";
3324
+ const proposed = fs15.readFileSync(file.proposedPath, "utf-8");
3325
+ const current = file.currentPath ? fs15.readFileSync(file.currentPath, "utf-8") : "";
3317
3326
  const patch = createTwoFilesPatch(
3318
3327
  file.isNew ? "/dev/null" : file.relativePath,
3319
3328
  file.relativePath,
@@ -3476,7 +3485,7 @@ async function interactiveDiffExplorer(files) {
3476
3485
  }
3477
3486
 
3478
3487
  // src/commands/setup-files.ts
3479
- import fs15 from "fs";
3488
+ import fs16 from "fs";
3480
3489
  function buildSkillContent(skill) {
3481
3490
  const frontmatter = `---
3482
3491
  name: ${skill.name}
@@ -3525,7 +3534,7 @@ function collectSetupFiles(setup, targetAgent) {
3525
3534
  }
3526
3535
  }
3527
3536
  const codexTargeted = targetAgent ? targetAgent.includes("codex") : false;
3528
- if (codexTargeted && !fs15.existsSync("AGENTS.md") && !(codex && codex.agentsMd)) {
3537
+ if (codexTargeted && !fs16.existsSync("AGENTS.md") && !(codex && codex.agentsMd)) {
3529
3538
  const agentRefs = [];
3530
3539
  if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
3531
3540
  if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
@@ -3542,12 +3551,12 @@ ${agentRefs.join(" ")}
3542
3551
  }
3543
3552
 
3544
3553
  // src/lib/hooks.ts
3545
- import fs17 from "fs";
3546
- import path12 from "path";
3554
+ import fs18 from "fs";
3555
+ import path13 from "path";
3547
3556
  import { execSync as execSync7 } from "child_process";
3548
3557
 
3549
3558
  // src/lib/resolve-caliber.ts
3550
- import fs16 from "fs";
3559
+ import fs17 from "fs";
3551
3560
  import { execSync as execSync6 } from "child_process";
3552
3561
  var _resolved = null;
3553
3562
  function resolveCaliber() {
@@ -3570,7 +3579,7 @@ function resolveCaliber() {
3570
3579
  } catch {
3571
3580
  }
3572
3581
  const binPath = process.argv[1];
3573
- if (binPath && fs16.existsSync(binPath)) {
3582
+ if (binPath && fs17.existsSync(binPath)) {
3574
3583
  _resolved = binPath;
3575
3584
  return _resolved;
3576
3585
  }
@@ -3586,24 +3595,24 @@ function isCaliberCommand(command, subcommandTail) {
3586
3595
  }
3587
3596
 
3588
3597
  // src/lib/hooks.ts
3589
- var SETTINGS_PATH = path12.join(".claude", "settings.json");
3598
+ var SETTINGS_PATH = path13.join(".claude", "settings.json");
3590
3599
  var REFRESH_TAIL = "refresh --quiet";
3591
3600
  var HOOK_DESCRIPTION = "Caliber: auto-refreshing docs based on code changes";
3592
3601
  function getHookCommand() {
3593
3602
  return `${resolveCaliber()} ${REFRESH_TAIL}`;
3594
3603
  }
3595
3604
  function readSettings() {
3596
- if (!fs17.existsSync(SETTINGS_PATH)) return {};
3605
+ if (!fs18.existsSync(SETTINGS_PATH)) return {};
3597
3606
  try {
3598
- return JSON.parse(fs17.readFileSync(SETTINGS_PATH, "utf-8"));
3607
+ return JSON.parse(fs18.readFileSync(SETTINGS_PATH, "utf-8"));
3599
3608
  } catch {
3600
3609
  return {};
3601
3610
  }
3602
3611
  }
3603
3612
  function writeSettings(settings) {
3604
- const dir = path12.dirname(SETTINGS_PATH);
3605
- if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
3606
- fs17.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
3613
+ const dir = path13.dirname(SETTINGS_PATH);
3614
+ if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
3615
+ fs18.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
3607
3616
  }
3608
3617
  function findHookIndex(sessionEnd) {
3609
3618
  return sessionEnd.findIndex(
@@ -3666,19 +3675,19 @@ ${PRECOMMIT_END}`;
3666
3675
  function getGitHooksDir() {
3667
3676
  try {
3668
3677
  const gitDir = execSync7("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
3669
- return path12.join(gitDir, "hooks");
3678
+ return path13.join(gitDir, "hooks");
3670
3679
  } catch {
3671
3680
  return null;
3672
3681
  }
3673
3682
  }
3674
3683
  function getPreCommitPath() {
3675
3684
  const hooksDir = getGitHooksDir();
3676
- return hooksDir ? path12.join(hooksDir, "pre-commit") : null;
3685
+ return hooksDir ? path13.join(hooksDir, "pre-commit") : null;
3677
3686
  }
3678
3687
  function isPreCommitHookInstalled() {
3679
3688
  const hookPath = getPreCommitPath();
3680
- if (!hookPath || !fs17.existsSync(hookPath)) return false;
3681
- const content = fs17.readFileSync(hookPath, "utf-8");
3689
+ if (!hookPath || !fs18.existsSync(hookPath)) return false;
3690
+ const content = fs18.readFileSync(hookPath, "utf-8");
3682
3691
  return content.includes(PRECOMMIT_START);
3683
3692
  }
3684
3693
  function installPreCommitHook() {
@@ -3687,43 +3696,43 @@ function installPreCommitHook() {
3687
3696
  }
3688
3697
  const hookPath = getPreCommitPath();
3689
3698
  if (!hookPath) return { installed: false, alreadyInstalled: false };
3690
- const hooksDir = path12.dirname(hookPath);
3691
- if (!fs17.existsSync(hooksDir)) fs17.mkdirSync(hooksDir, { recursive: true });
3699
+ const hooksDir = path13.dirname(hookPath);
3700
+ if (!fs18.existsSync(hooksDir)) fs18.mkdirSync(hooksDir, { recursive: true });
3692
3701
  let content = "";
3693
- if (fs17.existsSync(hookPath)) {
3694
- content = fs17.readFileSync(hookPath, "utf-8");
3702
+ if (fs18.existsSync(hookPath)) {
3703
+ content = fs18.readFileSync(hookPath, "utf-8");
3695
3704
  if (!content.endsWith("\n")) content += "\n";
3696
3705
  content += "\n" + getPrecommitBlock() + "\n";
3697
3706
  } else {
3698
3707
  content = "#!/bin/sh\n\n" + getPrecommitBlock() + "\n";
3699
3708
  }
3700
- fs17.writeFileSync(hookPath, content);
3701
- fs17.chmodSync(hookPath, 493);
3709
+ fs18.writeFileSync(hookPath, content);
3710
+ fs18.chmodSync(hookPath, 493);
3702
3711
  return { installed: true, alreadyInstalled: false };
3703
3712
  }
3704
3713
  function removePreCommitHook() {
3705
3714
  const hookPath = getPreCommitPath();
3706
- if (!hookPath || !fs17.existsSync(hookPath)) {
3715
+ if (!hookPath || !fs18.existsSync(hookPath)) {
3707
3716
  return { removed: false, notFound: true };
3708
3717
  }
3709
- let content = fs17.readFileSync(hookPath, "utf-8");
3718
+ let content = fs18.readFileSync(hookPath, "utf-8");
3710
3719
  if (!content.includes(PRECOMMIT_START)) {
3711
3720
  return { removed: false, notFound: true };
3712
3721
  }
3713
3722
  const regex2 = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
3714
3723
  content = content.replace(regex2, "\n");
3715
3724
  if (content.trim() === "#!/bin/sh" || content.trim() === "") {
3716
- fs17.unlinkSync(hookPath);
3725
+ fs18.unlinkSync(hookPath);
3717
3726
  } else {
3718
- fs17.writeFileSync(hookPath, content);
3727
+ fs18.writeFileSync(hookPath, content);
3719
3728
  }
3720
3729
  return { removed: true, notFound: false };
3721
3730
  }
3722
3731
 
3723
3732
  // src/lib/learning-hooks.ts
3724
- import fs18 from "fs";
3725
- import path13 from "path";
3726
- var SETTINGS_PATH2 = path13.join(".claude", "settings.json");
3733
+ import fs19 from "fs";
3734
+ import path14 from "path";
3735
+ var SETTINGS_PATH2 = path14.join(".claude", "settings.json");
3727
3736
  var HOOK_TAILS = [
3728
3737
  { event: "PostToolUse", tail: "learn observe", description: "Caliber: recording tool usage for session learning" },
3729
3738
  { event: "PostToolUseFailure", tail: "learn observe --failure", description: "Caliber: recording tool failure for session learning" },
@@ -3740,17 +3749,17 @@ function getHookConfigs() {
3740
3749
  }));
3741
3750
  }
3742
3751
  function readSettings2() {
3743
- if (!fs18.existsSync(SETTINGS_PATH2)) return {};
3752
+ if (!fs19.existsSync(SETTINGS_PATH2)) return {};
3744
3753
  try {
3745
- return JSON.parse(fs18.readFileSync(SETTINGS_PATH2, "utf-8"));
3754
+ return JSON.parse(fs19.readFileSync(SETTINGS_PATH2, "utf-8"));
3746
3755
  } catch {
3747
3756
  return {};
3748
3757
  }
3749
3758
  }
3750
3759
  function writeSettings2(settings) {
3751
- const dir = path13.dirname(SETTINGS_PATH2);
3752
- if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
3753
- fs18.writeFileSync(SETTINGS_PATH2, JSON.stringify(settings, null, 2));
3760
+ const dir = path14.dirname(SETTINGS_PATH2);
3761
+ if (!fs19.existsSync(dir)) fs19.mkdirSync(dir, { recursive: true });
3762
+ fs19.writeFileSync(SETTINGS_PATH2, JSON.stringify(settings, null, 2));
3754
3763
  }
3755
3764
  function hasLearningHook(matchers, tail) {
3756
3765
  return matchers.some((entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, tail)));
@@ -3784,7 +3793,7 @@ function installLearningHooks() {
3784
3793
  writeSettings2(settings);
3785
3794
  return { installed: true, alreadyInstalled: false };
3786
3795
  }
3787
- var CURSOR_HOOKS_PATH = path13.join(".cursor", "hooks.json");
3796
+ var CURSOR_HOOKS_PATH = path14.join(".cursor", "hooks.json");
3788
3797
  var CURSOR_HOOK_EVENTS = [
3789
3798
  { event: "postToolUse", tail: "learn observe" },
3790
3799
  { event: "postToolUseFailure", tail: "learn observe --failure" },
@@ -3792,17 +3801,17 @@ var CURSOR_HOOK_EVENTS = [
3792
3801
  { event: "sessionEnd", tail: "learn finalize" }
3793
3802
  ];
3794
3803
  function readCursorHooks() {
3795
- if (!fs18.existsSync(CURSOR_HOOKS_PATH)) return { version: 1, hooks: {} };
3804
+ if (!fs19.existsSync(CURSOR_HOOKS_PATH)) return { version: 1, hooks: {} };
3796
3805
  try {
3797
- return JSON.parse(fs18.readFileSync(CURSOR_HOOKS_PATH, "utf-8"));
3806
+ return JSON.parse(fs19.readFileSync(CURSOR_HOOKS_PATH, "utf-8"));
3798
3807
  } catch {
3799
3808
  return { version: 1, hooks: {} };
3800
3809
  }
3801
3810
  }
3802
3811
  function writeCursorHooks(config) {
3803
- const dir = path13.dirname(CURSOR_HOOKS_PATH);
3804
- if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
3805
- fs18.writeFileSync(CURSOR_HOOKS_PATH, JSON.stringify(config, null, 2));
3812
+ const dir = path14.dirname(CURSOR_HOOKS_PATH);
3813
+ if (!fs19.existsSync(dir)) fs19.mkdirSync(dir, { recursive: true });
3814
+ fs19.writeFileSync(CURSOR_HOOKS_PATH, JSON.stringify(config, null, 2));
3806
3815
  }
3807
3816
  function hasCursorHook(entries, tail) {
3808
3817
  return entries.some((e) => isCaliberCommand(e.command, tail));
@@ -3872,10 +3881,10 @@ function removeLearningHooks() {
3872
3881
 
3873
3882
  // src/lib/state.ts
3874
3883
  init_constants();
3875
- import fs19 from "fs";
3876
- import path14 from "path";
3884
+ import fs20 from "fs";
3885
+ import path15 from "path";
3877
3886
  import { execSync as execSync8 } from "child_process";
3878
- var STATE_FILE = path14.join(CALIBER_DIR, ".caliber-state.json");
3887
+ var STATE_FILE = path15.join(CALIBER_DIR, ".caliber-state.json");
3879
3888
  function normalizeTargetAgent(value) {
3880
3889
  if (Array.isArray(value)) return value;
3881
3890
  if (typeof value === "string") {
@@ -3886,8 +3895,8 @@ function normalizeTargetAgent(value) {
3886
3895
  }
3887
3896
  function readState() {
3888
3897
  try {
3889
- if (!fs19.existsSync(STATE_FILE)) return null;
3890
- const raw = JSON.parse(fs19.readFileSync(STATE_FILE, "utf-8"));
3898
+ if (!fs20.existsSync(STATE_FILE)) return null;
3899
+ const raw = JSON.parse(fs20.readFileSync(STATE_FILE, "utf-8"));
3891
3900
  if (raw.targetAgent) raw.targetAgent = normalizeTargetAgent(raw.targetAgent);
3892
3901
  return raw;
3893
3902
  } catch {
@@ -3895,10 +3904,10 @@ function readState() {
3895
3904
  }
3896
3905
  }
3897
3906
  function writeState(state) {
3898
- if (!fs19.existsSync(CALIBER_DIR)) {
3899
- fs19.mkdirSync(CALIBER_DIR, { recursive: true });
3907
+ if (!fs20.existsSync(CALIBER_DIR)) {
3908
+ fs20.mkdirSync(CALIBER_DIR, { recursive: true });
3900
3909
  }
3901
- fs19.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
3910
+ fs20.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
3902
3911
  }
3903
3912
  function getCurrentHeadSha() {
3904
3913
  try {
@@ -5255,22 +5264,22 @@ function checkBonus(dir) {
5255
5264
 
5256
5265
  // src/scoring/dismissed.ts
5257
5266
  init_constants();
5258
- import fs20 from "fs";
5259
- import path15 from "path";
5260
- var DISMISSED_FILE = path15.join(CALIBER_DIR, "dismissed-checks.json");
5267
+ import fs21 from "fs";
5268
+ import path16 from "path";
5269
+ var DISMISSED_FILE = path16.join(CALIBER_DIR, "dismissed-checks.json");
5261
5270
  function readDismissedChecks() {
5262
5271
  try {
5263
- if (!fs20.existsSync(DISMISSED_FILE)) return [];
5264
- return JSON.parse(fs20.readFileSync(DISMISSED_FILE, "utf-8"));
5272
+ if (!fs21.existsSync(DISMISSED_FILE)) return [];
5273
+ return JSON.parse(fs21.readFileSync(DISMISSED_FILE, "utf-8"));
5265
5274
  } catch {
5266
5275
  return [];
5267
5276
  }
5268
5277
  }
5269
5278
  function writeDismissedChecks(checks) {
5270
- if (!fs20.existsSync(CALIBER_DIR)) {
5271
- fs20.mkdirSync(CALIBER_DIR, { recursive: true });
5279
+ if (!fs21.existsSync(CALIBER_DIR)) {
5280
+ fs21.mkdirSync(CALIBER_DIR, { recursive: true });
5272
5281
  }
5273
- fs20.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
5282
+ fs21.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
5274
5283
  }
5275
5284
  function getDismissedIds() {
5276
5285
  return new Set(readDismissedChecks().map((c) => c.id));
@@ -5466,13 +5475,13 @@ import { mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync4,
5466
5475
  import { join as join9, dirname as dirname2 } from "path";
5467
5476
 
5468
5477
  // src/scanner/index.ts
5469
- import fs21 from "fs";
5470
- import path16 from "path";
5478
+ import fs22 from "fs";
5479
+ import path17 from "path";
5471
5480
  import crypto2 from "crypto";
5472
5481
  function scanLocalState(dir) {
5473
5482
  const items = [];
5474
- const claudeMdPath = path16.join(dir, "CLAUDE.md");
5475
- if (fs21.existsSync(claudeMdPath)) {
5483
+ const claudeMdPath = path17.join(dir, "CLAUDE.md");
5484
+ if (fs22.existsSync(claudeMdPath)) {
5476
5485
  items.push({
5477
5486
  type: "rule",
5478
5487
  platform: "claude",
@@ -5481,10 +5490,10 @@ function scanLocalState(dir) {
5481
5490
  path: claudeMdPath
5482
5491
  });
5483
5492
  }
5484
- const skillsDir = path16.join(dir, ".claude", "skills");
5485
- if (fs21.existsSync(skillsDir)) {
5486
- for (const file of fs21.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
5487
- const filePath = path16.join(skillsDir, file);
5493
+ const skillsDir = path17.join(dir, ".claude", "skills");
5494
+ if (fs22.existsSync(skillsDir)) {
5495
+ for (const file of fs22.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
5496
+ const filePath = path17.join(skillsDir, file);
5488
5497
  items.push({
5489
5498
  type: "skill",
5490
5499
  platform: "claude",
@@ -5494,10 +5503,10 @@ function scanLocalState(dir) {
5494
5503
  });
5495
5504
  }
5496
5505
  }
5497
- const mcpJsonPath = path16.join(dir, ".mcp.json");
5498
- if (fs21.existsSync(mcpJsonPath)) {
5506
+ const mcpJsonPath = path17.join(dir, ".mcp.json");
5507
+ if (fs22.existsSync(mcpJsonPath)) {
5499
5508
  try {
5500
- const mcpJson = JSON.parse(fs21.readFileSync(mcpJsonPath, "utf-8"));
5509
+ const mcpJson = JSON.parse(fs22.readFileSync(mcpJsonPath, "utf-8"));
5501
5510
  if (mcpJson.mcpServers) {
5502
5511
  for (const name of Object.keys(mcpJson.mcpServers)) {
5503
5512
  items.push({
@@ -5512,8 +5521,8 @@ function scanLocalState(dir) {
5512
5521
  } catch {
5513
5522
  }
5514
5523
  }
5515
- const agentsMdPath = path16.join(dir, "AGENTS.md");
5516
- if (fs21.existsSync(agentsMdPath)) {
5524
+ const agentsMdPath = path17.join(dir, "AGENTS.md");
5525
+ if (fs22.existsSync(agentsMdPath)) {
5517
5526
  items.push({
5518
5527
  type: "rule",
5519
5528
  platform: "codex",
@@ -5522,12 +5531,12 @@ function scanLocalState(dir) {
5522
5531
  path: agentsMdPath
5523
5532
  });
5524
5533
  }
5525
- const codexSkillsDir = path16.join(dir, ".agents", "skills");
5526
- if (fs21.existsSync(codexSkillsDir)) {
5534
+ const codexSkillsDir = path17.join(dir, ".agents", "skills");
5535
+ if (fs22.existsSync(codexSkillsDir)) {
5527
5536
  try {
5528
- for (const name of fs21.readdirSync(codexSkillsDir)) {
5529
- const skillFile = path16.join(codexSkillsDir, name, "SKILL.md");
5530
- if (fs21.existsSync(skillFile)) {
5537
+ for (const name of fs22.readdirSync(codexSkillsDir)) {
5538
+ const skillFile = path17.join(codexSkillsDir, name, "SKILL.md");
5539
+ if (fs22.existsSync(skillFile)) {
5531
5540
  items.push({
5532
5541
  type: "skill",
5533
5542
  platform: "codex",
@@ -5540,8 +5549,8 @@ function scanLocalState(dir) {
5540
5549
  } catch {
5541
5550
  }
5542
5551
  }
5543
- const cursorrulesPath = path16.join(dir, ".cursorrules");
5544
- if (fs21.existsSync(cursorrulesPath)) {
5552
+ const cursorrulesPath = path17.join(dir, ".cursorrules");
5553
+ if (fs22.existsSync(cursorrulesPath)) {
5545
5554
  items.push({
5546
5555
  type: "rule",
5547
5556
  platform: "cursor",
@@ -5550,10 +5559,10 @@ function scanLocalState(dir) {
5550
5559
  path: cursorrulesPath
5551
5560
  });
5552
5561
  }
5553
- const cursorRulesDir = path16.join(dir, ".cursor", "rules");
5554
- if (fs21.existsSync(cursorRulesDir)) {
5555
- for (const file of fs21.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
5556
- const filePath = path16.join(cursorRulesDir, file);
5562
+ const cursorRulesDir = path17.join(dir, ".cursor", "rules");
5563
+ if (fs22.existsSync(cursorRulesDir)) {
5564
+ for (const file of fs22.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
5565
+ const filePath = path17.join(cursorRulesDir, file);
5557
5566
  items.push({
5558
5567
  type: "rule",
5559
5568
  platform: "cursor",
@@ -5563,12 +5572,12 @@ function scanLocalState(dir) {
5563
5572
  });
5564
5573
  }
5565
5574
  }
5566
- const cursorSkillsDir = path16.join(dir, ".cursor", "skills");
5567
- if (fs21.existsSync(cursorSkillsDir)) {
5575
+ const cursorSkillsDir = path17.join(dir, ".cursor", "skills");
5576
+ if (fs22.existsSync(cursorSkillsDir)) {
5568
5577
  try {
5569
- for (const name of fs21.readdirSync(cursorSkillsDir)) {
5570
- const skillFile = path16.join(cursorSkillsDir, name, "SKILL.md");
5571
- if (fs21.existsSync(skillFile)) {
5578
+ for (const name of fs22.readdirSync(cursorSkillsDir)) {
5579
+ const skillFile = path17.join(cursorSkillsDir, name, "SKILL.md");
5580
+ if (fs22.existsSync(skillFile)) {
5572
5581
  items.push({
5573
5582
  type: "skill",
5574
5583
  platform: "cursor",
@@ -5581,10 +5590,10 @@ function scanLocalState(dir) {
5581
5590
  } catch {
5582
5591
  }
5583
5592
  }
5584
- const cursorMcpPath = path16.join(dir, ".cursor", "mcp.json");
5585
- if (fs21.existsSync(cursorMcpPath)) {
5593
+ const cursorMcpPath = path17.join(dir, ".cursor", "mcp.json");
5594
+ if (fs22.existsSync(cursorMcpPath)) {
5586
5595
  try {
5587
- const mcpJson = JSON.parse(fs21.readFileSync(cursorMcpPath, "utf-8"));
5596
+ const mcpJson = JSON.parse(fs22.readFileSync(cursorMcpPath, "utf-8"));
5588
5597
  if (mcpJson.mcpServers) {
5589
5598
  for (const name of Object.keys(mcpJson.mcpServers)) {
5590
5599
  items.push({
@@ -5602,7 +5611,7 @@ function scanLocalState(dir) {
5602
5611
  return items;
5603
5612
  }
5604
5613
  function hashFile(filePath) {
5605
- const text = fs21.readFileSync(filePath, "utf-8");
5614
+ const text = fs22.readFileSync(filePath, "utf-8");
5606
5615
  return crypto2.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
5607
5616
  }
5608
5617
  function hashJson(obj) {
@@ -5617,27 +5626,27 @@ import { PostHog } from "posthog-node";
5617
5626
  import chalk7 from "chalk";
5618
5627
 
5619
5628
  // src/telemetry/config.ts
5620
- import fs22 from "fs";
5621
- import path17 from "path";
5622
- import os3 from "os";
5629
+ import fs23 from "fs";
5630
+ import path18 from "path";
5631
+ import os4 from "os";
5623
5632
  import crypto3 from "crypto";
5624
5633
  import { execSync as execSync12 } from "child_process";
5625
- var CONFIG_DIR2 = path17.join(os3.homedir(), ".caliber");
5626
- var CONFIG_FILE2 = path17.join(CONFIG_DIR2, "config.json");
5634
+ var CONFIG_DIR2 = path18.join(os4.homedir(), ".caliber");
5635
+ var CONFIG_FILE2 = path18.join(CONFIG_DIR2, "config.json");
5627
5636
  var runtimeDisabled = false;
5628
5637
  function readConfig() {
5629
5638
  try {
5630
- if (!fs22.existsSync(CONFIG_FILE2)) return {};
5631
- return JSON.parse(fs22.readFileSync(CONFIG_FILE2, "utf-8"));
5639
+ if (!fs23.existsSync(CONFIG_FILE2)) return {};
5640
+ return JSON.parse(fs23.readFileSync(CONFIG_FILE2, "utf-8"));
5632
5641
  } catch {
5633
5642
  return {};
5634
5643
  }
5635
5644
  }
5636
5645
  function writeConfig(config) {
5637
- if (!fs22.existsSync(CONFIG_DIR2)) {
5638
- fs22.mkdirSync(CONFIG_DIR2, { recursive: true });
5646
+ if (!fs23.existsSync(CONFIG_DIR2)) {
5647
+ fs23.mkdirSync(CONFIG_DIR2, { recursive: true });
5639
5648
  }
5640
- fs22.writeFileSync(CONFIG_FILE2, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
5649
+ fs23.writeFileSync(CONFIG_FILE2, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
5641
5650
  }
5642
5651
  function getMachineId() {
5643
5652
  const config = readConfig();
@@ -6361,8 +6370,8 @@ function printSkills(recs) {
6361
6370
  }
6362
6371
 
6363
6372
  // src/lib/debug-report.ts
6364
- import fs23 from "fs";
6365
- import path18 from "path";
6373
+ import fs24 from "fs";
6374
+ import path19 from "path";
6366
6375
  var DebugReport = class {
6367
6376
  sections = [];
6368
6377
  startTime;
@@ -6431,11 +6440,11 @@ var DebugReport = class {
6431
6440
  lines.push(`| **Total** | **${formatMs(totalMs)}** |`);
6432
6441
  lines.push("");
6433
6442
  }
6434
- const dir = path18.dirname(outputPath);
6435
- if (!fs23.existsSync(dir)) {
6436
- fs23.mkdirSync(dir, { recursive: true });
6443
+ const dir = path19.dirname(outputPath);
6444
+ if (!fs24.existsSync(dir)) {
6445
+ fs24.mkdirSync(dir, { recursive: true });
6437
6446
  }
6438
- fs23.writeFileSync(outputPath, lines.join("\n"));
6447
+ fs24.writeFileSync(outputPath, lines.join("\n"));
6439
6448
  }
6440
6449
  };
6441
6450
  function formatMs(ms) {
@@ -6921,7 +6930,7 @@ async function initCommand(options) {
6921
6930
  }
6922
6931
  const writeSpinner = ora2("Writing config files...").start();
6923
6932
  try {
6924
- if (targetAgent.includes("codex") && !fs24.existsSync("AGENTS.md") && !generatedSetup.codex) {
6933
+ if (targetAgent.includes("codex") && !fs25.existsSync("AGENTS.md") && !generatedSetup.codex) {
6925
6934
  const claude = generatedSetup.claude;
6926
6935
  const cursor = generatedSetup.cursor;
6927
6936
  const agentRefs = [];
@@ -7062,9 +7071,9 @@ ${agentRefs.join(" ")}
7062
7071
  }
7063
7072
  if (report) {
7064
7073
  report.markStep("Finished");
7065
- const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
7074
+ const reportPath = path20.join(process.cwd(), ".caliber", "debug-report.md");
7066
7075
  report.write(reportPath);
7067
- console.log(chalk10.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
7076
+ console.log(chalk10.dim(` Debug report written to ${path20.relative(process.cwd(), reportPath)}
7068
7077
  `));
7069
7078
  }
7070
7079
  }
@@ -7111,7 +7120,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
7111
7120
  }
7112
7121
  function summarizeSetup(action, setup) {
7113
7122
  const descriptions = setup.fileDescriptions;
7114
- const files = descriptions ? Object.entries(descriptions).map(([path27, desc]) => ` ${path27}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
7123
+ const files = descriptions ? Object.entries(descriptions).map(([path28, desc]) => ` ${path28}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
7115
7124
  return `${action}. Files:
7116
7125
  ${files}`;
7117
7126
  }
@@ -7227,7 +7236,7 @@ function printSetupSummary(setup) {
7227
7236
  };
7228
7237
  if (claude) {
7229
7238
  if (claude.claudeMd) {
7230
- const icon = fs24.existsSync("CLAUDE.md") ? chalk10.yellow("~") : chalk10.green("+");
7239
+ const icon = fs25.existsSync("CLAUDE.md") ? chalk10.yellow("~") : chalk10.green("+");
7231
7240
  const desc = getDescription("CLAUDE.md");
7232
7241
  console.log(` ${icon} ${chalk10.bold("CLAUDE.md")}`);
7233
7242
  if (desc) console.log(chalk10.dim(` ${desc}`));
@@ -7237,7 +7246,7 @@ function printSetupSummary(setup) {
7237
7246
  if (Array.isArray(skills) && skills.length > 0) {
7238
7247
  for (const skill of skills) {
7239
7248
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
7240
- const icon = fs24.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7249
+ const icon = fs25.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7241
7250
  const desc = getDescription(skillPath);
7242
7251
  console.log(` ${icon} ${chalk10.bold(skillPath)}`);
7243
7252
  console.log(chalk10.dim(` ${desc || skill.description || skill.name}`));
@@ -7248,7 +7257,7 @@ function printSetupSummary(setup) {
7248
7257
  const codex = setup.codex;
7249
7258
  if (codex) {
7250
7259
  if (codex.agentsMd) {
7251
- const icon = fs24.existsSync("AGENTS.md") ? chalk10.yellow("~") : chalk10.green("+");
7260
+ const icon = fs25.existsSync("AGENTS.md") ? chalk10.yellow("~") : chalk10.green("+");
7252
7261
  const desc = getDescription("AGENTS.md");
7253
7262
  console.log(` ${icon} ${chalk10.bold("AGENTS.md")}`);
7254
7263
  if (desc) console.log(chalk10.dim(` ${desc}`));
@@ -7258,7 +7267,7 @@ function printSetupSummary(setup) {
7258
7267
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
7259
7268
  for (const skill of codexSkills) {
7260
7269
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
7261
- const icon = fs24.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7270
+ const icon = fs25.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7262
7271
  const desc = getDescription(skillPath);
7263
7272
  console.log(` ${icon} ${chalk10.bold(skillPath)}`);
7264
7273
  console.log(chalk10.dim(` ${desc || skill.description || skill.name}`));
@@ -7268,7 +7277,7 @@ function printSetupSummary(setup) {
7268
7277
  }
7269
7278
  if (cursor) {
7270
7279
  if (cursor.cursorrules) {
7271
- const icon = fs24.existsSync(".cursorrules") ? chalk10.yellow("~") : chalk10.green("+");
7280
+ const icon = fs25.existsSync(".cursorrules") ? chalk10.yellow("~") : chalk10.green("+");
7272
7281
  const desc = getDescription(".cursorrules");
7273
7282
  console.log(` ${icon} ${chalk10.bold(".cursorrules")}`);
7274
7283
  if (desc) console.log(chalk10.dim(` ${desc}`));
@@ -7278,7 +7287,7 @@ function printSetupSummary(setup) {
7278
7287
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
7279
7288
  for (const skill of cursorSkills) {
7280
7289
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
7281
- const icon = fs24.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7290
+ const icon = fs25.existsSync(skillPath) ? chalk10.yellow("~") : chalk10.green("+");
7282
7291
  const desc = getDescription(skillPath);
7283
7292
  console.log(` ${icon} ${chalk10.bold(skillPath)}`);
7284
7293
  console.log(chalk10.dim(` ${desc || skill.description || skill.name}`));
@@ -7289,7 +7298,7 @@ function printSetupSummary(setup) {
7289
7298
  if (Array.isArray(rules) && rules.length > 0) {
7290
7299
  for (const rule of rules) {
7291
7300
  const rulePath = `.cursor/rules/${rule.filename}`;
7292
- const icon = fs24.existsSync(rulePath) ? chalk10.yellow("~") : chalk10.green("+");
7301
+ const icon = fs25.existsSync(rulePath) ? chalk10.yellow("~") : chalk10.green("+");
7293
7302
  const desc = getDescription(rulePath);
7294
7303
  console.log(` ${icon} ${chalk10.bold(rulePath)}`);
7295
7304
  if (desc) {
@@ -7353,8 +7362,8 @@ function ensurePermissions(fingerprint) {
7353
7362
  const settingsPath = ".claude/settings.json";
7354
7363
  let settings = {};
7355
7364
  try {
7356
- if (fs24.existsSync(settingsPath)) {
7357
- settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
7365
+ if (fs25.existsSync(settingsPath)) {
7366
+ settings = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
7358
7367
  }
7359
7368
  } catch {
7360
7369
  }
@@ -7363,8 +7372,8 @@ function ensurePermissions(fingerprint) {
7363
7372
  if (Array.isArray(allow) && allow.length > 0) return;
7364
7373
  permissions.allow = derivePermissions(fingerprint);
7365
7374
  settings.permissions = permissions;
7366
- if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
7367
- fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
7375
+ if (!fs25.existsSync(".claude")) fs25.mkdirSync(".claude", { recursive: true });
7376
+ fs25.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
7368
7377
  }
7369
7378
  function displayTokenUsage() {
7370
7379
  const summary = getUsageSummary();
@@ -7388,7 +7397,7 @@ function displayTokenUsage() {
7388
7397
  }
7389
7398
  function writeErrorLog(config, rawOutput, error, stopReason) {
7390
7399
  try {
7391
- const logPath = path19.join(process.cwd(), ".caliber", "error-log.md");
7400
+ const logPath = path20.join(process.cwd(), ".caliber", "error-log.md");
7392
7401
  const lines = [
7393
7402
  `# Generation Error \u2014 ${(/* @__PURE__ */ new Date()).toISOString()}`,
7394
7403
  "",
@@ -7401,8 +7410,8 @@ function writeErrorLog(config, rawOutput, error, stopReason) {
7401
7410
  lines.push("## Error", "```", error, "```", "");
7402
7411
  }
7403
7412
  lines.push("## Raw LLM Output", "```", rawOutput || "(empty)", "```");
7404
- fs24.mkdirSync(path19.join(process.cwd(), ".caliber"), { recursive: true });
7405
- fs24.writeFileSync(logPath, lines.join("\n"));
7413
+ fs25.mkdirSync(path20.join(process.cwd(), ".caliber"), { recursive: true });
7414
+ fs25.writeFileSync(logPath, lines.join("\n"));
7406
7415
  console.log(chalk10.dim(`
7407
7416
  Error log written to .caliber/error-log.md`));
7408
7417
  } catch {
@@ -7443,7 +7452,7 @@ function undoCommand() {
7443
7452
 
7444
7453
  // src/commands/status.ts
7445
7454
  import chalk12 from "chalk";
7446
- import fs25 from "fs";
7455
+ import fs26 from "fs";
7447
7456
  init_config();
7448
7457
  async function statusCommand(options) {
7449
7458
  const config = loadConfig();
@@ -7470,7 +7479,7 @@ async function statusCommand(options) {
7470
7479
  }
7471
7480
  console.log(` Files managed: ${chalk12.cyan(manifest.entries.length.toString())}`);
7472
7481
  for (const entry of manifest.entries) {
7473
- const exists = fs25.existsSync(entry.path);
7482
+ const exists = fs26.existsSync(entry.path);
7474
7483
  const icon = exists ? chalk12.green("\u2713") : chalk12.red("\u2717");
7475
7484
  console.log(` ${icon} ${entry.path} (${entry.action})`);
7476
7485
  }
@@ -7651,8 +7660,8 @@ async function scoreCommand(options) {
7651
7660
  }
7652
7661
 
7653
7662
  // src/commands/refresh.ts
7654
- import fs29 from "fs";
7655
- import path23 from "path";
7663
+ import fs30 from "fs";
7664
+ import path24 from "path";
7656
7665
  import chalk15 from "chalk";
7657
7666
  import ora5 from "ora";
7658
7667
 
@@ -7730,37 +7739,37 @@ function collectDiff(lastSha) {
7730
7739
  }
7731
7740
 
7732
7741
  // src/writers/refresh.ts
7733
- import fs26 from "fs";
7734
- import path20 from "path";
7742
+ import fs27 from "fs";
7743
+ import path21 from "path";
7735
7744
  function writeRefreshDocs(docs) {
7736
7745
  const written = [];
7737
7746
  if (docs.claudeMd) {
7738
- fs26.writeFileSync("CLAUDE.md", docs.claudeMd);
7747
+ fs27.writeFileSync("CLAUDE.md", docs.claudeMd);
7739
7748
  written.push("CLAUDE.md");
7740
7749
  }
7741
7750
  if (docs.readmeMd) {
7742
- fs26.writeFileSync("README.md", docs.readmeMd);
7751
+ fs27.writeFileSync("README.md", docs.readmeMd);
7743
7752
  written.push("README.md");
7744
7753
  }
7745
7754
  if (docs.cursorrules) {
7746
- fs26.writeFileSync(".cursorrules", docs.cursorrules);
7755
+ fs27.writeFileSync(".cursorrules", docs.cursorrules);
7747
7756
  written.push(".cursorrules");
7748
7757
  }
7749
7758
  if (docs.cursorRules) {
7750
- const rulesDir = path20.join(".cursor", "rules");
7751
- if (!fs26.existsSync(rulesDir)) fs26.mkdirSync(rulesDir, { recursive: true });
7759
+ const rulesDir = path21.join(".cursor", "rules");
7760
+ if (!fs27.existsSync(rulesDir)) fs27.mkdirSync(rulesDir, { recursive: true });
7752
7761
  for (const rule of docs.cursorRules) {
7753
- const filePath = path20.join(rulesDir, rule.filename);
7754
- fs26.writeFileSync(filePath, rule.content);
7762
+ const filePath = path21.join(rulesDir, rule.filename);
7763
+ fs27.writeFileSync(filePath, rule.content);
7755
7764
  written.push(filePath);
7756
7765
  }
7757
7766
  }
7758
7767
  if (docs.claudeSkills) {
7759
- const skillsDir = path20.join(".claude", "skills");
7760
- if (!fs26.existsSync(skillsDir)) fs26.mkdirSync(skillsDir, { recursive: true });
7768
+ const skillsDir = path21.join(".claude", "skills");
7769
+ if (!fs27.existsSync(skillsDir)) fs27.mkdirSync(skillsDir, { recursive: true });
7761
7770
  for (const skill of docs.claudeSkills) {
7762
- const filePath = path20.join(skillsDir, skill.filename);
7763
- fs26.writeFileSync(filePath, skill.content);
7771
+ const filePath = path21.join(skillsDir, skill.filename);
7772
+ fs27.writeFileSync(filePath, skill.content);
7764
7773
  written.push(filePath);
7765
7774
  }
7766
7775
  }
@@ -7837,8 +7846,8 @@ Changed files: ${diff.changedFiles.join(", ")}`);
7837
7846
  }
7838
7847
 
7839
7848
  // src/learner/writer.ts
7840
- import fs27 from "fs";
7841
- import path21 from "path";
7849
+ import fs28 from "fs";
7850
+ import path22 from "path";
7842
7851
  var LEARNINGS_FILE = "CALIBER_LEARNINGS.md";
7843
7852
  var LEARNINGS_HEADER = `# Caliber Learnings
7844
7853
 
@@ -7922,16 +7931,16 @@ function deduplicateLearnedItems(existing, incoming) {
7922
7931
  function writeLearnedSection(content) {
7923
7932
  const existingSection = readLearnedSection();
7924
7933
  const { merged, newCount, newItems } = deduplicateLearnedItems(existingSection, content);
7925
- fs27.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + merged + "\n");
7934
+ fs28.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + merged + "\n");
7926
7935
  return { newCount, newItems };
7927
7936
  }
7928
7937
  function writeLearnedSkill(skill) {
7929
- const skillDir = path21.join(".claude", "skills", skill.name);
7930
- if (!fs27.existsSync(skillDir)) fs27.mkdirSync(skillDir, { recursive: true });
7931
- const skillPath = path21.join(skillDir, "SKILL.md");
7932
- if (!skill.isNew && fs27.existsSync(skillPath)) {
7933
- const existing = fs27.readFileSync(skillPath, "utf-8");
7934
- fs27.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
7938
+ const skillDir = path22.join(".claude", "skills", skill.name);
7939
+ if (!fs28.existsSync(skillDir)) fs28.mkdirSync(skillDir, { recursive: true });
7940
+ const skillPath = path22.join(skillDir, "SKILL.md");
7941
+ if (!skill.isNew && fs28.existsSync(skillPath)) {
7942
+ const existing = fs28.readFileSync(skillPath, "utf-8");
7943
+ fs28.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
7935
7944
  } else {
7936
7945
  const frontmatter = [
7937
7946
  "---",
@@ -7940,37 +7949,37 @@ function writeLearnedSkill(skill) {
7940
7949
  "---",
7941
7950
  ""
7942
7951
  ].join("\n");
7943
- fs27.writeFileSync(skillPath, frontmatter + skill.content);
7952
+ fs28.writeFileSync(skillPath, frontmatter + skill.content);
7944
7953
  }
7945
7954
  return skillPath;
7946
7955
  }
7947
7956
  function readLearnedSection() {
7948
- if (fs27.existsSync(LEARNINGS_FILE)) {
7949
- const content2 = fs27.readFileSync(LEARNINGS_FILE, "utf-8");
7957
+ if (fs28.existsSync(LEARNINGS_FILE)) {
7958
+ const content2 = fs28.readFileSync(LEARNINGS_FILE, "utf-8");
7950
7959
  const bullets = content2.split("\n").filter((l) => l.startsWith("- ")).join("\n");
7951
7960
  return bullets || null;
7952
7961
  }
7953
7962
  const claudeMdPath = "CLAUDE.md";
7954
- if (!fs27.existsSync(claudeMdPath)) return null;
7955
- const content = fs27.readFileSync(claudeMdPath, "utf-8");
7963
+ if (!fs28.existsSync(claudeMdPath)) return null;
7964
+ const content = fs28.readFileSync(claudeMdPath, "utf-8");
7956
7965
  const startIdx = content.indexOf(LEARNED_START);
7957
7966
  const endIdx = content.indexOf(LEARNED_END);
7958
7967
  if (startIdx === -1 || endIdx === -1) return null;
7959
7968
  return content.slice(startIdx + LEARNED_START.length, endIdx).trim() || null;
7960
7969
  }
7961
7970
  function migrateInlineLearnings() {
7962
- if (fs27.existsSync(LEARNINGS_FILE)) return false;
7971
+ if (fs28.existsSync(LEARNINGS_FILE)) return false;
7963
7972
  const claudeMdPath = "CLAUDE.md";
7964
- if (!fs27.existsSync(claudeMdPath)) return false;
7965
- const content = fs27.readFileSync(claudeMdPath, "utf-8");
7973
+ if (!fs28.existsSync(claudeMdPath)) return false;
7974
+ const content = fs28.readFileSync(claudeMdPath, "utf-8");
7966
7975
  const startIdx = content.indexOf(LEARNED_START);
7967
7976
  const endIdx = content.indexOf(LEARNED_END);
7968
7977
  if (startIdx === -1 || endIdx === -1) return false;
7969
7978
  const section = content.slice(startIdx + LEARNED_START.length, endIdx).trim();
7970
7979
  if (!section) return false;
7971
- fs27.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + section + "\n");
7980
+ fs28.writeFileSync(LEARNINGS_FILE, LEARNINGS_HEADER + section + "\n");
7972
7981
  const cleaned = content.slice(0, startIdx) + content.slice(endIdx + LEARNED_END.length);
7973
- fs27.writeFileSync(claudeMdPath, cleaned.replace(/\n{3,}/g, "\n\n").trim() + "\n");
7982
+ fs28.writeFileSync(claudeMdPath, cleaned.replace(/\n{3,}/g, "\n\n").trim() + "\n");
7974
7983
  return true;
7975
7984
  }
7976
7985
 
@@ -7982,11 +7991,11 @@ function log2(quiet, ...args) {
7982
7991
  function discoverGitRepos(parentDir) {
7983
7992
  const repos = [];
7984
7993
  try {
7985
- const entries = fs29.readdirSync(parentDir, { withFileTypes: true });
7994
+ const entries = fs30.readdirSync(parentDir, { withFileTypes: true });
7986
7995
  for (const entry of entries) {
7987
7996
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
7988
- const childPath = path23.join(parentDir, entry.name);
7989
- if (fs29.existsSync(path23.join(childPath, ".git"))) {
7997
+ const childPath = path24.join(parentDir, entry.name);
7998
+ if (fs30.existsSync(path24.join(childPath, ".git"))) {
7990
7999
  repos.push(childPath);
7991
8000
  }
7992
8001
  }
@@ -8089,7 +8098,7 @@ async function refreshCommand(options) {
8089
8098
  `));
8090
8099
  const originalDir = process.cwd();
8091
8100
  for (const repo of repos) {
8092
- const repoName = path23.basename(repo);
8101
+ const repoName = path24.basename(repo);
8093
8102
  try {
8094
8103
  process.chdir(repo);
8095
8104
  await refreshSingleRepo(repo, { ...options, label: repoName });
@@ -8313,7 +8322,7 @@ async function configCommand() {
8313
8322
  }
8314
8323
 
8315
8324
  // src/commands/learn.ts
8316
- import fs31 from "fs";
8325
+ import fs32 from "fs";
8317
8326
  import chalk18 from "chalk";
8318
8327
 
8319
8328
  // src/learner/stdin.ts
@@ -8345,8 +8354,8 @@ function readStdin() {
8345
8354
 
8346
8355
  // src/learner/storage.ts
8347
8356
  init_constants();
8348
- import fs30 from "fs";
8349
- import path24 from "path";
8357
+ import fs31 from "fs";
8358
+ import path25 from "path";
8350
8359
  var MAX_RESPONSE_LENGTH = 2e3;
8351
8360
  var DEFAULT_STATE = {
8352
8361
  sessionId: null,
@@ -8354,15 +8363,15 @@ var DEFAULT_STATE = {
8354
8363
  lastAnalysisTimestamp: null
8355
8364
  };
8356
8365
  function ensureLearningDir() {
8357
- if (!fs30.existsSync(LEARNING_DIR)) {
8358
- fs30.mkdirSync(LEARNING_DIR, { recursive: true });
8366
+ if (!fs31.existsSync(LEARNING_DIR)) {
8367
+ fs31.mkdirSync(LEARNING_DIR, { recursive: true });
8359
8368
  }
8360
8369
  }
8361
8370
  function sessionFilePath() {
8362
- return path24.join(LEARNING_DIR, LEARNING_SESSION_FILE);
8371
+ return path25.join(LEARNING_DIR, LEARNING_SESSION_FILE);
8363
8372
  }
8364
8373
  function stateFilePath() {
8365
- return path24.join(LEARNING_DIR, LEARNING_STATE_FILE);
8374
+ return path25.join(LEARNING_DIR, LEARNING_STATE_FILE);
8366
8375
  }
8367
8376
  function truncateResponse(response) {
8368
8377
  const str = JSON.stringify(response);
@@ -8373,29 +8382,29 @@ function appendEvent(event) {
8373
8382
  ensureLearningDir();
8374
8383
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
8375
8384
  const filePath = sessionFilePath();
8376
- fs30.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
8385
+ fs31.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
8377
8386
  const count = getEventCount();
8378
8387
  if (count > LEARNING_MAX_EVENTS) {
8379
- const lines = fs30.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8388
+ const lines = fs31.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8380
8389
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
8381
- fs30.writeFileSync(filePath, kept.join("\n") + "\n");
8390
+ fs31.writeFileSync(filePath, kept.join("\n") + "\n");
8382
8391
  }
8383
8392
  }
8384
8393
  function appendPromptEvent(event) {
8385
8394
  ensureLearningDir();
8386
8395
  const filePath = sessionFilePath();
8387
- fs30.appendFileSync(filePath, JSON.stringify(event) + "\n");
8396
+ fs31.appendFileSync(filePath, JSON.stringify(event) + "\n");
8388
8397
  const count = getEventCount();
8389
8398
  if (count > LEARNING_MAX_EVENTS) {
8390
- const lines = fs30.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8399
+ const lines = fs31.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8391
8400
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
8392
- fs30.writeFileSync(filePath, kept.join("\n") + "\n");
8401
+ fs31.writeFileSync(filePath, kept.join("\n") + "\n");
8393
8402
  }
8394
8403
  }
8395
8404
  function readAllEvents() {
8396
8405
  const filePath = sessionFilePath();
8397
- if (!fs30.existsSync(filePath)) return [];
8398
- const lines = fs30.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8406
+ if (!fs31.existsSync(filePath)) return [];
8407
+ const lines = fs31.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
8399
8408
  const events = [];
8400
8409
  for (const line of lines) {
8401
8410
  try {
@@ -8407,26 +8416,26 @@ function readAllEvents() {
8407
8416
  }
8408
8417
  function getEventCount() {
8409
8418
  const filePath = sessionFilePath();
8410
- if (!fs30.existsSync(filePath)) return 0;
8411
- const content = fs30.readFileSync(filePath, "utf-8");
8419
+ if (!fs31.existsSync(filePath)) return 0;
8420
+ const content = fs31.readFileSync(filePath, "utf-8");
8412
8421
  return content.split("\n").filter(Boolean).length;
8413
8422
  }
8414
8423
  function clearSession() {
8415
8424
  const filePath = sessionFilePath();
8416
- if (fs30.existsSync(filePath)) fs30.unlinkSync(filePath);
8425
+ if (fs31.existsSync(filePath)) fs31.unlinkSync(filePath);
8417
8426
  }
8418
8427
  function readState2() {
8419
8428
  const filePath = stateFilePath();
8420
- if (!fs30.existsSync(filePath)) return { ...DEFAULT_STATE };
8429
+ if (!fs31.existsSync(filePath)) return { ...DEFAULT_STATE };
8421
8430
  try {
8422
- return JSON.parse(fs30.readFileSync(filePath, "utf-8"));
8431
+ return JSON.parse(fs31.readFileSync(filePath, "utf-8"));
8423
8432
  } catch {
8424
8433
  return { ...DEFAULT_STATE };
8425
8434
  }
8426
8435
  }
8427
8436
  function writeState2(state) {
8428
8437
  ensureLearningDir();
8429
- fs30.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
8438
+ fs31.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
8430
8439
  }
8431
8440
  function resetState() {
8432
8441
  writeState2({ ...DEFAULT_STATE });
@@ -8434,14 +8443,14 @@ function resetState() {
8434
8443
  var LOCK_FILE2 = "finalize.lock";
8435
8444
  var LOCK_STALE_MS = 5 * 60 * 1e3;
8436
8445
  function lockFilePath() {
8437
- return path24.join(LEARNING_DIR, LOCK_FILE2);
8446
+ return path25.join(LEARNING_DIR, LOCK_FILE2);
8438
8447
  }
8439
8448
  function acquireFinalizeLock() {
8440
8449
  ensureLearningDir();
8441
8450
  const lockPath = lockFilePath();
8442
- if (fs30.existsSync(lockPath)) {
8451
+ if (fs31.existsSync(lockPath)) {
8443
8452
  try {
8444
- const stat = fs30.statSync(lockPath);
8453
+ const stat = fs31.statSync(lockPath);
8445
8454
  if (Date.now() - stat.mtimeMs < LOCK_STALE_MS) {
8446
8455
  return false;
8447
8456
  }
@@ -8449,7 +8458,7 @@ function acquireFinalizeLock() {
8449
8458
  }
8450
8459
  }
8451
8460
  try {
8452
- fs30.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
8461
+ fs31.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
8453
8462
  return true;
8454
8463
  } catch {
8455
8464
  return false;
@@ -8458,7 +8467,7 @@ function acquireFinalizeLock() {
8458
8467
  function releaseFinalizeLock() {
8459
8468
  const lockPath = lockFilePath();
8460
8469
  try {
8461
- if (fs30.existsSync(lockPath)) fs30.unlinkSync(lockPath);
8470
+ if (fs31.existsSync(lockPath)) fs31.unlinkSync(lockPath);
8462
8471
  } catch {
8463
8472
  }
8464
8473
  }
@@ -8690,7 +8699,7 @@ async function learnFinalizeCommand(options) {
8690
8699
  }
8691
8700
  async function learnInstallCommand() {
8692
8701
  let anyInstalled = false;
8693
- if (fs31.existsSync(".claude")) {
8702
+ if (fs32.existsSync(".claude")) {
8694
8703
  const r = installLearningHooks();
8695
8704
  if (r.installed) {
8696
8705
  console.log(chalk18.green("\u2713") + " Claude Code learning hooks installed");
@@ -8699,7 +8708,7 @@ async function learnInstallCommand() {
8699
8708
  console.log(chalk18.dim(" Claude Code hooks already installed"));
8700
8709
  }
8701
8710
  }
8702
- if (fs31.existsSync(".cursor")) {
8711
+ if (fs32.existsSync(".cursor")) {
8703
8712
  const r = installCursorLearningHooks();
8704
8713
  if (r.installed) {
8705
8714
  console.log(chalk18.green("\u2713") + " Cursor learning hooks installed");
@@ -8708,7 +8717,7 @@ async function learnInstallCommand() {
8708
8717
  console.log(chalk18.dim(" Cursor hooks already installed"));
8709
8718
  }
8710
8719
  }
8711
- if (!fs31.existsSync(".claude") && !fs31.existsSync(".cursor")) {
8720
+ if (!fs32.existsSync(".claude") && !fs32.existsSync(".cursor")) {
8712
8721
  console.log(chalk18.yellow("No .claude/ or .cursor/ directory found."));
8713
8722
  console.log(chalk18.dim(" Run `caliber init` first, or create the directory manually."));
8714
8723
  return;
@@ -8771,9 +8780,9 @@ Learned items in CALIBER_LEARNINGS.md: ${chalk18.cyan(String(lineCount))}`);
8771
8780
  }
8772
8781
 
8773
8782
  // src/cli.ts
8774
- var __dirname = path25.dirname(fileURLToPath(import.meta.url));
8783
+ var __dirname = path26.dirname(fileURLToPath(import.meta.url));
8775
8784
  var pkg = JSON.parse(
8776
- fs32.readFileSync(path25.resolve(__dirname, "..", "package.json"), "utf-8")
8785
+ fs33.readFileSync(path26.resolve(__dirname, "..", "package.json"), "utf-8")
8777
8786
  );
8778
8787
  var program = new Command();
8779
8788
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -8847,22 +8856,42 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
8847
8856
  learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
8848
8857
 
8849
8858
  // src/utils/version-check.ts
8850
- import fs33 from "fs";
8851
- import path26 from "path";
8859
+ import fs34 from "fs";
8860
+ import path27 from "path";
8852
8861
  import { fileURLToPath as fileURLToPath2 } from "url";
8853
8862
  import { execSync as execSync14 } from "child_process";
8854
8863
  import chalk19 from "chalk";
8855
8864
  import ora6 from "ora";
8856
8865
  import confirm2 from "@inquirer/confirm";
8857
- var __dirname_vc = path26.dirname(fileURLToPath2(import.meta.url));
8866
+ var __dirname_vc = path27.dirname(fileURLToPath2(import.meta.url));
8858
8867
  var pkg2 = JSON.parse(
8859
- fs33.readFileSync(path26.resolve(__dirname_vc, "..", "package.json"), "utf-8")
8868
+ fs34.readFileSync(path27.resolve(__dirname_vc, "..", "package.json"), "utf-8")
8860
8869
  );
8870
+ function getChannel(version) {
8871
+ const match = version.match(/-(dev|next)\./);
8872
+ return match ? match[1] : "latest";
8873
+ }
8874
+ function isNewer(registry, current) {
8875
+ const parse = (v) => {
8876
+ const [core, pre] = v.split("-");
8877
+ const parts = core.split(".").map(Number);
8878
+ return { major: parts[0], minor: parts[1], patch: parts[2], pre };
8879
+ };
8880
+ const r = parse(registry);
8881
+ const c = parse(current);
8882
+ if (r.major !== c.major) return r.major > c.major;
8883
+ if (r.minor !== c.minor) return r.minor > c.minor;
8884
+ if (r.patch !== c.patch) return r.patch > c.patch;
8885
+ if (!r.pre && c.pre) return true;
8886
+ if (r.pre && !c.pre) return false;
8887
+ if (r.pre && c.pre) return r.pre > c.pre;
8888
+ return false;
8889
+ }
8861
8890
  function getInstalledVersion() {
8862
8891
  try {
8863
8892
  const globalRoot = execSync14("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
8864
- const pkgPath = path26.join(globalRoot, "@rely-ai", "caliber", "package.json");
8865
- return JSON.parse(fs33.readFileSync(pkgPath, "utf-8")).version;
8893
+ const pkgPath = path27.join(globalRoot, "@rely-ai", "caliber", "package.json");
8894
+ return JSON.parse(fs34.readFileSync(pkgPath, "utf-8")).version;
8866
8895
  } catch {
8867
8896
  return null;
8868
8897
  }
@@ -8870,9 +8899,11 @@ function getInstalledVersion() {
8870
8899
  async function checkForUpdates() {
8871
8900
  if (process.env.CALIBER_SKIP_UPDATE_CHECK) return;
8872
8901
  try {
8902
+ const current = pkg2.version;
8903
+ const channel = getChannel(current);
8873
8904
  const controller = new AbortController();
8874
8905
  const timeout = setTimeout(() => controller.abort(), 2e3);
8875
- const res = await fetch("https://registry.npmjs.org/@rely-ai/caliber/latest", {
8906
+ const res = await fetch(`https://registry.npmjs.org/@rely-ai/caliber/${channel}`, {
8876
8907
  signal: controller.signal
8877
8908
  });
8878
8909
  clearTimeout(timeout);
@@ -8880,15 +8911,15 @@ async function checkForUpdates() {
8880
8911
  const data = await res.json();
8881
8912
  const latest = data.version;
8882
8913
  if (!latest) return;
8883
- const current = pkg2.version;
8884
- if (current === latest) return;
8914
+ if (!isNewer(latest, current)) return;
8885
8915
  const isInteractive = process.stdin.isTTY === true;
8886
8916
  if (!isInteractive) {
8917
+ const installTag = channel === "latest" ? "" : `@${channel}`;
8887
8918
  console.log(
8888
8919
  chalk19.yellow(
8889
8920
  `
8890
8921
  Update available: ${current} -> ${latest}
8891
- Run ${chalk19.bold("npm install -g @rely-ai/caliber")} to upgrade.
8922
+ Run ${chalk19.bold(`npm install -g @rely-ai/caliber${installTag}`)} to upgrade.
8892
8923
  `
8893
8924
  )
8894
8925
  );
@@ -8903,9 +8934,10 @@ Update available: ${current} -> ${latest}`)
8903
8934
  console.log();
8904
8935
  return;
8905
8936
  }
8937
+ const tag = channel === "latest" ? latest : channel;
8906
8938
  const spinner = ora6("Updating caliber...").start();
8907
8939
  try {
8908
- execSync14(`npm install -g @rely-ai/caliber@${latest}`, {
8940
+ execSync14(`npm install -g @rely-ai/caliber@${tag}`, {
8909
8941
  stdio: "pipe",
8910
8942
  timeout: 12e4,
8911
8943
  env: { ...process.env, npm_config_fund: "false", npm_config_audit: "false" }
@@ -8913,7 +8945,7 @@ Update available: ${current} -> ${latest}`)
8913
8945
  const installed = getInstalledVersion();
8914
8946
  if (installed !== latest) {
8915
8947
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
8916
- console.log(chalk19.yellow(`Run ${chalk19.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually.
8948
+ console.log(chalk19.yellow(`Run ${chalk19.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually.
8917
8949
  `));
8918
8950
  return;
8919
8951
  }
@@ -8936,7 +8968,7 @@ Restarting: caliber ${args.join(" ")}
8936
8968
  }
8937
8969
  console.log(
8938
8970
  chalk19.yellow(
8939
- `Run ${chalk19.bold(`npm install -g @rely-ai/caliber@${latest}`)} manually to upgrade.
8971
+ `Run ${chalk19.bold(`npm install -g @rely-ai/caliber@${tag}`)} manually to upgrade.
8940
8972
  `
8941
8973
  )
8942
8974
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.20.0-dev.1773685636",
3
+ "version": "1.20.0-dev.1773686430",
4
4
  "description": "Analyze your codebase and generate optimized AI agent configs (CLAUDE.md, .cursorrules, skills) — no API key needed",
5
5
  "type": "module",
6
6
  "bin": {