@rely-ai/caliber 1.7.4 → 1.7.5

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 +196 -159
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -165,7 +165,7 @@ var init_constants = __esm({
165
165
 
166
166
  // src/cli.ts
167
167
  import { Command } from "commander";
168
- import fs28 from "fs";
168
+ import fs29 from "fs";
169
169
  import path22 from "path";
170
170
  import { fileURLToPath } from "url";
171
171
 
@@ -175,7 +175,7 @@ import ora2 from "ora";
175
175
  import readline3 from "readline";
176
176
  import select5 from "@inquirer/select";
177
177
  import checkbox from "@inquirer/checkbox";
178
- import fs22 from "fs";
178
+ import fs23 from "fs";
179
179
 
180
180
  // src/fingerprint/index.ts
181
181
  import fs6 from "fs";
@@ -2670,28 +2670,64 @@ ${agentRefs.join(" ")}
2670
2670
  }
2671
2671
 
2672
2672
  // src/lib/hooks.ts
2673
- import fs16 from "fs";
2673
+ import fs17 from "fs";
2674
2674
  import path12 from "path";
2675
+ import { execSync as execSync6 } from "child_process";
2676
+
2677
+ // src/lib/resolve-caliber.ts
2678
+ import fs16 from "fs";
2675
2679
  import { execSync as execSync5 } from "child_process";
2680
+ var _resolved = null;
2681
+ function resolveCaliber() {
2682
+ if (_resolved) return _resolved;
2683
+ try {
2684
+ const found = execSync5("which caliber", {
2685
+ encoding: "utf-8",
2686
+ stdio: ["pipe", "pipe", "pipe"]
2687
+ }).trim();
2688
+ if (found) {
2689
+ _resolved = found;
2690
+ return _resolved;
2691
+ }
2692
+ } catch {
2693
+ }
2694
+ const binPath = process.argv[1];
2695
+ if (binPath && fs16.existsSync(binPath)) {
2696
+ _resolved = binPath;
2697
+ return _resolved;
2698
+ }
2699
+ _resolved = "caliber";
2700
+ return _resolved;
2701
+ }
2702
+ function isCaliberCommand(command, subcommandTail) {
2703
+ if (command === `caliber ${subcommandTail}`) return true;
2704
+ if (command.endsWith(`/caliber ${subcommandTail}`)) return true;
2705
+ return false;
2706
+ }
2707
+
2708
+ // src/lib/hooks.ts
2676
2709
  var SETTINGS_PATH = path12.join(".claude", "settings.json");
2677
- var HOOK_COMMAND = "caliber refresh --quiet";
2710
+ var REFRESH_TAIL = "refresh --quiet";
2678
2711
  var HOOK_DESCRIPTION = "Caliber: auto-refreshing docs based on code changes";
2712
+ function getHookCommand() {
2713
+ return `${resolveCaliber()} ${REFRESH_TAIL}`;
2714
+ }
2679
2715
  function readSettings() {
2680
- if (!fs16.existsSync(SETTINGS_PATH)) return {};
2716
+ if (!fs17.existsSync(SETTINGS_PATH)) return {};
2681
2717
  try {
2682
- return JSON.parse(fs16.readFileSync(SETTINGS_PATH, "utf-8"));
2718
+ return JSON.parse(fs17.readFileSync(SETTINGS_PATH, "utf-8"));
2683
2719
  } catch {
2684
2720
  return {};
2685
2721
  }
2686
2722
  }
2687
2723
  function writeSettings(settings) {
2688
2724
  const dir = path12.dirname(SETTINGS_PATH);
2689
- if (!fs16.existsSync(dir)) fs16.mkdirSync(dir, { recursive: true });
2690
- fs16.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
2725
+ if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
2726
+ fs17.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
2691
2727
  }
2692
2728
  function findHookIndex(sessionEnd) {
2693
2729
  return sessionEnd.findIndex(
2694
- (entry) => entry.hooks?.some((h) => h.command === HOOK_COMMAND)
2730
+ (entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, REFRESH_TAIL))
2695
2731
  );
2696
2732
  }
2697
2733
  function isHookInstalled() {
@@ -2709,7 +2745,7 @@ function installHook() {
2709
2745
  }
2710
2746
  settings.hooks.SessionEnd.push({
2711
2747
  matcher: "",
2712
- hooks: [{ type: "command", command: HOOK_COMMAND, description: HOOK_DESCRIPTION }]
2748
+ hooks: [{ type: "command", command: getHookCommand(), description: HOOK_DESCRIPTION }]
2713
2749
  });
2714
2750
  writeSettings(settings);
2715
2751
  return { installed: true, alreadyInstalled: false };
@@ -2736,16 +2772,19 @@ function removeHook() {
2736
2772
  }
2737
2773
  var PRECOMMIT_START = "# caliber:pre-commit:start";
2738
2774
  var PRECOMMIT_END = "# caliber:pre-commit:end";
2739
- var PRECOMMIT_BLOCK = `${PRECOMMIT_START}
2740
- if command -v caliber >/dev/null 2>&1; then
2775
+ function getPrecommitBlock() {
2776
+ const bin = resolveCaliber();
2777
+ return `${PRECOMMIT_START}
2778
+ if [ -x "${bin}" ] || command -v "${bin}" >/dev/null 2>&1; then
2741
2779
  echo "\\033[2mcaliber: refreshing docs...\\033[0m"
2742
- caliber refresh 2>/dev/null || true
2780
+ "${bin}" refresh 2>/dev/null || true
2743
2781
  git diff --name-only -- CLAUDE.md .claude/ .cursor/ AGENTS.md 2>/dev/null | xargs git add 2>/dev/null || true
2744
2782
  fi
2745
2783
  ${PRECOMMIT_END}`;
2784
+ }
2746
2785
  function getGitHooksDir() {
2747
2786
  try {
2748
- const gitDir = execSync5("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
2787
+ const gitDir = execSync6("git rev-parse --git-dir", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
2749
2788
  return path12.join(gitDir, "hooks");
2750
2789
  } catch {
2751
2790
  return null;
@@ -2757,8 +2796,8 @@ function getPreCommitPath() {
2757
2796
  }
2758
2797
  function isPreCommitHookInstalled() {
2759
2798
  const hookPath = getPreCommitPath();
2760
- if (!hookPath || !fs16.existsSync(hookPath)) return false;
2761
- const content = fs16.readFileSync(hookPath, "utf-8");
2799
+ if (!hookPath || !fs17.existsSync(hookPath)) return false;
2800
+ const content = fs17.readFileSync(hookPath, "utf-8");
2762
2801
  return content.includes(PRECOMMIT_START);
2763
2802
  }
2764
2803
  function installPreCommitHook() {
@@ -2768,81 +2807,78 @@ function installPreCommitHook() {
2768
2807
  const hookPath = getPreCommitPath();
2769
2808
  if (!hookPath) return { installed: false, alreadyInstalled: false };
2770
2809
  const hooksDir = path12.dirname(hookPath);
2771
- if (!fs16.existsSync(hooksDir)) fs16.mkdirSync(hooksDir, { recursive: true });
2810
+ if (!fs17.existsSync(hooksDir)) fs17.mkdirSync(hooksDir, { recursive: true });
2772
2811
  let content = "";
2773
- if (fs16.existsSync(hookPath)) {
2774
- content = fs16.readFileSync(hookPath, "utf-8");
2812
+ if (fs17.existsSync(hookPath)) {
2813
+ content = fs17.readFileSync(hookPath, "utf-8");
2775
2814
  if (!content.endsWith("\n")) content += "\n";
2776
- content += "\n" + PRECOMMIT_BLOCK + "\n";
2815
+ content += "\n" + getPrecommitBlock() + "\n";
2777
2816
  } else {
2778
- content = "#!/bin/sh\n\n" + PRECOMMIT_BLOCK + "\n";
2817
+ content = "#!/bin/sh\n\n" + getPrecommitBlock() + "\n";
2779
2818
  }
2780
- fs16.writeFileSync(hookPath, content);
2781
- fs16.chmodSync(hookPath, 493);
2819
+ fs17.writeFileSync(hookPath, content);
2820
+ fs17.chmodSync(hookPath, 493);
2782
2821
  return { installed: true, alreadyInstalled: false };
2783
2822
  }
2784
2823
  function removePreCommitHook() {
2785
2824
  const hookPath = getPreCommitPath();
2786
- if (!hookPath || !fs16.existsSync(hookPath)) {
2825
+ if (!hookPath || !fs17.existsSync(hookPath)) {
2787
2826
  return { removed: false, notFound: true };
2788
2827
  }
2789
- let content = fs16.readFileSync(hookPath, "utf-8");
2828
+ let content = fs17.readFileSync(hookPath, "utf-8");
2790
2829
  if (!content.includes(PRECOMMIT_START)) {
2791
2830
  return { removed: false, notFound: true };
2792
2831
  }
2793
2832
  const regex = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
2794
2833
  content = content.replace(regex, "\n");
2795
2834
  if (content.trim() === "#!/bin/sh" || content.trim() === "") {
2796
- fs16.unlinkSync(hookPath);
2835
+ fs17.unlinkSync(hookPath);
2797
2836
  } else {
2798
- fs16.writeFileSync(hookPath, content);
2837
+ fs17.writeFileSync(hookPath, content);
2799
2838
  }
2800
2839
  return { removed: true, notFound: false };
2801
2840
  }
2802
2841
 
2803
2842
  // src/lib/learning-hooks.ts
2804
- import fs17 from "fs";
2843
+ import fs18 from "fs";
2805
2844
  import path13 from "path";
2806
2845
  var SETTINGS_PATH2 = path13.join(".claude", "settings.json");
2807
- var HOOK_CONFIGS = [
2808
- {
2809
- event: "PostToolUse",
2810
- command: "caliber learn observe",
2811
- description: "Caliber: recording tool usage for session learning"
2812
- },
2813
- {
2814
- event: "PostToolUseFailure",
2815
- command: "caliber learn observe --failure",
2816
- description: "Caliber: recording tool failure for session learning"
2817
- },
2818
- {
2819
- event: "SessionEnd",
2820
- command: "caliber learn finalize",
2821
- description: "Caliber: finalizing session learnings"
2822
- }
2846
+ var HOOK_TAILS = [
2847
+ { event: "PostToolUse", tail: "learn observe", description: "Caliber: recording tool usage for session learning" },
2848
+ { event: "PostToolUseFailure", tail: "learn observe --failure", description: "Caliber: recording tool failure for session learning" },
2849
+ { event: "SessionEnd", tail: "learn finalize", description: "Caliber: finalizing session learnings" }
2823
2850
  ];
2851
+ function getHookConfigs() {
2852
+ const bin = resolveCaliber();
2853
+ return HOOK_TAILS.map(({ event, tail, description }) => ({
2854
+ event,
2855
+ command: `${bin} ${tail}`,
2856
+ tail,
2857
+ description
2858
+ }));
2859
+ }
2824
2860
  function readSettings2() {
2825
- if (!fs17.existsSync(SETTINGS_PATH2)) return {};
2861
+ if (!fs18.existsSync(SETTINGS_PATH2)) return {};
2826
2862
  try {
2827
- return JSON.parse(fs17.readFileSync(SETTINGS_PATH2, "utf-8"));
2863
+ return JSON.parse(fs18.readFileSync(SETTINGS_PATH2, "utf-8"));
2828
2864
  } catch {
2829
2865
  return {};
2830
2866
  }
2831
2867
  }
2832
2868
  function writeSettings2(settings) {
2833
2869
  const dir = path13.dirname(SETTINGS_PATH2);
2834
- if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
2835
- fs17.writeFileSync(SETTINGS_PATH2, JSON.stringify(settings, null, 2));
2870
+ if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
2871
+ fs18.writeFileSync(SETTINGS_PATH2, JSON.stringify(settings, null, 2));
2836
2872
  }
2837
- function hasLearningHook(matchers, command) {
2838
- return matchers.some((entry) => entry.hooks?.some((h) => h.command === command));
2873
+ function hasLearningHook(matchers, tail) {
2874
+ return matchers.some((entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, tail)));
2839
2875
  }
2840
2876
  function areLearningHooksInstalled() {
2841
2877
  const settings = readSettings2();
2842
2878
  if (!settings.hooks) return false;
2843
- return HOOK_CONFIGS.every((cfg) => {
2879
+ return HOOK_TAILS.every((cfg) => {
2844
2880
  const matchers = settings.hooks[cfg.event];
2845
- return Array.isArray(matchers) && hasLearningHook(matchers, cfg.command);
2881
+ return Array.isArray(matchers) && hasLearningHook(matchers, cfg.tail);
2846
2882
  });
2847
2883
  }
2848
2884
  function installLearningHooks() {
@@ -2851,11 +2887,12 @@ function installLearningHooks() {
2851
2887
  }
2852
2888
  const settings = readSettings2();
2853
2889
  if (!settings.hooks) settings.hooks = {};
2854
- for (const cfg of HOOK_CONFIGS) {
2890
+ const configs = getHookConfigs();
2891
+ for (const cfg of configs) {
2855
2892
  if (!Array.isArray(settings.hooks[cfg.event])) {
2856
2893
  settings.hooks[cfg.event] = [];
2857
2894
  }
2858
- if (!hasLearningHook(settings.hooks[cfg.event], cfg.command)) {
2895
+ if (!hasLearningHook(settings.hooks[cfg.event], cfg.tail)) {
2859
2896
  settings.hooks[cfg.event].push({
2860
2897
  matcher: "",
2861
2898
  hooks: [{ type: "command", command: cfg.command, description: cfg.description }]
@@ -2869,10 +2906,10 @@ function removeLearningHooks() {
2869
2906
  const settings = readSettings2();
2870
2907
  if (!settings.hooks) return { removed: false, notFound: true };
2871
2908
  let removedAny = false;
2872
- for (const cfg of HOOK_CONFIGS) {
2909
+ for (const cfg of HOOK_TAILS) {
2873
2910
  const matchers = settings.hooks[cfg.event];
2874
2911
  if (!Array.isArray(matchers)) continue;
2875
- const idx = matchers.findIndex((entry) => entry.hooks?.some((h) => h.command === cfg.command));
2912
+ const idx = matchers.findIndex((entry) => entry.hooks?.some((h) => isCaliberCommand(h.command, cfg.tail)));
2876
2913
  if (idx !== -1) {
2877
2914
  matchers.splice(idx, 1);
2878
2915
  removedAny = true;
@@ -2889,9 +2926,9 @@ function removeLearningHooks() {
2889
2926
 
2890
2927
  // src/lib/state.ts
2891
2928
  init_constants();
2892
- import fs18 from "fs";
2929
+ import fs19 from "fs";
2893
2930
  import path14 from "path";
2894
- import { execSync as execSync6 } from "child_process";
2931
+ import { execSync as execSync7 } from "child_process";
2895
2932
  var STATE_FILE = path14.join(CALIBER_DIR, ".caliber-state.json");
2896
2933
  function normalizeTargetAgent(value) {
2897
2934
  if (Array.isArray(value)) return value;
@@ -2903,8 +2940,8 @@ function normalizeTargetAgent(value) {
2903
2940
  }
2904
2941
  function readState() {
2905
2942
  try {
2906
- if (!fs18.existsSync(STATE_FILE)) return null;
2907
- const raw = JSON.parse(fs18.readFileSync(STATE_FILE, "utf-8"));
2943
+ if (!fs19.existsSync(STATE_FILE)) return null;
2944
+ const raw = JSON.parse(fs19.readFileSync(STATE_FILE, "utf-8"));
2908
2945
  if (raw.targetAgent) raw.targetAgent = normalizeTargetAgent(raw.targetAgent);
2909
2946
  return raw;
2910
2947
  } catch {
@@ -2912,14 +2949,14 @@ function readState() {
2912
2949
  }
2913
2950
  }
2914
2951
  function writeState(state) {
2915
- if (!fs18.existsSync(CALIBER_DIR)) {
2916
- fs18.mkdirSync(CALIBER_DIR, { recursive: true });
2952
+ if (!fs19.existsSync(CALIBER_DIR)) {
2953
+ fs19.mkdirSync(CALIBER_DIR, { recursive: true });
2917
2954
  }
2918
- fs18.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
2955
+ fs19.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
2919
2956
  }
2920
2957
  function getCurrentHeadSha() {
2921
2958
  try {
2922
- return execSync6("git rev-parse HEAD", {
2959
+ return execSync7("git rev-parse HEAD", {
2923
2960
  encoding: "utf-8",
2924
2961
  stdio: ["pipe", "pipe", "pipe"]
2925
2962
  }).trim();
@@ -4041,7 +4078,7 @@ function checkFreshness(dir) {
4041
4078
 
4042
4079
  // src/scoring/checks/bonus.ts
4043
4080
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
4044
- import { execSync as execSync7 } from "child_process";
4081
+ import { execSync as execSync8 } from "child_process";
4045
4082
  import { join as join6 } from "path";
4046
4083
  function readFileOrNull5(path24) {
4047
4084
  try {
@@ -4052,7 +4089,7 @@ function readFileOrNull5(path24) {
4052
4089
  }
4053
4090
  function hasPreCommitHook(dir) {
4054
4091
  try {
4055
- const gitDir = execSync7("git rev-parse --git-dir", { cwd: dir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
4092
+ const gitDir = execSync8("git rev-parse --git-dir", { cwd: dir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
4056
4093
  const hookPath = join6(gitDir, "hooks", "pre-commit");
4057
4094
  const content = readFileOrNull5(hookPath);
4058
4095
  return content ? content.includes("caliber") : false;
@@ -4140,22 +4177,22 @@ function checkBonus(dir) {
4140
4177
 
4141
4178
  // src/scoring/dismissed.ts
4142
4179
  init_constants();
4143
- import fs19 from "fs";
4180
+ import fs20 from "fs";
4144
4181
  import path15 from "path";
4145
4182
  var DISMISSED_FILE = path15.join(CALIBER_DIR, "dismissed-checks.json");
4146
4183
  function readDismissedChecks() {
4147
4184
  try {
4148
- if (!fs19.existsSync(DISMISSED_FILE)) return [];
4149
- return JSON.parse(fs19.readFileSync(DISMISSED_FILE, "utf-8"));
4185
+ if (!fs20.existsSync(DISMISSED_FILE)) return [];
4186
+ return JSON.parse(fs20.readFileSync(DISMISSED_FILE, "utf-8"));
4150
4187
  } catch {
4151
4188
  return [];
4152
4189
  }
4153
4190
  }
4154
4191
  function writeDismissedChecks(checks) {
4155
- if (!fs19.existsSync(CALIBER_DIR)) {
4156
- fs19.mkdirSync(CALIBER_DIR, { recursive: true });
4192
+ if (!fs20.existsSync(CALIBER_DIR)) {
4193
+ fs20.mkdirSync(CALIBER_DIR, { recursive: true });
4157
4194
  }
4158
- fs19.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
4195
+ fs20.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
4159
4196
  }
4160
4197
  function getDismissedIds() {
4161
4198
  return new Set(readDismissedChecks().map((c) => c.id));
@@ -4350,13 +4387,13 @@ import { mkdirSync, readFileSync as readFileSync7, readdirSync as readdirSync5,
4350
4387
  import { join as join8, dirname as dirname2 } from "path";
4351
4388
 
4352
4389
  // src/scanner/index.ts
4353
- import fs20 from "fs";
4390
+ import fs21 from "fs";
4354
4391
  import path16 from "path";
4355
4392
  import crypto2 from "crypto";
4356
4393
  function scanLocalState(dir) {
4357
4394
  const items = [];
4358
4395
  const claudeMdPath = path16.join(dir, "CLAUDE.md");
4359
- if (fs20.existsSync(claudeMdPath)) {
4396
+ if (fs21.existsSync(claudeMdPath)) {
4360
4397
  items.push({
4361
4398
  type: "rule",
4362
4399
  platform: "claude",
@@ -4366,8 +4403,8 @@ function scanLocalState(dir) {
4366
4403
  });
4367
4404
  }
4368
4405
  const skillsDir = path16.join(dir, ".claude", "skills");
4369
- if (fs20.existsSync(skillsDir)) {
4370
- for (const file of fs20.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4406
+ if (fs21.existsSync(skillsDir)) {
4407
+ for (const file of fs21.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4371
4408
  const filePath = path16.join(skillsDir, file);
4372
4409
  items.push({
4373
4410
  type: "skill",
@@ -4379,9 +4416,9 @@ function scanLocalState(dir) {
4379
4416
  }
4380
4417
  }
4381
4418
  const mcpJsonPath = path16.join(dir, ".mcp.json");
4382
- if (fs20.existsSync(mcpJsonPath)) {
4419
+ if (fs21.existsSync(mcpJsonPath)) {
4383
4420
  try {
4384
- const mcpJson = JSON.parse(fs20.readFileSync(mcpJsonPath, "utf-8"));
4421
+ const mcpJson = JSON.parse(fs21.readFileSync(mcpJsonPath, "utf-8"));
4385
4422
  if (mcpJson.mcpServers) {
4386
4423
  for (const name of Object.keys(mcpJson.mcpServers)) {
4387
4424
  items.push({
@@ -4397,7 +4434,7 @@ function scanLocalState(dir) {
4397
4434
  }
4398
4435
  }
4399
4436
  const agentsMdPath = path16.join(dir, "AGENTS.md");
4400
- if (fs20.existsSync(agentsMdPath)) {
4437
+ if (fs21.existsSync(agentsMdPath)) {
4401
4438
  items.push({
4402
4439
  type: "rule",
4403
4440
  platform: "codex",
@@ -4407,11 +4444,11 @@ function scanLocalState(dir) {
4407
4444
  });
4408
4445
  }
4409
4446
  const codexSkillsDir = path16.join(dir, ".agents", "skills");
4410
- if (fs20.existsSync(codexSkillsDir)) {
4447
+ if (fs21.existsSync(codexSkillsDir)) {
4411
4448
  try {
4412
- for (const name of fs20.readdirSync(codexSkillsDir)) {
4449
+ for (const name of fs21.readdirSync(codexSkillsDir)) {
4413
4450
  const skillFile = path16.join(codexSkillsDir, name, "SKILL.md");
4414
- if (fs20.existsSync(skillFile)) {
4451
+ if (fs21.existsSync(skillFile)) {
4415
4452
  items.push({
4416
4453
  type: "skill",
4417
4454
  platform: "codex",
@@ -4425,7 +4462,7 @@ function scanLocalState(dir) {
4425
4462
  }
4426
4463
  }
4427
4464
  const cursorrulesPath = path16.join(dir, ".cursorrules");
4428
- if (fs20.existsSync(cursorrulesPath)) {
4465
+ if (fs21.existsSync(cursorrulesPath)) {
4429
4466
  items.push({
4430
4467
  type: "rule",
4431
4468
  platform: "cursor",
@@ -4435,8 +4472,8 @@ function scanLocalState(dir) {
4435
4472
  });
4436
4473
  }
4437
4474
  const cursorRulesDir = path16.join(dir, ".cursor", "rules");
4438
- if (fs20.existsSync(cursorRulesDir)) {
4439
- for (const file of fs20.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4475
+ if (fs21.existsSync(cursorRulesDir)) {
4476
+ for (const file of fs21.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4440
4477
  const filePath = path16.join(cursorRulesDir, file);
4441
4478
  items.push({
4442
4479
  type: "rule",
@@ -4448,11 +4485,11 @@ function scanLocalState(dir) {
4448
4485
  }
4449
4486
  }
4450
4487
  const cursorSkillsDir = path16.join(dir, ".cursor", "skills");
4451
- if (fs20.existsSync(cursorSkillsDir)) {
4488
+ if (fs21.existsSync(cursorSkillsDir)) {
4452
4489
  try {
4453
- for (const name of fs20.readdirSync(cursorSkillsDir)) {
4490
+ for (const name of fs21.readdirSync(cursorSkillsDir)) {
4454
4491
  const skillFile = path16.join(cursorSkillsDir, name, "SKILL.md");
4455
- if (fs20.existsSync(skillFile)) {
4492
+ if (fs21.existsSync(skillFile)) {
4456
4493
  items.push({
4457
4494
  type: "skill",
4458
4495
  platform: "cursor",
@@ -4466,9 +4503,9 @@ function scanLocalState(dir) {
4466
4503
  }
4467
4504
  }
4468
4505
  const cursorMcpPath = path16.join(dir, ".cursor", "mcp.json");
4469
- if (fs20.existsSync(cursorMcpPath)) {
4506
+ if (fs21.existsSync(cursorMcpPath)) {
4470
4507
  try {
4471
- const mcpJson = JSON.parse(fs20.readFileSync(cursorMcpPath, "utf-8"));
4508
+ const mcpJson = JSON.parse(fs21.readFileSync(cursorMcpPath, "utf-8"));
4472
4509
  if (mcpJson.mcpServers) {
4473
4510
  for (const name of Object.keys(mcpJson.mcpServers)) {
4474
4511
  items.push({
@@ -4486,7 +4523,7 @@ function scanLocalState(dir) {
4486
4523
  return items;
4487
4524
  }
4488
4525
  function hashFile(filePath) {
4489
- const text = fs20.readFileSync(filePath, "utf-8");
4526
+ const text = fs21.readFileSync(filePath, "utf-8");
4490
4527
  return crypto2.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
4491
4528
  }
4492
4529
  function hashJson(obj) {
@@ -4501,27 +4538,27 @@ import { PostHog } from "posthog-node";
4501
4538
  import chalk6 from "chalk";
4502
4539
 
4503
4540
  // src/telemetry/config.ts
4504
- import fs21 from "fs";
4541
+ import fs22 from "fs";
4505
4542
  import path17 from "path";
4506
4543
  import os3 from "os";
4507
4544
  import crypto3 from "crypto";
4508
- import { execSync as execSync8 } from "child_process";
4545
+ import { execSync as execSync9 } from "child_process";
4509
4546
  var CONFIG_DIR2 = path17.join(os3.homedir(), ".caliber");
4510
4547
  var CONFIG_FILE2 = path17.join(CONFIG_DIR2, "config.json");
4511
4548
  var runtimeDisabled = false;
4512
4549
  function readConfig() {
4513
4550
  try {
4514
- if (!fs21.existsSync(CONFIG_FILE2)) return {};
4515
- return JSON.parse(fs21.readFileSync(CONFIG_FILE2, "utf-8"));
4551
+ if (!fs22.existsSync(CONFIG_FILE2)) return {};
4552
+ return JSON.parse(fs22.readFileSync(CONFIG_FILE2, "utf-8"));
4516
4553
  } catch {
4517
4554
  return {};
4518
4555
  }
4519
4556
  }
4520
4557
  function writeConfig(config) {
4521
- if (!fs21.existsSync(CONFIG_DIR2)) {
4522
- fs21.mkdirSync(CONFIG_DIR2, { recursive: true });
4558
+ if (!fs22.existsSync(CONFIG_DIR2)) {
4559
+ fs22.mkdirSync(CONFIG_DIR2, { recursive: true });
4523
4560
  }
4524
- fs21.writeFileSync(CONFIG_FILE2, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
4561
+ fs22.writeFileSync(CONFIG_FILE2, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
4525
4562
  }
4526
4563
  function getMachineId() {
4527
4564
  const config = readConfig();
@@ -4532,7 +4569,7 @@ function getMachineId() {
4532
4569
  }
4533
4570
  function getGitEmailHash() {
4534
4571
  try {
4535
- const email = execSync8("git config user.email", { encoding: "utf-8" }).trim();
4572
+ const email = execSync9("git config user.email", { encoding: "utf-8" }).trim();
4536
4573
  if (!email) return void 0;
4537
4574
  return crypto3.createHash("sha256").update(email).digest("hex");
4538
4575
  } catch {
@@ -5738,7 +5775,7 @@ function printSetupSummary(setup) {
5738
5775
  };
5739
5776
  if (claude) {
5740
5777
  if (claude.claudeMd) {
5741
- const icon = fs22.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5778
+ const icon = fs23.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5742
5779
  const desc = getDescription("CLAUDE.md");
5743
5780
  console.log(` ${icon} ${chalk8.bold("CLAUDE.md")}`);
5744
5781
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5748,7 +5785,7 @@ function printSetupSummary(setup) {
5748
5785
  if (Array.isArray(skills) && skills.length > 0) {
5749
5786
  for (const skill of skills) {
5750
5787
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
5751
- const icon = fs22.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5788
+ const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5752
5789
  const desc = getDescription(skillPath);
5753
5790
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5754
5791
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5759,7 +5796,7 @@ function printSetupSummary(setup) {
5759
5796
  const codex = setup.codex;
5760
5797
  if (codex) {
5761
5798
  if (codex.agentsMd) {
5762
- const icon = fs22.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5799
+ const icon = fs23.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5763
5800
  const desc = getDescription("AGENTS.md");
5764
5801
  console.log(` ${icon} ${chalk8.bold("AGENTS.md")}`);
5765
5802
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5769,7 +5806,7 @@ function printSetupSummary(setup) {
5769
5806
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
5770
5807
  for (const skill of codexSkills) {
5771
5808
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
5772
- const icon = fs22.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5809
+ const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5773
5810
  const desc = getDescription(skillPath);
5774
5811
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5775
5812
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5779,7 +5816,7 @@ function printSetupSummary(setup) {
5779
5816
  }
5780
5817
  if (cursor) {
5781
5818
  if (cursor.cursorrules) {
5782
- const icon = fs22.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5819
+ const icon = fs23.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5783
5820
  const desc = getDescription(".cursorrules");
5784
5821
  console.log(` ${icon} ${chalk8.bold(".cursorrules")}`);
5785
5822
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5789,7 +5826,7 @@ function printSetupSummary(setup) {
5789
5826
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
5790
5827
  for (const skill of cursorSkills) {
5791
5828
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
5792
- const icon = fs22.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5829
+ const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5793
5830
  const desc = getDescription(skillPath);
5794
5831
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5795
5832
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5800,7 +5837,7 @@ function printSetupSummary(setup) {
5800
5837
  if (Array.isArray(rules) && rules.length > 0) {
5801
5838
  for (const rule of rules) {
5802
5839
  const rulePath = `.cursor/rules/${rule.filename}`;
5803
- const icon = fs22.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5840
+ const icon = fs23.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5804
5841
  const desc = getDescription(rulePath);
5805
5842
  console.log(` ${icon} ${chalk8.bold(rulePath)}`);
5806
5843
  if (desc) {
@@ -5813,7 +5850,7 @@ function printSetupSummary(setup) {
5813
5850
  }
5814
5851
  }
5815
5852
  }
5816
- if (!codex && !fs22.existsSync("AGENTS.md")) {
5853
+ if (!codex && !fs23.existsSync("AGENTS.md")) {
5817
5854
  console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
5818
5855
  console.log(chalk8.dim(" Cross-agent coordination file"));
5819
5856
  console.log("");
@@ -5832,8 +5869,8 @@ function ensurePermissions() {
5832
5869
  const settingsPath = ".claude/settings.json";
5833
5870
  let settings = {};
5834
5871
  try {
5835
- if (fs22.existsSync(settingsPath)) {
5836
- settings = JSON.parse(fs22.readFileSync(settingsPath, "utf-8"));
5872
+ if (fs23.existsSync(settingsPath)) {
5873
+ settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
5837
5874
  }
5838
5875
  } catch {
5839
5876
  }
@@ -5847,8 +5884,8 @@ function ensurePermissions() {
5847
5884
  "Bash(git *)"
5848
5885
  ];
5849
5886
  settings.permissions = permissions;
5850
- if (!fs22.existsSync(".claude")) fs22.mkdirSync(".claude", { recursive: true });
5851
- fs22.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5887
+ if (!fs23.existsSync(".claude")) fs23.mkdirSync(".claude", { recursive: true });
5888
+ fs23.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5852
5889
  }
5853
5890
 
5854
5891
  // src/commands/undo.ts
@@ -5885,7 +5922,7 @@ function undoCommand() {
5885
5922
 
5886
5923
  // src/commands/status.ts
5887
5924
  import chalk10 from "chalk";
5888
- import fs23 from "fs";
5925
+ import fs24 from "fs";
5889
5926
  init_config();
5890
5927
  async function statusCommand(options) {
5891
5928
  const config = loadConfig();
@@ -5912,7 +5949,7 @@ async function statusCommand(options) {
5912
5949
  }
5913
5950
  console.log(` Files managed: ${chalk10.cyan(manifest.entries.length.toString())}`);
5914
5951
  for (const entry of manifest.entries) {
5915
- const exists = fs23.existsSync(entry.path);
5952
+ const exists = fs24.existsSync(entry.path);
5916
5953
  const icon = exists ? chalk10.green("\u2713") : chalk10.red("\u2717");
5917
5954
  console.log(` ${icon} ${entry.path} (${entry.action})`);
5918
5955
  }
@@ -6093,13 +6130,13 @@ async function scoreCommand(options) {
6093
6130
  }
6094
6131
 
6095
6132
  // src/commands/refresh.ts
6096
- import fs25 from "fs";
6133
+ import fs26 from "fs";
6097
6134
  import path19 from "path";
6098
6135
  import chalk13 from "chalk";
6099
6136
  import ora5 from "ora";
6100
6137
 
6101
6138
  // src/lib/git-diff.ts
6102
- import { execSync as execSync9 } from "child_process";
6139
+ import { execSync as execSync10 } from "child_process";
6103
6140
  var MAX_DIFF_BYTES = 1e5;
6104
6141
  var DOC_PATTERNS = [
6105
6142
  "CLAUDE.md",
@@ -6113,7 +6150,7 @@ function excludeArgs() {
6113
6150
  }
6114
6151
  function safeExec(cmd) {
6115
6152
  try {
6116
- return execSync9(cmd, {
6153
+ return execSync10(cmd, {
6117
6154
  encoding: "utf-8",
6118
6155
  stdio: ["pipe", "pipe", "pipe"],
6119
6156
  maxBuffer: 10 * 1024 * 1024
@@ -6171,37 +6208,37 @@ function collectDiff(lastSha) {
6171
6208
  }
6172
6209
 
6173
6210
  // src/writers/refresh.ts
6174
- import fs24 from "fs";
6211
+ import fs25 from "fs";
6175
6212
  import path18 from "path";
6176
6213
  function writeRefreshDocs(docs) {
6177
6214
  const written = [];
6178
6215
  if (docs.claudeMd) {
6179
- fs24.writeFileSync("CLAUDE.md", docs.claudeMd);
6216
+ fs25.writeFileSync("CLAUDE.md", docs.claudeMd);
6180
6217
  written.push("CLAUDE.md");
6181
6218
  }
6182
6219
  if (docs.readmeMd) {
6183
- fs24.writeFileSync("README.md", docs.readmeMd);
6220
+ fs25.writeFileSync("README.md", docs.readmeMd);
6184
6221
  written.push("README.md");
6185
6222
  }
6186
6223
  if (docs.cursorrules) {
6187
- fs24.writeFileSync(".cursorrules", docs.cursorrules);
6224
+ fs25.writeFileSync(".cursorrules", docs.cursorrules);
6188
6225
  written.push(".cursorrules");
6189
6226
  }
6190
6227
  if (docs.cursorRules) {
6191
6228
  const rulesDir = path18.join(".cursor", "rules");
6192
- if (!fs24.existsSync(rulesDir)) fs24.mkdirSync(rulesDir, { recursive: true });
6229
+ if (!fs25.existsSync(rulesDir)) fs25.mkdirSync(rulesDir, { recursive: true });
6193
6230
  for (const rule of docs.cursorRules) {
6194
6231
  const filePath = path18.join(rulesDir, rule.filename);
6195
- fs24.writeFileSync(filePath, rule.content);
6232
+ fs25.writeFileSync(filePath, rule.content);
6196
6233
  written.push(filePath);
6197
6234
  }
6198
6235
  }
6199
6236
  if (docs.claudeSkills) {
6200
6237
  const skillsDir = path18.join(".claude", "skills");
6201
- if (!fs24.existsSync(skillsDir)) fs24.mkdirSync(skillsDir, { recursive: true });
6238
+ if (!fs25.existsSync(skillsDir)) fs25.mkdirSync(skillsDir, { recursive: true });
6202
6239
  for (const skill of docs.claudeSkills) {
6203
6240
  const filePath = path18.join(skillsDir, skill.filename);
6204
- fs24.writeFileSync(filePath, skill.content);
6241
+ fs25.writeFileSync(filePath, skill.content);
6205
6242
  written.push(filePath);
6206
6243
  }
6207
6244
  }
@@ -6280,11 +6317,11 @@ function log(quiet, ...args) {
6280
6317
  function discoverGitRepos(parentDir) {
6281
6318
  const repos = [];
6282
6319
  try {
6283
- const entries = fs25.readdirSync(parentDir, { withFileTypes: true });
6320
+ const entries = fs26.readdirSync(parentDir, { withFileTypes: true });
6284
6321
  for (const entry of entries) {
6285
6322
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
6286
6323
  const childPath = path19.join(parentDir, entry.name);
6287
- if (fs25.existsSync(path19.join(childPath, ".git"))) {
6324
+ if (fs26.existsSync(path19.join(childPath, ".git"))) {
6288
6325
  repos.push(childPath);
6289
6326
  }
6290
6327
  }
@@ -6636,7 +6673,7 @@ function readStdin() {
6636
6673
 
6637
6674
  // src/learner/storage.ts
6638
6675
  init_constants();
6639
- import fs26 from "fs";
6676
+ import fs27 from "fs";
6640
6677
  import path20 from "path";
6641
6678
  var MAX_RESPONSE_LENGTH = 2e3;
6642
6679
  var DEFAULT_STATE = {
@@ -6645,8 +6682,8 @@ var DEFAULT_STATE = {
6645
6682
  lastAnalysisTimestamp: null
6646
6683
  };
6647
6684
  function ensureLearningDir() {
6648
- if (!fs26.existsSync(LEARNING_DIR)) {
6649
- fs26.mkdirSync(LEARNING_DIR, { recursive: true });
6685
+ if (!fs27.existsSync(LEARNING_DIR)) {
6686
+ fs27.mkdirSync(LEARNING_DIR, { recursive: true });
6650
6687
  }
6651
6688
  }
6652
6689
  function sessionFilePath() {
@@ -6664,49 +6701,49 @@ function appendEvent(event) {
6664
6701
  ensureLearningDir();
6665
6702
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
6666
6703
  const filePath = sessionFilePath();
6667
- fs26.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6704
+ fs27.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6668
6705
  const count = getEventCount();
6669
6706
  if (count > LEARNING_MAX_EVENTS) {
6670
- const lines = fs26.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6707
+ const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6671
6708
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
6672
- fs26.writeFileSync(filePath, kept.join("\n") + "\n");
6709
+ fs27.writeFileSync(filePath, kept.join("\n") + "\n");
6673
6710
  }
6674
6711
  }
6675
6712
  function readAllEvents() {
6676
6713
  const filePath = sessionFilePath();
6677
- if (!fs26.existsSync(filePath)) return [];
6678
- const lines = fs26.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6714
+ if (!fs27.existsSync(filePath)) return [];
6715
+ const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6679
6716
  return lines.map((line) => JSON.parse(line));
6680
6717
  }
6681
6718
  function getEventCount() {
6682
6719
  const filePath = sessionFilePath();
6683
- if (!fs26.existsSync(filePath)) return 0;
6684
- const content = fs26.readFileSync(filePath, "utf-8");
6720
+ if (!fs27.existsSync(filePath)) return 0;
6721
+ const content = fs27.readFileSync(filePath, "utf-8");
6685
6722
  return content.split("\n").filter(Boolean).length;
6686
6723
  }
6687
6724
  function clearSession() {
6688
6725
  const filePath = sessionFilePath();
6689
- if (fs26.existsSync(filePath)) fs26.unlinkSync(filePath);
6726
+ if (fs27.existsSync(filePath)) fs27.unlinkSync(filePath);
6690
6727
  }
6691
6728
  function readState2() {
6692
6729
  const filePath = stateFilePath();
6693
- if (!fs26.existsSync(filePath)) return { ...DEFAULT_STATE };
6730
+ if (!fs27.existsSync(filePath)) return { ...DEFAULT_STATE };
6694
6731
  try {
6695
- return JSON.parse(fs26.readFileSync(filePath, "utf-8"));
6732
+ return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
6696
6733
  } catch {
6697
6734
  return { ...DEFAULT_STATE };
6698
6735
  }
6699
6736
  }
6700
6737
  function writeState2(state) {
6701
6738
  ensureLearningDir();
6702
- fs26.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6739
+ fs27.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6703
6740
  }
6704
6741
  function resetState() {
6705
6742
  writeState2({ ...DEFAULT_STATE });
6706
6743
  }
6707
6744
 
6708
6745
  // src/learner/writer.ts
6709
- import fs27 from "fs";
6746
+ import fs28 from "fs";
6710
6747
  import path21 from "path";
6711
6748
  var LEARNED_START = "<!-- caliber:learned -->";
6712
6749
  var LEARNED_END = "<!-- /caliber:learned -->";
@@ -6727,8 +6764,8 @@ function writeLearnedContent(update) {
6727
6764
  function writeLearnedSection(content) {
6728
6765
  const claudeMdPath = "CLAUDE.md";
6729
6766
  let existing = "";
6730
- if (fs27.existsSync(claudeMdPath)) {
6731
- existing = fs27.readFileSync(claudeMdPath, "utf-8");
6767
+ if (fs28.existsSync(claudeMdPath)) {
6768
+ existing = fs28.readFileSync(claudeMdPath, "utf-8");
6732
6769
  }
6733
6770
  const section = `${LEARNED_START}
6734
6771
  ${content}
@@ -6742,15 +6779,15 @@ ${LEARNED_END}`;
6742
6779
  const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
6743
6780
  updated = existing + separator + "\n" + section + "\n";
6744
6781
  }
6745
- fs27.writeFileSync(claudeMdPath, updated);
6782
+ fs28.writeFileSync(claudeMdPath, updated);
6746
6783
  }
6747
6784
  function writeLearnedSkill(skill) {
6748
6785
  const skillDir = path21.join(".claude", "skills", skill.name);
6749
- if (!fs27.existsSync(skillDir)) fs27.mkdirSync(skillDir, { recursive: true });
6786
+ if (!fs28.existsSync(skillDir)) fs28.mkdirSync(skillDir, { recursive: true });
6750
6787
  const skillPath = path21.join(skillDir, "SKILL.md");
6751
- if (!skill.isNew && fs27.existsSync(skillPath)) {
6752
- const existing = fs27.readFileSync(skillPath, "utf-8");
6753
- fs27.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6788
+ if (!skill.isNew && fs28.existsSync(skillPath)) {
6789
+ const existing = fs28.readFileSync(skillPath, "utf-8");
6790
+ fs28.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6754
6791
  } else {
6755
6792
  const frontmatter = [
6756
6793
  "---",
@@ -6759,14 +6796,14 @@ function writeLearnedSkill(skill) {
6759
6796
  "---",
6760
6797
  ""
6761
6798
  ].join("\n");
6762
- fs27.writeFileSync(skillPath, frontmatter + skill.content);
6799
+ fs28.writeFileSync(skillPath, frontmatter + skill.content);
6763
6800
  }
6764
6801
  return skillPath;
6765
6802
  }
6766
6803
  function readLearnedSection() {
6767
6804
  const claudeMdPath = "CLAUDE.md";
6768
- if (!fs27.existsSync(claudeMdPath)) return null;
6769
- const content = fs27.readFileSync(claudeMdPath, "utf-8");
6805
+ if (!fs28.existsSync(claudeMdPath)) return null;
6806
+ const content = fs28.readFileSync(claudeMdPath, "utf-8");
6770
6807
  const startIdx = content.indexOf(LEARNED_START);
6771
6808
  const endIdx = content.indexOf(LEARNED_END);
6772
6809
  if (startIdx === -1 || endIdx === -1) return null;
@@ -6957,7 +6994,7 @@ Learned items in CLAUDE.md: ${chalk16.cyan(String(lineCount))}`);
6957
6994
  // src/cli.ts
6958
6995
  var __dirname = path22.dirname(fileURLToPath(import.meta.url));
6959
6996
  var pkg = JSON.parse(
6960
- fs28.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
6997
+ fs29.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
6961
6998
  );
6962
6999
  var program = new Command();
6963
7000
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -7031,22 +7068,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
7031
7068
  learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
7032
7069
 
7033
7070
  // src/utils/version-check.ts
7034
- import fs29 from "fs";
7071
+ import fs30 from "fs";
7035
7072
  import path23 from "path";
7036
7073
  import { fileURLToPath as fileURLToPath2 } from "url";
7037
- import { execSync as execSync10 } from "child_process";
7074
+ import { execSync as execSync11 } from "child_process";
7038
7075
  import chalk17 from "chalk";
7039
7076
  import ora6 from "ora";
7040
7077
  import confirm from "@inquirer/confirm";
7041
7078
  var __dirname_vc = path23.dirname(fileURLToPath2(import.meta.url));
7042
7079
  var pkg2 = JSON.parse(
7043
- fs29.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7080
+ fs30.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7044
7081
  );
7045
7082
  function getInstalledVersion() {
7046
7083
  try {
7047
- const globalRoot = execSync10("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
7084
+ const globalRoot = execSync11("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
7048
7085
  const pkgPath = path23.join(globalRoot, "@rely-ai", "caliber", "package.json");
7049
- return JSON.parse(fs29.readFileSync(pkgPath, "utf-8")).version;
7086
+ return JSON.parse(fs30.readFileSync(pkgPath, "utf-8")).version;
7050
7087
  } catch {
7051
7088
  return null;
7052
7089
  }
@@ -7089,7 +7126,7 @@ Update available: ${current} -> ${latest}`)
7089
7126
  }
7090
7127
  const spinner = ora6("Updating caliber...").start();
7091
7128
  try {
7092
- execSync10(`npm install -g @rely-ai/caliber@${latest}`, {
7129
+ execSync11(`npm install -g @rely-ai/caliber@${latest}`, {
7093
7130
  stdio: "pipe",
7094
7131
  timeout: 12e4,
7095
7132
  env: { ...process.env, npm_config_fund: "false", npm_config_audit: "false" }
@@ -7106,7 +7143,7 @@ Update available: ${current} -> ${latest}`)
7106
7143
  console.log(chalk17.dim(`
7107
7144
  Restarting: caliber ${args.join(" ")}
7108
7145
  `));
7109
- execSync10(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
7146
+ execSync11(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
7110
7147
  stdio: "inherit",
7111
7148
  env: { ...process.env, CALIBER_SKIP_UPDATE_CHECK: "1" }
7112
7149
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
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": {