@caliber-ai/cli 0.16.5 → 0.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -937,16 +937,6 @@ function scanLocalState(dir) {
937
937
  path: claudeMdPath
938
938
  });
939
939
  }
940
- const settingsPath = path9.join(dir, ".claude", "settings.json");
941
- if (fs8.existsSync(settingsPath)) {
942
- items.push({
943
- type: "config",
944
- platform: "claude",
945
- name: "settings.json",
946
- contentHash: hashFile(settingsPath),
947
- path: settingsPath
948
- });
949
- }
950
940
  const skillsDir = path9.join(dir, ".claude", "skills");
951
941
  if (fs8.existsSync(skillsDir)) {
952
942
  for (const file of fs8.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
@@ -970,7 +960,7 @@ function scanLocalState(dir) {
970
960
  type: "mcp",
971
961
  platform: "claude",
972
962
  name,
973
- contentHash: hashContent(JSON.stringify(mcpJson.mcpServers[name])),
963
+ contentHash: hashJson(mcpJson.mcpServers[name]),
974
964
  path: mcpJsonPath
975
965
  });
976
966
  }
@@ -1011,7 +1001,7 @@ function scanLocalState(dir) {
1011
1001
  type: "mcp",
1012
1002
  platform: "cursor",
1013
1003
  name,
1014
- contentHash: hashContent(JSON.stringify(mcpJson.mcpServers[name])),
1004
+ contentHash: hashJson(mcpJson.mcpServers[name]),
1015
1005
  path: cursorMcpPath
1016
1006
  });
1017
1007
  }
@@ -1048,11 +1038,11 @@ function compareState(serverItems, localItems) {
1048
1038
  return { installed, missing, outdated, extra };
1049
1039
  }
1050
1040
  function hashFile(filePath) {
1051
- const content = fs8.readFileSync(filePath);
1052
- return crypto3.createHash("sha256").update(content).digest("hex");
1041
+ const text = fs8.readFileSync(filePath, "utf-8");
1042
+ return crypto3.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
1053
1043
  }
1054
- function hashContent(content) {
1055
- return crypto3.createHash("sha256").update(JSON.stringify({ text: content })).digest("hex");
1044
+ function hashJson(obj) {
1045
+ return crypto3.createHash("sha256").update(JSON.stringify(obj)).digest("hex");
1056
1046
  }
1057
1047
 
1058
1048
  // src/api/client.ts
@@ -2575,11 +2565,10 @@ function printRecommendations(recs) {
2575
2565
  console.log("");
2576
2566
  }
2577
2567
 
2578
- // src/commands/health.ts
2568
+ // src/commands/sync.ts
2579
2569
  import chalk9 from "chalk";
2580
2570
  import ora6 from "ora";
2581
- import confirm2 from "@inquirer/confirm";
2582
- async function healthCommand(options) {
2571
+ async function syncCommand(options) {
2583
2572
  const auth2 = getStoredAuth();
2584
2573
  if (!auth2) {
2585
2574
  console.log(chalk9.red("Not authenticated. Run `caliber login` first."));
@@ -2596,153 +2585,7 @@ async function healthCommand(options) {
2596
2585
  throw new Error("__exit__");
2597
2586
  }
2598
2587
  const projectId = match.project.id;
2599
- const spinner = ora6("Analyzing context health...").start();
2600
- let report;
2601
- try {
2602
- report = await apiRequest(
2603
- `/api/context/project/${projectId}/analyze`,
2604
- { method: "POST" }
2605
- );
2606
- spinner.succeed("Analysis complete");
2607
- } catch (err) {
2608
- spinner.fail("Analysis failed");
2609
- throw err;
2610
- }
2611
- if (options.json) {
2612
- console.log(JSON.stringify(report, null, 2));
2613
- return;
2614
- }
2615
- printReport(report);
2616
- const shouldFix = options.fix || report.recommendations.length > 0 && !options.json && await confirm2({ message: "Would you like to fix these issues?", default: true });
2617
- if (shouldFix) {
2618
- const planSpinner = ora6("Generating fix plan...").start();
2619
- const plan = await apiRequest(
2620
- `/api/context/reports/${report.id}/fix-plan`,
2621
- { method: "POST", body: { projectId } }
2622
- );
2623
- planSpinner.succeed("Fix plan ready");
2624
- if (!plan?.actions.length) {
2625
- console.log(chalk9.dim(" No fixes needed."));
2626
- return;
2627
- }
2628
- console.log(chalk9.bold("\n Fix Plan:\n"));
2629
- for (const action of plan.actions) {
2630
- if (action.type === "remove") {
2631
- console.log(` ${chalk9.red("\u2717 Remove")} ${action.items.join(", ")}`);
2632
- if (action.reason) console.log(chalk9.dim(` ${action.reason}`));
2633
- } else if (action.type === "add") {
2634
- console.log(` ${chalk9.green("+ Add")} ${action.items.join(", ")}`);
2635
- if (action.reason) console.log(chalk9.dim(` ${action.reason}`));
2636
- }
2637
- console.log("");
2638
- }
2639
- const scoreAfterStr = plan.estimatedScoreAfter != null ? String(plan.estimatedScoreAfter) : `${report.score + plan.estimatedScoreImprovement}`;
2640
- console.log(` Expected: ${report.score} \u2192 ${chalk9.green(scoreAfterStr)}/100
2641
- `);
2642
- const shouldExecute = options.fix || await confirm2({ message: "Apply this fix plan?", default: true });
2643
- if (!shouldExecute) {
2644
- console.log(chalk9.dim(" Fix cancelled."));
2645
- return;
2646
- }
2647
- const fixSpinner = ora6("Applying fixes...").start();
2648
- try {
2649
- const result = await apiRequest(
2650
- `/api/context/reports/${report.id}/fix-execute`,
2651
- { method: "POST", body: { projectId } }
2652
- );
2653
- fixSpinner.succeed("Fixes applied");
2654
- console.log("");
2655
- console.log(` Score: ${result.scoreBefore} \u2192 ${chalk9.green(String(result.scoreAfter))} (${chalk9.green(`+${result.improvement}`)})`);
2656
- if (result.itemsRemoved) console.log(` Removed: ${result.itemsRemoved} items`);
2657
- if (result.itemsConsolidated) console.log(` Consolidated: ${result.itemsConsolidated} items`);
2658
- if (result.itemsAdded) console.log(` Added: ${result.itemsAdded} items`);
2659
- console.log("");
2660
- } catch (err) {
2661
- fixSpinner.fail("Fix execution failed");
2662
- throw err;
2663
- }
2664
- }
2665
- }
2666
- var CATEGORY_DESCRIPTIONS = {
2667
- tooling: "build/test/lint commands (helps agents the most)",
2668
- essential: "constraints agents can't discover from code",
2669
- convention: "style/naming rules (linters handle this; low value)",
2670
- overview: "project summaries (agents discover this by reading code)",
2671
- workflow: "development workflows and processes"
2672
- };
2673
- function printReport(report) {
2674
- const gradeColors = {
2675
- A: chalk9.green,
2676
- B: chalk9.blue,
2677
- C: chalk9.yellow,
2678
- D: chalk9.hex("#FFA500"),
2679
- F: chalk9.red
2680
- };
2681
- const gradeColor = gradeColors[report.grade] || chalk9.white;
2682
- console.log(chalk9.bold("\n Context Health Report\n"));
2683
- console.log(` Grade: ${gradeColor(report.grade)} Score: ${gradeColor(String(report.score))}/100
2684
- `);
2685
- const categories = Object.entries(report.category_breakdown);
2686
- if (categories.length) {
2687
- console.log(chalk9.bold(" Category Breakdown:\n"));
2688
- const itemsByCategory = /* @__PURE__ */ new Map();
2689
- if (report.item_classifications) {
2690
- for (const item of report.item_classifications) {
2691
- const cat = item.category.toLowerCase();
2692
- if (!itemsByCategory.has(cat)) itemsByCategory.set(cat, []);
2693
- itemsByCategory.get(cat).push(item);
2694
- }
2695
- }
2696
- for (const [name, data] of categories) {
2697
- const desc = CATEGORY_DESCRIPTIONS[name] || "";
2698
- const header = desc ? `${chalk9.bold(name)} ${chalk9.dim(`\u2014 ${desc}`)}` : chalk9.bold(name);
2699
- console.log(` ${header}`);
2700
- const items = itemsByCategory.get(name);
2701
- if (items?.length) {
2702
- for (const item of items) {
2703
- const icon = item.impactScore >= 0 ? chalk9.green("\u2713") : chalk9.red("\u2717");
2704
- const snippet = item.recommendation.length > 70 ? item.recommendation.slice(0, 67) + "..." : item.recommendation;
2705
- console.log(` ${icon} ${item.itemName.padEnd(22)} ${chalk9.dim(`"${snippet}"`)}`);
2706
- }
2707
- }
2708
- console.log(chalk9.dim(` ${data.count} items \xB7 ${data.tokens} tokens
2709
- `));
2710
- }
2711
- }
2712
- if (report.recommendations.length) {
2713
- console.log(chalk9.bold(" Recommendations:\n"));
2714
- for (const rec of report.recommendations) {
2715
- const icon = rec.priority === "high" ? chalk9.red("!") : rec.priority === "medium" ? chalk9.yellow("~") : chalk9.dim("-");
2716
- console.log(` ${icon} ${rec.description}`);
2717
- if (rec.reasoning) {
2718
- console.log(chalk9.dim(` ${rec.reasoning}`));
2719
- }
2720
- console.log("");
2721
- }
2722
- }
2723
- }
2724
-
2725
- // src/commands/sync.ts
2726
- import chalk10 from "chalk";
2727
- import ora7 from "ora";
2728
- async function syncCommand(options) {
2729
- const auth2 = getStoredAuth();
2730
- if (!auth2) {
2731
- console.log(chalk10.red("Not authenticated. Run `caliber login` first."));
2732
- throw new Error("__exit__");
2733
- }
2734
- const fingerprint = collectFingerprint(process.cwd());
2735
- const hash = computeFingerprintHash(fingerprint);
2736
- const match = await apiRequest(
2737
- "/api/projects/match",
2738
- { method: "POST", body: { fingerprintHash: hash } }
2739
- );
2740
- if (!match?.project) {
2741
- console.log(chalk10.yellow("No project found. Run `caliber init` first."));
2742
- throw new Error("__exit__");
2743
- }
2744
- const projectId = match.project.id;
2745
- const spinner = ora7("Scanning local state...").start();
2588
+ const spinner = ora6("Scanning local state...").start();
2746
2589
  const localItems = scanLocalState(process.cwd());
2747
2590
  spinner.text = "Fetching server items...";
2748
2591
  const serverItems = await apiRequest(
@@ -2750,7 +2593,7 @@ async function syncCommand(options) {
2750
2593
  );
2751
2594
  spinner.succeed(`Found ${localItems.length} local items, ${serverItems?.length || 0} server items`);
2752
2595
  if (!serverItems?.length) {
2753
- console.log(chalk10.dim("\nNo items configured on server. Run `caliber init` to set up your project.\n"));
2596
+ console.log(chalk9.dim("\nNo items configured on server. Run `caliber init` to set up your project.\n"));
2754
2597
  return;
2755
2598
  }
2756
2599
  const platformFilter = options.platform;
@@ -2759,15 +2602,15 @@ async function syncCommand(options) {
2759
2602
  const diff = compareState(filteredServer, filteredLocal);
2760
2603
  printDiff(diff);
2761
2604
  if (diff.missing.length === 0 && diff.outdated.length === 0) {
2762
- console.log(chalk10.green("\nAll items synced.\n"));
2605
+ console.log(chalk9.green("\nAll items synced.\n"));
2763
2606
  await reportToServer(projectId, filteredServer, diff);
2764
2607
  return;
2765
2608
  }
2766
2609
  if (options.dryRun) {
2767
- console.log(chalk10.dim("\nDry run \u2014 no changes made.\n"));
2610
+ console.log(chalk9.dim("\nDry run \u2014 no changes made.\n"));
2768
2611
  return;
2769
2612
  }
2770
- const installSpinner = ora7("Installing missing and outdated items...").start();
2613
+ const installSpinner = ora6("Installing missing and outdated items...").start();
2771
2614
  try {
2772
2615
  const setup = buildSetupFromItems([...diff.missing, ...diff.outdated.map((o) => o.server)]);
2773
2616
  if (setup) {
@@ -2820,26 +2663,26 @@ async function reportToServer(projectId, serverItems, diff) {
2820
2663
  }
2821
2664
  }
2822
2665
  function printDiff(diff) {
2823
- console.log(chalk10.bold("\n Sync Status\n"));
2666
+ console.log(chalk9.bold("\n Sync Status\n"));
2824
2667
  if (diff.installed.length) {
2825
- console.log(` ${chalk10.green("\u2713")} Installed: ${diff.installed.length}`);
2668
+ console.log(` ${chalk9.green("\u2713")} Installed: ${diff.installed.length}`);
2826
2669
  }
2827
2670
  if (diff.missing.length) {
2828
- console.log(` ${chalk10.red("\u2717")} Missing: ${diff.missing.length}`);
2671
+ console.log(` ${chalk9.red("\u2717")} Missing: ${diff.missing.length}`);
2829
2672
  for (const item of diff.missing) {
2830
- console.log(` ${chalk10.red("-")} ${item.name} (${item.type}/${item.platform})`);
2673
+ console.log(` ${chalk9.red("-")} ${item.name} (${item.type}/${item.platform})`);
2831
2674
  }
2832
2675
  }
2833
2676
  if (diff.outdated.length) {
2834
- console.log(` ${chalk10.yellow("~")} Outdated: ${diff.outdated.length}`);
2677
+ console.log(` ${chalk9.yellow("~")} Outdated: ${diff.outdated.length}`);
2835
2678
  for (const item of diff.outdated) {
2836
- console.log(` ${chalk10.yellow("~")} ${item.server.name} (${item.server.type}/${item.server.platform})`);
2679
+ console.log(` ${chalk9.yellow("~")} ${item.server.name} (${item.server.type}/${item.server.platform})`);
2837
2680
  }
2838
2681
  }
2839
2682
  if (diff.extra.length) {
2840
- console.log(` ${chalk10.dim("+")} Extra (local only): ${diff.extra.length}`);
2683
+ console.log(` ${chalk9.dim("+")} Extra (local only): ${diff.extra.length}`);
2841
2684
  for (const item of diff.extra) {
2842
- console.log(` ${chalk10.dim("+")} ${item.name} (${item.type}/${item.platform})`);
2685
+ console.log(` ${chalk9.dim("+")} ${item.name} (${item.type}/${item.platform})`);
2843
2686
  }
2844
2687
  }
2845
2688
  console.log("");
@@ -2900,12 +2743,12 @@ function buildSetupFromItems(items) {
2900
2743
  }
2901
2744
 
2902
2745
  // src/commands/diff.ts
2903
- import chalk11 from "chalk";
2904
- import ora8 from "ora";
2746
+ import chalk10 from "chalk";
2747
+ import ora7 from "ora";
2905
2748
  async function diffCommand(options) {
2906
2749
  const auth2 = getStoredAuth();
2907
2750
  if (!auth2) {
2908
- console.log(chalk11.red("Not authenticated. Run `caliber login` first."));
2751
+ console.log(chalk10.red("Not authenticated. Run `caliber login` first."));
2909
2752
  throw new Error("__exit__");
2910
2753
  }
2911
2754
  const fingerprint = collectFingerprint(process.cwd());
@@ -2915,58 +2758,58 @@ async function diffCommand(options) {
2915
2758
  { method: "POST", body: { fingerprintHash: hash } }
2916
2759
  );
2917
2760
  if (!match?.project) {
2918
- console.log(chalk11.yellow("No project found. Run `caliber init` first."));
2761
+ console.log(chalk10.yellow("No project found. Run `caliber init` first."));
2919
2762
  throw new Error("__exit__");
2920
2763
  }
2921
2764
  const projectId = match.project.id;
2922
- const spinner = ora8("Comparing local and server state...").start();
2765
+ const spinner = ora7("Comparing local and server state...").start();
2923
2766
  const localItems = scanLocalState(process.cwd());
2924
2767
  const serverItems = await apiRequest(
2925
2768
  `/api/sync/project/${projectId}/items`
2926
2769
  );
2927
2770
  spinner.stop();
2928
2771
  if (!serverItems?.length) {
2929
- console.log(chalk11.dim("\nNo items configured on server.\n"));
2772
+ console.log(chalk10.dim("\nNo items configured on server.\n"));
2930
2773
  return;
2931
2774
  }
2932
2775
  const platformFilter = options.platform;
2933
2776
  const filteredServer = platformFilter ? serverItems.filter((i) => i.platform === platformFilter || i.platform === "both") : serverItems;
2934
2777
  const filteredLocal = platformFilter ? localItems.filter((i) => i.platform === platformFilter) : localItems;
2935
2778
  const diff = compareState(filteredServer, filteredLocal);
2936
- console.log(chalk11.bold("\n Config Diff\n"));
2779
+ console.log(chalk10.bold("\n Config Diff\n"));
2937
2780
  if (diff.installed.length) {
2938
- console.log(` ${chalk11.green("\u2713")} In sync: ${diff.installed.length}`);
2781
+ console.log(` ${chalk10.green("\u2713")} In sync: ${diff.installed.length}`);
2939
2782
  }
2940
2783
  if (diff.missing.length) {
2941
- console.log(` ${chalk11.red("\u2717")} Missing locally: ${diff.missing.length}`);
2784
+ console.log(` ${chalk10.red("\u2717")} Missing locally: ${diff.missing.length}`);
2942
2785
  for (const item of diff.missing) {
2943
- console.log(` ${chalk11.red("-")} ${item.name} (${item.type}/${item.platform})`);
2786
+ console.log(` ${chalk10.red("-")} ${item.name} (${item.type}/${item.platform})`);
2944
2787
  }
2945
2788
  }
2946
2789
  if (diff.outdated.length) {
2947
- console.log(` ${chalk11.yellow("~")} Outdated: ${diff.outdated.length}`);
2790
+ console.log(` ${chalk10.yellow("~")} Outdated: ${diff.outdated.length}`);
2948
2791
  for (const item of diff.outdated) {
2949
- console.log(` ${chalk11.yellow("~")} ${item.server.name} (${item.server.type}/${item.server.platform})`);
2792
+ console.log(` ${chalk10.yellow("~")} ${item.server.name} (${item.server.type}/${item.server.platform})`);
2950
2793
  }
2951
2794
  }
2952
2795
  if (diff.extra.length) {
2953
- console.log(` ${chalk11.dim("+")} Local only: ${diff.extra.length}`);
2796
+ console.log(` ${chalk10.dim("+")} Local only: ${diff.extra.length}`);
2954
2797
  for (const item of diff.extra) {
2955
- console.log(` ${chalk11.dim("+")} ${item.name} (${item.type}/${item.platform})`);
2798
+ console.log(` ${chalk10.dim("+")} ${item.name} (${item.type}/${item.platform})`);
2956
2799
  }
2957
2800
  }
2958
2801
  if (diff.missing.length === 0 && diff.outdated.length === 0) {
2959
- console.log(chalk11.green("\n Everything is in sync.\n"));
2802
+ console.log(chalk10.green("\n Everything is in sync.\n"));
2960
2803
  } else {
2961
- console.log(chalk11.dim("\n Run `caliber sync` to apply changes.\n"));
2804
+ console.log(chalk10.dim("\n Run `caliber sync` to apply changes.\n"));
2962
2805
  }
2963
2806
  }
2964
2807
 
2965
2808
  // src/commands/refresh.ts
2966
2809
  import fs19 from "fs";
2967
2810
  import path16 from "path";
2968
- import chalk12 from "chalk";
2969
- import ora9 from "ora";
2811
+ import chalk11 from "chalk";
2812
+ import ora8 from "ora";
2970
2813
 
2971
2814
  // src/lib/git-diff.ts
2972
2815
  import { execSync as execSync3 } from "child_process";
@@ -3099,7 +2942,7 @@ function discoverGitRepos(parentDir) {
3099
2942
  }
3100
2943
  async function refreshSingleRepo(repoDir, options) {
3101
2944
  const quiet = !!options.quiet;
3102
- const prefix = options.label ? `${chalk12.bold(options.label)} ` : "";
2945
+ const prefix = options.label ? `${chalk11.bold(options.label)} ` : "";
3103
2946
  const state = readState();
3104
2947
  const lastSha = state?.lastRefreshSha ?? null;
3105
2948
  const diff = collectDiff(lastSha);
@@ -3108,10 +2951,10 @@ async function refreshSingleRepo(repoDir, options) {
3108
2951
  if (currentSha) {
3109
2952
  writeState({ lastRefreshSha: currentSha, lastRefreshTimestamp: (/* @__PURE__ */ new Date()).toISOString() });
3110
2953
  }
3111
- log(quiet, chalk12.dim(`${prefix}No changes since last refresh.`));
2954
+ log(quiet, chalk11.dim(`${prefix}No changes since last refresh.`));
3112
2955
  return;
3113
2956
  }
3114
- const spinner = quiet ? null : ora9(`${prefix}Analyzing changes...`).start();
2957
+ const spinner = quiet ? null : ora8(`${prefix}Analyzing changes...`).start();
3115
2958
  const existingDocs = readExistingConfigs(repoDir);
3116
2959
  const fingerprint = collectFingerprint(repoDir);
3117
2960
  const projectContext = {
@@ -3143,10 +2986,10 @@ async function refreshSingleRepo(repoDir, options) {
3143
2986
  if (options.dryRun) {
3144
2987
  spinner?.info(`${prefix}Dry run \u2014 would update:`);
3145
2988
  for (const doc of response.docsUpdated) {
3146
- console.log(` ${chalk12.yellow("~")} ${doc}`);
2989
+ console.log(` ${chalk11.yellow("~")} ${doc}`);
3147
2990
  }
3148
2991
  if (response.changesSummary) {
3149
- console.log(chalk12.dim(`
2992
+ console.log(chalk11.dim(`
3150
2993
  ${response.changesSummary}`));
3151
2994
  }
3152
2995
  return;
@@ -3154,10 +2997,10 @@ async function refreshSingleRepo(repoDir, options) {
3154
2997
  const written = writeRefreshDocs(response.updatedDocs);
3155
2998
  spinner?.succeed(`${prefix}Updated ${written.length} doc${written.length === 1 ? "" : "s"}`);
3156
2999
  for (const file of written) {
3157
- log(quiet, ` ${chalk12.green("\u2713")} ${file}`);
3000
+ log(quiet, ` ${chalk11.green("\u2713")} ${file}`);
3158
3001
  }
3159
3002
  if (response.changesSummary) {
3160
- log(quiet, chalk12.dim(`
3003
+ log(quiet, chalk11.dim(`
3161
3004
  ${response.changesSummary}`));
3162
3005
  }
3163
3006
  if (currentSha) {
@@ -3174,7 +3017,7 @@ async function refreshCommand(options) {
3174
3017
  const auth2 = getStoredAuth();
3175
3018
  if (!auth2) {
3176
3019
  if (quiet) return;
3177
- console.log(chalk12.red("Not authenticated. Run `caliber login` first."));
3020
+ console.log(chalk11.red("Not authenticated. Run `caliber login` first."));
3178
3021
  throw new Error("__exit__");
3179
3022
  }
3180
3023
  if (isGitRepo()) {
@@ -3184,10 +3027,10 @@ async function refreshCommand(options) {
3184
3027
  const repos = discoverGitRepos(process.cwd());
3185
3028
  if (repos.length === 0) {
3186
3029
  if (quiet) return;
3187
- console.log(chalk12.red("Not inside a git repository and no git repos found in child directories."));
3030
+ console.log(chalk11.red("Not inside a git repository and no git repos found in child directories."));
3188
3031
  throw new Error("__exit__");
3189
3032
  }
3190
- log(quiet, chalk12.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
3033
+ log(quiet, chalk11.dim(`Found ${repos.length} git repo${repos.length === 1 ? "" : "s"}
3191
3034
  `));
3192
3035
  const originalDir = process.cwd();
3193
3036
  for (const repo of repos) {
@@ -3197,7 +3040,7 @@ async function refreshCommand(options) {
3197
3040
  await refreshSingleRepo(repo, { ...options, label: repoName });
3198
3041
  } catch (err) {
3199
3042
  if (err instanceof Error && err.message === "__exit__") continue;
3200
- log(quiet, chalk12.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
3043
+ log(quiet, chalk11.yellow(`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`));
3201
3044
  }
3202
3045
  }
3203
3046
  process.chdir(originalDir);
@@ -3205,46 +3048,46 @@ async function refreshCommand(options) {
3205
3048
  if (err instanceof Error && err.message === "__exit__") throw err;
3206
3049
  if (quiet) return;
3207
3050
  const msg = err instanceof Error ? err.message : "Unknown error";
3208
- console.log(chalk12.red(`Refresh failed: ${msg}`));
3051
+ console.log(chalk11.red(`Refresh failed: ${msg}`));
3209
3052
  throw new Error("__exit__");
3210
3053
  }
3211
3054
  }
3212
3055
 
3213
3056
  // src/commands/hooks.ts
3214
- import chalk13 from "chalk";
3057
+ import chalk12 from "chalk";
3215
3058
  async function hooksInstallCommand() {
3216
3059
  const result = installHook();
3217
3060
  if (result.alreadyInstalled) {
3218
- console.log(chalk13.dim("Hook already installed."));
3061
+ console.log(chalk12.dim("Hook already installed."));
3219
3062
  return;
3220
3063
  }
3221
- console.log(chalk13.green("\u2713") + " SessionEnd hook installed in .claude/settings.json");
3222
- console.log(chalk13.dim(" Docs will auto-refresh when Claude Code sessions end."));
3064
+ console.log(chalk12.green("\u2713") + " SessionEnd hook installed in .claude/settings.json");
3065
+ console.log(chalk12.dim(" Docs will auto-refresh when Claude Code sessions end."));
3223
3066
  }
3224
3067
  async function hooksRemoveCommand() {
3225
3068
  const result = removeHook();
3226
3069
  if (result.notFound) {
3227
- console.log(chalk13.dim("Hook not found."));
3070
+ console.log(chalk12.dim("Hook not found."));
3228
3071
  return;
3229
3072
  }
3230
- console.log(chalk13.green("\u2713") + " SessionEnd hook removed from .claude/settings.json");
3073
+ console.log(chalk12.green("\u2713") + " SessionEnd hook removed from .claude/settings.json");
3231
3074
  }
3232
3075
  async function hooksStatusCommand() {
3233
3076
  const installed = isHookInstalled();
3234
3077
  if (installed) {
3235
- console.log(chalk13.green("\u2713") + " Auto-refresh hook is " + chalk13.green("installed"));
3078
+ console.log(chalk12.green("\u2713") + " Auto-refresh hook is " + chalk12.green("installed"));
3236
3079
  } else {
3237
- console.log(chalk13.dim("\u2717") + " Auto-refresh hook is " + chalk13.yellow("not installed"));
3238
- console.log(chalk13.dim(" Run `caliber hooks install` to enable auto-refresh on session end."));
3080
+ console.log(chalk12.dim("\u2717") + " Auto-refresh hook is " + chalk12.yellow("not installed"));
3081
+ console.log(chalk12.dim(" Run `caliber hooks install` to enable auto-refresh on session end."));
3239
3082
  }
3240
3083
  }
3241
3084
 
3242
3085
  // src/commands/review.ts
3243
- import chalk14 from "chalk";
3086
+ import chalk13 from "chalk";
3244
3087
  import readline2 from "readline";
3245
- import ora10 from "ora";
3088
+ import ora9 from "ora";
3246
3089
  import select2 from "@inquirer/select";
3247
- import confirm3 from "@inquirer/confirm";
3090
+ import confirm2 from "@inquirer/confirm";
3248
3091
  function prompt(question) {
3249
3092
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
3250
3093
  return new Promise((resolve2) => {
@@ -3280,12 +3123,12 @@ function starRating(rating) {
3280
3123
  return "\u2605".repeat(rating) + "\u2606".repeat(5 - rating);
3281
3124
  }
3282
3125
  async function submitReview(body) {
3283
- const spinner = ora10("Submitting review...").start();
3126
+ const spinner = ora9("Submitting review...").start();
3284
3127
  try {
3285
3128
  await apiRequest("/api/reviews", { method: "POST", body });
3286
3129
  spinner.succeed("Review submitted");
3287
3130
  trackEvent("review_submitted", { rating: body.rating, would_recommend: body.wouldRecommend });
3288
- console.log(chalk14.green.bold("\n Thank you for your feedback!\n"));
3131
+ console.log(chalk13.green.bold("\n Thank you for your feedback!\n"));
3289
3132
  } catch (err) {
3290
3133
  const msg = err instanceof Error ? err.message : "Unknown error";
3291
3134
  spinner.fail(`Failed to submit review: ${msg}`);
@@ -3296,37 +3139,37 @@ async function submitReview(body) {
3296
3139
  async function reviewCommand(message, options) {
3297
3140
  const auth2 = getStoredAuth();
3298
3141
  if (!auth2) {
3299
- console.log(chalk14.red("\n Not authenticated. Run `caliber login` first.\n"));
3142
+ console.log(chalk13.red("\n Not authenticated. Run `caliber login` first.\n"));
3300
3143
  throw new Error("__exit__");
3301
3144
  }
3302
3145
  if (message) {
3303
3146
  const rating2 = options.rating ? parseInt(options.rating, 10) : 5;
3304
3147
  if (rating2 < 1 || rating2 > 5 || isNaN(rating2)) {
3305
- console.log(chalk14.red("Rating must be between 1 and 5."));
3148
+ console.log(chalk13.red("Rating must be between 1 and 5."));
3306
3149
  throw new Error("__exit__");
3307
3150
  }
3308
- console.log(chalk14.dim(`
3151
+ console.log(chalk13.dim(`
3309
3152
  ${starRating(rating2)} "${message}"
3310
3153
  `));
3311
3154
  await submitReview({ rating: rating2, bestPart: message, biggestGap: "", wouldRecommend: "yes" });
3312
3155
  return;
3313
3156
  }
3314
- console.log(chalk14.hex("#6366f1").bold("\n Share your feedback\n"));
3315
- console.log(chalk14.dim(" We'd love to hear how Caliber is working for you."));
3316
- console.log(chalk14.dim(" This takes under 2 minutes.\n"));
3317
- console.log(chalk14.dim(' Tip: use `caliber review "your feedback"` for a quick review.\n'));
3157
+ console.log(chalk13.hex("#6366f1").bold("\n Share your feedback\n"));
3158
+ console.log(chalk13.dim(" We'd love to hear how Caliber is working for you."));
3159
+ console.log(chalk13.dim(" This takes under 2 minutes.\n"));
3160
+ console.log(chalk13.dim(' Tip: use `caliber review "your feedback"` for a quick review.\n'));
3318
3161
  const rating = await promptRating();
3319
- const bestPart = await prompt(chalk14.cyan("\n What did you find most useful? "));
3320
- const biggestGap = await prompt(chalk14.cyan("\n What was missing or could be better? "));
3162
+ const bestPart = await prompt(chalk13.cyan("\n What did you find most useful? "));
3163
+ const biggestGap = await prompt(chalk13.cyan("\n What was missing or could be better? "));
3321
3164
  const wouldRecommend = await promptRecommend();
3322
- console.log(chalk14.bold("\n Your review:\n"));
3165
+ console.log(chalk13.bold("\n Your review:\n"));
3323
3166
  console.log(` Rating: ${starRating(rating)} (${rating}/5)`);
3324
- console.log(` Most useful: ${bestPart || chalk14.dim("(skipped)")}`);
3325
- console.log(` Could be better: ${biggestGap || chalk14.dim("(skipped)")}`);
3167
+ console.log(` Most useful: ${bestPart || chalk13.dim("(skipped)")}`);
3168
+ console.log(` Could be better: ${biggestGap || chalk13.dim("(skipped)")}`);
3326
3169
  console.log(` Would recommend: ${wouldRecommend}`);
3327
- const shouldSubmit = await confirm3({ message: "Submit this review?", default: true });
3170
+ const shouldSubmit = await confirm2({ message: "Submit this review?", default: true });
3328
3171
  if (!shouldSubmit) {
3329
- console.log(chalk14.dim("\n Review cancelled.\n"));
3172
+ console.log(chalk13.dim("\n Review cancelled.\n"));
3330
3173
  return;
3331
3174
  }
3332
3175
  await submitReview({ rating, bestPart, biggestGap, wouldRecommend });
@@ -3347,7 +3190,6 @@ program.command("regenerate").alias("regen").alias("re").alias("update").descrip
3347
3190
  program.command("login").description("Authenticate with Caliber").action(loginCommand);
3348
3191
  program.command("logout").description("Clear stored credentials").action(logoutCommand);
3349
3192
  program.command("recommend").description("Discover and manage skill recommendations").option("--generate", "Force fresh recommendation generation").option("--status <status>", "View recommendations by status: pending, accepted, dismissed").action(recommendCommand);
3350
- program.command("health").description("Analyze context health and quality").option("--fix", "Generate and execute a fix plan").option("--json", "Output as JSON").action(healthCommand);
3351
3193
  program.command("sync").description("Sync local config with server state").option("--platform <platform>", "Target platform: claude, cursor, or both").option("--dry-run", "Preview changes without writing files").action(syncCommand);
3352
3194
  program.command("diff").description("Compare local config with server state").option("--platform <platform>", "Target platform: claude, cursor, or both").action(diffCommand);
3353
3195
  program.command("refresh").description("Update docs based on recent code changes").option("--quiet", "Suppress output (for use in hooks)").option("--dry-run", "Preview changes without writing files").action(refreshCommand);
@@ -3362,9 +3204,9 @@ import fs21 from "fs";
3362
3204
  import path18 from "path";
3363
3205
  import { fileURLToPath as fileURLToPath4 } from "url";
3364
3206
  import { execSync as execSync4 } from "child_process";
3365
- import chalk15 from "chalk";
3366
- import ora11 from "ora";
3367
- import confirm4 from "@inquirer/confirm";
3207
+ import chalk14 from "chalk";
3208
+ import ora10 from "ora";
3209
+ import confirm3 from "@inquirer/confirm";
3368
3210
  var __dirname_vc = path18.dirname(fileURLToPath4(import.meta.url));
3369
3211
  var pkg4 = JSON.parse(
3370
3212
  fs21.readFileSync(path18.resolve(__dirname_vc, "..", "package.json"), "utf-8")
@@ -3396,37 +3238,37 @@ async function checkForUpdates() {
3396
3238
  const isInteractive = process.stdin.isTTY === true;
3397
3239
  if (!isInteractive) {
3398
3240
  console.log(
3399
- chalk15.yellow(
3241
+ chalk14.yellow(
3400
3242
  `
3401
3243
  Update available: ${current} -> ${latest}
3402
- Run ${chalk15.bold("npm install -g @caliber-ai/cli")} to upgrade.
3244
+ Run ${chalk14.bold("npm install -g @caliber-ai/cli")} to upgrade.
3403
3245
  `
3404
3246
  )
3405
3247
  );
3406
3248
  return;
3407
3249
  }
3408
3250
  console.log(
3409
- chalk15.yellow(`
3251
+ chalk14.yellow(`
3410
3252
  Update available: ${current} -> ${latest}`)
3411
3253
  );
3412
- const shouldUpdate = await confirm4({ message: "Would you like to update now? (Y/n)", default: true });
3254
+ const shouldUpdate = await confirm3({ message: "Would you like to update now? (Y/n)", default: true });
3413
3255
  if (!shouldUpdate) {
3414
3256
  console.log();
3415
3257
  return;
3416
3258
  }
3417
- const spinner = ora11("Updating @caliber-ai/cli...").start();
3259
+ const spinner = ora10("Updating @caliber-ai/cli...").start();
3418
3260
  try {
3419
3261
  execSync4(`npm install -g @caliber-ai/cli@${latest} --prefer-online`, { stdio: "pipe", timeout: 6e4 });
3420
3262
  const installed = getInstalledVersion();
3421
3263
  if (installed !== latest) {
3422
3264
  spinner.fail(`Update incomplete \u2014 got ${installed ?? "unknown"}, expected ${latest}`);
3423
- console.log(chalk15.yellow(`Run ${chalk15.bold(`npm install -g @caliber-ai/cli@${latest}`)} manually.
3265
+ console.log(chalk14.yellow(`Run ${chalk14.bold(`npm install -g @caliber-ai/cli@${latest}`)} manually.
3424
3266
  `));
3425
3267
  return;
3426
3268
  }
3427
- spinner.succeed(chalk15.green(`Updated to ${latest}`));
3269
+ spinner.succeed(chalk14.green(`Updated to ${latest}`));
3428
3270
  const args = process.argv.slice(2);
3429
- console.log(chalk15.dim(`
3271
+ console.log(chalk14.dim(`
3430
3272
  Restarting: caliber ${args.join(" ")}
3431
3273
  `));
3432
3274
  execSync4(`caliber ${args.map((a) => JSON.stringify(a)).join(" ")}`, {
@@ -3437,10 +3279,10 @@ Restarting: caliber ${args.join(" ")}
3437
3279
  } catch (err) {
3438
3280
  spinner.fail("Update failed");
3439
3281
  const msg = err instanceof Error ? err.message : "";
3440
- if (msg && !msg.includes("SIGTERM")) console.log(chalk15.dim(` ${msg.split("\n")[0]}`));
3282
+ if (msg && !msg.includes("SIGTERM")) console.log(chalk14.dim(` ${msg.split("\n")[0]}`));
3441
3283
  console.log(
3442
- chalk15.yellow(
3443
- `Run ${chalk15.bold(`npm install -g @caliber-ai/cli@${latest}`)} manually to upgrade.
3284
+ chalk14.yellow(
3285
+ `Run ${chalk14.bold(`npm install -g @caliber-ai/cli@${latest}`)} manually to upgrade.
3444
3286
  `
3445
3287
  )
3446
3288
  );