@rely-ai/caliber 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +209 -135
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -51,8 +51,8 @@ var init_constants = __esm({
51
51
 
52
52
  // src/cli.ts
53
53
  import { Command } from "commander";
54
- import fs24 from "fs";
55
- import path21 from "path";
54
+ import fs25 from "fs";
55
+ import path22 from "path";
56
56
  import { fileURLToPath } from "url";
57
57
 
58
58
  // src/commands/onboard.ts
@@ -60,7 +60,7 @@ import chalk4 from "chalk";
60
60
  import ora from "ora";
61
61
  import readline3 from "readline";
62
62
  import select2 from "@inquirer/select";
63
- import fs17 from "fs";
63
+ import fs18 from "fs";
64
64
 
65
65
  // src/fingerprint/index.ts
66
66
  import fs7 from "fs";
@@ -2127,16 +2127,25 @@ import path12 from "path";
2127
2127
  var STAGED_DIR = path12.join(CALIBER_DIR, "staged");
2128
2128
  var PROPOSED_DIR = path12.join(STAGED_DIR, "proposed");
2129
2129
  var CURRENT_DIR = path12.join(STAGED_DIR, "current");
2130
+ function normalizeContent(content) {
2131
+ return content.split("\n").map((line) => line.trimEnd()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
2132
+ }
2130
2133
  function stageFiles(files, projectDir) {
2131
2134
  cleanupStaging();
2132
2135
  let newFiles = 0;
2133
2136
  let modifiedFiles = 0;
2134
2137
  const stagedFiles = [];
2135
2138
  for (const file of files) {
2139
+ const originalPath = path12.join(projectDir, file.path);
2140
+ if (fs13.existsSync(originalPath)) {
2141
+ const existing = fs13.readFileSync(originalPath, "utf-8");
2142
+ if (normalizeContent(existing) === normalizeContent(file.content)) {
2143
+ continue;
2144
+ }
2145
+ }
2136
2146
  const proposedPath = path12.join(PROPOSED_DIR, file.path);
2137
2147
  fs13.mkdirSync(path12.dirname(proposedPath), { recursive: true });
2138
2148
  fs13.writeFileSync(proposedPath, file.content);
2139
- const originalPath = path12.join(projectDir, file.path);
2140
2149
  if (fs13.existsSync(originalPath)) {
2141
2150
  const currentPath = path12.join(CURRENT_DIR, file.path);
2142
2151
  fs13.mkdirSync(path12.dirname(currentPath), { recursive: true });
@@ -2715,15 +2724,15 @@ function computeGrade(score) {
2715
2724
  // src/scoring/checks/coverage.ts
2716
2725
  import { readFileSync, readdirSync } from "fs";
2717
2726
  import { join } from "path";
2718
- function readFileOrNull(path23) {
2727
+ function readFileOrNull(path24) {
2719
2728
  try {
2720
- return readFileSync(path23, "utf-8");
2729
+ return readFileSync(path24, "utf-8");
2721
2730
  } catch {
2722
2731
  return null;
2723
2732
  }
2724
2733
  }
2725
- function readJsonOrNull(path23) {
2726
- const content = readFileOrNull(path23);
2734
+ function readJsonOrNull(path24) {
2735
+ const content = readFileOrNull(path24);
2727
2736
  if (!content) return null;
2728
2737
  try {
2729
2738
  return JSON.parse(content);
@@ -3079,9 +3088,9 @@ function checkExistence(dir) {
3079
3088
  // src/scoring/checks/quality.ts
3080
3089
  import { readFileSync as readFileSync3 } from "fs";
3081
3090
  import { join as join3 } from "path";
3082
- function readFileOrNull2(path23) {
3091
+ function readFileOrNull2(path24) {
3083
3092
  try {
3084
- return readFileSync3(path23, "utf-8");
3093
+ return readFileSync3(path24, "utf-8");
3085
3094
  } catch {
3086
3095
  return null;
3087
3096
  }
@@ -3232,15 +3241,15 @@ function checkQuality(dir) {
3232
3241
  // src/scoring/checks/accuracy.ts
3233
3242
  import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
3234
3243
  import { join as join4 } from "path";
3235
- function readFileOrNull3(path23) {
3244
+ function readFileOrNull3(path24) {
3236
3245
  try {
3237
- return readFileSync4(path23, "utf-8");
3246
+ return readFileSync4(path24, "utf-8");
3238
3247
  } catch {
3239
3248
  return null;
3240
3249
  }
3241
3250
  }
3242
- function readJsonOrNull2(path23) {
3243
- const content = readFileOrNull3(path23);
3251
+ function readJsonOrNull2(path24) {
3252
+ const content = readFileOrNull3(path24);
3244
3253
  if (!content) return null;
3245
3254
  try {
3246
3255
  return JSON.parse(content);
@@ -3423,9 +3432,9 @@ function checkAccuracy(dir) {
3423
3432
  // src/scoring/checks/freshness.ts
3424
3433
  import { readFileSync as readFileSync5, statSync as statSync2 } from "fs";
3425
3434
  import { join as join5 } from "path";
3426
- function readFileOrNull4(path23) {
3435
+ function readFileOrNull4(path24) {
3427
3436
  try {
3428
- return readFileSync5(path23, "utf-8");
3437
+ return readFileSync5(path24, "utf-8");
3429
3438
  } catch {
3430
3439
  return null;
3431
3440
  }
@@ -3535,9 +3544,9 @@ function checkFreshness(dir) {
3535
3544
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
3536
3545
  import { execSync as execSync7 } from "child_process";
3537
3546
  import { join as join6 } from "path";
3538
- function readFileOrNull5(path23) {
3547
+ function readFileOrNull5(path24) {
3539
3548
  try {
3540
- return readFileSync6(path23, "utf-8");
3549
+ return readFileSync6(path24, "utf-8");
3541
3550
  } catch {
3542
3551
  return null;
3543
3552
  }
@@ -3630,6 +3639,29 @@ function checkBonus(dir) {
3630
3639
  return checks;
3631
3640
  }
3632
3641
 
3642
+ // src/scoring/dismissed.ts
3643
+ init_constants();
3644
+ import fs17 from "fs";
3645
+ import path16 from "path";
3646
+ var DISMISSED_FILE = path16.join(CALIBER_DIR, "dismissed-checks.json");
3647
+ function readDismissedChecks() {
3648
+ try {
3649
+ if (!fs17.existsSync(DISMISSED_FILE)) return [];
3650
+ return JSON.parse(fs17.readFileSync(DISMISSED_FILE, "utf-8"));
3651
+ } catch {
3652
+ return [];
3653
+ }
3654
+ }
3655
+ function writeDismissedChecks(checks) {
3656
+ if (!fs17.existsSync(CALIBER_DIR)) {
3657
+ fs17.mkdirSync(CALIBER_DIR, { recursive: true });
3658
+ }
3659
+ fs17.writeFileSync(DISMISSED_FILE, JSON.stringify(checks, null, 2) + "\n");
3660
+ }
3661
+ function getDismissedIds() {
3662
+ return new Set(readDismissedChecks().map((c) => c.id));
3663
+ }
3664
+
3633
3665
  // src/scoring/index.ts
3634
3666
  function sumCategory(checks, category) {
3635
3667
  const categoryChecks = checks.filter((c) => c.category === category);
@@ -3666,7 +3698,8 @@ function computeLocalScore(dir, targetAgent) {
3666
3698
  ...checkFreshness(dir),
3667
3699
  ...checkBonus(dir)
3668
3700
  ];
3669
- const checks = filterChecksForTarget(allChecks, target);
3701
+ const dismissed = getDismissedIds();
3702
+ const checks = filterChecksForTarget(allChecks, target).filter((c) => !dismissed.has(c.id));
3670
3703
  const maxPossible = checks.reduce((s, c) => s + c.maxPoints, 0);
3671
3704
  const earned = checks.reduce((s, c) => s + c.earnedPoints, 0);
3672
3705
  const score = maxPossible > 0 ? Math.min(100, Math.max(0, Math.round(earned / maxPossible * 100))) : 0;
@@ -3772,7 +3805,7 @@ function displayScoreSummary(result) {
3772
3805
  const remaining = failing.length - shown.length;
3773
3806
  const moreText = remaining > 0 ? ` (+${remaining} more)` : "";
3774
3807
  console.log(chalk3.dim(`
3775
- Run ${chalk3.reset("caliber score")} for details.${moreText}`));
3808
+ Run ${chalk3.hex("#83D1EB")("caliber score")} for details.${moreText}`));
3776
3809
  }
3777
3810
  console.log("");
3778
3811
  }
@@ -3874,12 +3907,23 @@ async function initCommand(options) {
3874
3907
  console.log(chalk4.dim(` Files: ${fingerprint.fileTree.length} found
3875
3908
  `));
3876
3909
  const targetAgent = options.agent || await promptAgent();
3910
+ const preScore = computeLocalScore(process.cwd(), targetAgent);
3911
+ const failingForDismissal = preScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
3912
+ if (failingForDismissal.length > 0) {
3913
+ const newDismissals = await evaluateDismissals(failingForDismissal, fingerprint);
3914
+ if (newDismissals.length > 0) {
3915
+ const existing = readDismissedChecks();
3916
+ const existingIds = new Set(existing.map((d) => d.id));
3917
+ const merged = [...existing, ...newDismissals.filter((d) => !existingIds.has(d.id))];
3918
+ writeDismissedChecks(merged);
3919
+ }
3920
+ }
3877
3921
  const baselineScore = computeLocalScore(process.cwd(), targetAgent);
3878
3922
  displayScoreSummary(baselineScore);
3879
3923
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length);
3880
3924
  if (hasExistingConfig && baselineScore.score === 100) {
3881
3925
  console.log(chalk4.bold.green(" Your setup is already optimal \u2014 nothing to change.\n"));
3882
- console.log(chalk4.dim(" Run `caliber onboard --force` to regenerate anyway.\n"));
3926
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber onboard --force") + chalk4.dim(" to regenerate anyway.\n"));
3883
3927
  if (!options.force) return;
3884
3928
  }
3885
3929
  const isEmpty = fingerprint.fileTree.length < 3;
@@ -4042,14 +4086,14 @@ async function initCommand(options) {
4042
4086
  const hookResult = installHook();
4043
4087
  if (hookResult.installed) {
4044
4088
  console.log(` ${chalk4.green("\u2713")} Claude Code hook installed \u2014 docs update on session end`);
4045
- console.log(chalk4.dim(" Run `caliber hooks remove` to disable"));
4089
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber hooks remove") + chalk4.dim(" to disable"));
4046
4090
  } else if (hookResult.alreadyInstalled) {
4047
4091
  console.log(chalk4.dim(" Claude Code hook already installed"));
4048
4092
  }
4049
4093
  const learnResult = installLearningHooks();
4050
4094
  if (learnResult.installed) {
4051
4095
  console.log(` ${chalk4.green("\u2713")} Learning hooks installed \u2014 session insights captured automatically`);
4052
- console.log(chalk4.dim(" Run `caliber learn remove` to disable"));
4096
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber learn remove") + chalk4.dim(" to disable"));
4053
4097
  } else if (learnResult.alreadyInstalled) {
4054
4098
  console.log(chalk4.dim(" Learning hooks already installed"));
4055
4099
  }
@@ -4058,7 +4102,7 @@ async function initCommand(options) {
4058
4102
  const precommitResult = installPreCommitHook();
4059
4103
  if (precommitResult.installed) {
4060
4104
  console.log(` ${chalk4.green("\u2713")} Pre-commit hook installed \u2014 docs refresh before each commit`);
4061
- console.log(chalk4.dim(" Run `caliber hooks remove-precommit` to disable"));
4105
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber hooks remove-precommit") + chalk4.dim(" to disable"));
4062
4106
  } else if (precommitResult.alreadyInstalled) {
4063
4107
  console.log(chalk4.dim(" Pre-commit hook already installed"));
4064
4108
  } else {
@@ -4066,7 +4110,7 @@ async function initCommand(options) {
4066
4110
  }
4067
4111
  }
4068
4112
  if (hookChoice === "skip") {
4069
- console.log(chalk4.dim(" Skipped auto-refresh hooks. Run `caliber hooks install` later to enable."));
4113
+ console.log(chalk4.dim(" Skipped auto-refresh hooks. Run ") + chalk4.hex("#83D1EB")("caliber hooks install") + chalk4.dim(" later to enable."));
4070
4114
  }
4071
4115
  const afterScore = computeLocalScore(process.cwd(), targetAgent);
4072
4116
  if (afterScore.score < baselineScore.score) {
@@ -4079,12 +4123,12 @@ async function initCommand(options) {
4079
4123
  }
4080
4124
  } catch {
4081
4125
  }
4082
- console.log(chalk4.dim(" Run `caliber onboard --force` to override.\n"));
4126
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber onboard --force") + chalk4.dim(" to override.\n"));
4083
4127
  return;
4084
4128
  }
4085
4129
  displayScoreDelta(baselineScore, afterScore);
4086
4130
  console.log(chalk4.bold.green(" Onboarding complete! Your project is ready for AI-assisted development."));
4087
- console.log(chalk4.dim(" Run `caliber undo` to revert changes.\n"));
4131
+ console.log(chalk4.dim(" Run ") + chalk4.hex("#83D1EB")("caliber undo") + chalk4.dim(" to revert changes.\n"));
4088
4132
  console.log(chalk4.bold(" Next steps:\n"));
4089
4133
  console.log(` ${title("caliber score")} See your full config breakdown`);
4090
4134
  console.log(` ${title("caliber recommend")} Discover community skills for your stack`);
@@ -4134,7 +4178,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
4134
4178
  }
4135
4179
  function summarizeSetup(action, setup) {
4136
4180
  const descriptions = setup.fileDescriptions;
4137
- const files = descriptions ? Object.entries(descriptions).map(([path23, desc]) => ` ${path23}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
4181
+ const files = descriptions ? Object.entries(descriptions).map(([path24, desc]) => ` ${path24}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
4138
4182
  return `${action}. Files:
4139
4183
  ${files}`;
4140
4184
  }
@@ -4155,6 +4199,36 @@ Return {"valid": true} or {"valid": false}. Nothing else.`,
4155
4199
  return true;
4156
4200
  }
4157
4201
  }
4202
+ async function evaluateDismissals(failingChecks, fingerprint) {
4203
+ const fastModel = process.env.ANTHROPIC_SMALL_FAST_MODEL;
4204
+ const checkList = failingChecks.map((c) => ({
4205
+ id: c.id,
4206
+ name: c.name,
4207
+ suggestion: c.suggestion
4208
+ }));
4209
+ try {
4210
+ const result = await llmJsonCall({
4211
+ system: `You evaluate whether scoring checks are applicable to a project.
4212
+ Given the project's languages/frameworks and a list of failing checks, return which checks are NOT applicable.
4213
+
4214
+ Only dismiss checks that truly don't apply \u2014 e.g. "Build/test/lint commands" for a pure Terraform/HCL repo with no build system.
4215
+ Do NOT dismiss checks that could reasonably apply even if the project doesn't use them yet.
4216
+
4217
+ Return {"dismissed": [{"id": "check_id", "reason": "brief reason"}]} or {"dismissed": []} if all apply.`,
4218
+ prompt: `Languages: ${fingerprint.languages.join(", ") || "none"}
4219
+ Frameworks: ${fingerprint.frameworks.join(", ") || "none"}
4220
+
4221
+ Failing checks:
4222
+ ${JSON.stringify(checkList, null, 2)}`,
4223
+ maxTokens: 200,
4224
+ ...fastModel ? { model: fastModel } : {}
4225
+ });
4226
+ if (!Array.isArray(result.dismissed)) return [];
4227
+ return result.dismissed.filter((d) => d.id && d.reason && failingChecks.some((c) => c.id === d.id)).map((d) => ({ id: d.id, reason: d.reason, dismissedAt: (/* @__PURE__ */ new Date()).toISOString() }));
4228
+ } catch {
4229
+ return [];
4230
+ }
4231
+ }
4158
4232
  function promptInput2(question) {
4159
4233
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
4160
4234
  return new Promise((resolve2) => {
@@ -4224,8 +4298,8 @@ async function openReview(method, stagedFiles) {
4224
4298
  return;
4225
4299
  }
4226
4300
  const fileInfos = stagedFiles.map((file) => {
4227
- const proposed = fs17.readFileSync(file.proposedPath, "utf-8");
4228
- const current = file.currentPath ? fs17.readFileSync(file.currentPath, "utf-8") : "";
4301
+ const proposed = fs18.readFileSync(file.proposedPath, "utf-8");
4302
+ const current = file.currentPath ? fs18.readFileSync(file.currentPath, "utf-8") : "";
4229
4303
  const patch = createTwoFilesPatch(
4230
4304
  file.isNew ? "/dev/null" : file.relativePath,
4231
4305
  file.relativePath,
@@ -4408,7 +4482,7 @@ function printSetupSummary(setup) {
4408
4482
  };
4409
4483
  if (claude) {
4410
4484
  if (claude.claudeMd) {
4411
- const icon = fs17.existsSync("CLAUDE.md") ? chalk4.yellow("~") : chalk4.green("+");
4485
+ const icon = fs18.existsSync("CLAUDE.md") ? chalk4.yellow("~") : chalk4.green("+");
4412
4486
  const desc = getDescription("CLAUDE.md");
4413
4487
  console.log(` ${icon} ${chalk4.bold("CLAUDE.md")}`);
4414
4488
  if (desc) console.log(chalk4.dim(` ${desc}`));
@@ -4418,7 +4492,7 @@ function printSetupSummary(setup) {
4418
4492
  if (Array.isArray(skills) && skills.length > 0) {
4419
4493
  for (const skill of skills) {
4420
4494
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
4421
- const icon = fs17.existsSync(skillPath) ? chalk4.yellow("~") : chalk4.green("+");
4495
+ const icon = fs18.existsSync(skillPath) ? chalk4.yellow("~") : chalk4.green("+");
4422
4496
  const desc = getDescription(skillPath);
4423
4497
  console.log(` ${icon} ${chalk4.bold(skillPath)}`);
4424
4498
  console.log(chalk4.dim(` ${desc || skill.description || skill.name}`));
@@ -4428,7 +4502,7 @@ function printSetupSummary(setup) {
4428
4502
  }
4429
4503
  if (cursor) {
4430
4504
  if (cursor.cursorrules) {
4431
- const icon = fs17.existsSync(".cursorrules") ? chalk4.yellow("~") : chalk4.green("+");
4505
+ const icon = fs18.existsSync(".cursorrules") ? chalk4.yellow("~") : chalk4.green("+");
4432
4506
  const desc = getDescription(".cursorrules");
4433
4507
  console.log(` ${icon} ${chalk4.bold(".cursorrules")}`);
4434
4508
  if (desc) console.log(chalk4.dim(` ${desc}`));
@@ -4438,7 +4512,7 @@ function printSetupSummary(setup) {
4438
4512
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
4439
4513
  for (const skill of cursorSkills) {
4440
4514
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
4441
- const icon = fs17.existsSync(skillPath) ? chalk4.yellow("~") : chalk4.green("+");
4515
+ const icon = fs18.existsSync(skillPath) ? chalk4.yellow("~") : chalk4.green("+");
4442
4516
  const desc = getDescription(skillPath);
4443
4517
  console.log(` ${icon} ${chalk4.bold(skillPath)}`);
4444
4518
  console.log(chalk4.dim(` ${desc || skill.description || skill.name}`));
@@ -4449,7 +4523,7 @@ function printSetupSummary(setup) {
4449
4523
  if (Array.isArray(rules) && rules.length > 0) {
4450
4524
  for (const rule of rules) {
4451
4525
  const rulePath = `.cursor/rules/${rule.filename}`;
4452
- const icon = fs17.existsSync(rulePath) ? chalk4.yellow("~") : chalk4.green("+");
4526
+ const icon = fs18.existsSync(rulePath) ? chalk4.yellow("~") : chalk4.green("+");
4453
4527
  const desc = getDescription(rulePath);
4454
4528
  console.log(` ${icon} ${chalk4.bold(rulePath)}`);
4455
4529
  if (desc) {
@@ -4462,7 +4536,7 @@ function printSetupSummary(setup) {
4462
4536
  }
4463
4537
  }
4464
4538
  }
4465
- if (!fs17.existsSync("AGENTS.md")) {
4539
+ if (!fs18.existsSync("AGENTS.md")) {
4466
4540
  console.log(` ${chalk4.green("+")} ${chalk4.bold("AGENTS.md")}`);
4467
4541
  console.log(chalk4.dim(" Cross-agent coordination file"));
4468
4542
  console.log("");
@@ -4490,8 +4564,8 @@ function ensurePermissions() {
4490
4564
  const settingsPath = ".claude/settings.json";
4491
4565
  let settings = {};
4492
4566
  try {
4493
- if (fs17.existsSync(settingsPath)) {
4494
- settings = JSON.parse(fs17.readFileSync(settingsPath, "utf-8"));
4567
+ if (fs18.existsSync(settingsPath)) {
4568
+ settings = JSON.parse(fs18.readFileSync(settingsPath, "utf-8"));
4495
4569
  }
4496
4570
  } catch {
4497
4571
  }
@@ -4505,8 +4579,8 @@ function ensurePermissions() {
4505
4579
  "Bash(git *)"
4506
4580
  ];
4507
4581
  settings.permissions = permissions;
4508
- if (!fs17.existsSync(".claude")) fs17.mkdirSync(".claude", { recursive: true });
4509
- fs17.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4582
+ if (!fs18.existsSync(".claude")) fs18.mkdirSync(".claude", { recursive: true });
4583
+ fs18.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4510
4584
  }
4511
4585
  function collectSetupFiles(setup) {
4512
4586
  const files = [];
@@ -4536,7 +4610,7 @@ function collectSetupFiles(setup) {
4536
4610
  }
4537
4611
  }
4538
4612
  }
4539
- if (!fs17.existsSync("AGENTS.md")) {
4613
+ if (!fs18.existsSync("AGENTS.md")) {
4540
4614
  const agentRefs = [];
4541
4615
  if (claude) agentRefs.push("See `CLAUDE.md` for Claude Code configuration.");
4542
4616
  if (cursor) agentRefs.push("See `.cursor/rules/` for Cursor rules.");
@@ -4587,7 +4661,7 @@ function undoCommand() {
4587
4661
 
4588
4662
  // src/commands/status.ts
4589
4663
  import chalk6 from "chalk";
4590
- import fs18 from "fs";
4664
+ import fs19 from "fs";
4591
4665
  async function statusCommand(options) {
4592
4666
  const config = loadConfig();
4593
4667
  const manifest = readManifest();
@@ -4604,16 +4678,16 @@ async function statusCommand(options) {
4604
4678
  if (config) {
4605
4679
  console.log(` LLM: ${chalk6.green(config.provider)} (${config.model})`);
4606
4680
  } else {
4607
- console.log(` LLM: ${chalk6.yellow("Not configured")} \u2014 run \`caliber config\``);
4681
+ console.log(` LLM: ${chalk6.yellow("Not configured")} \u2014 run ${chalk6.hex("#83D1EB")("caliber config")}`);
4608
4682
  }
4609
4683
  if (!manifest) {
4610
4684
  console.log(` Setup: ${chalk6.dim("No setup applied")}`);
4611
- console.log(chalk6.dim("\n Run `caliber onboard` to get started.\n"));
4685
+ console.log(chalk6.dim("\n Run ") + chalk6.hex("#83D1EB")("caliber onboard") + chalk6.dim(" to get started.\n"));
4612
4686
  return;
4613
4687
  }
4614
4688
  console.log(` Files managed: ${chalk6.cyan(manifest.entries.length.toString())}`);
4615
4689
  for (const entry of manifest.entries) {
4616
- const exists = fs18.existsSync(entry.path);
4690
+ const exists = fs19.existsSync(entry.path);
4617
4691
  const icon = exists ? chalk6.green("\u2713") : chalk6.red("\u2717");
4618
4692
  console.log(` ${icon} ${entry.path} (${entry.action})`);
4619
4693
  }
@@ -4627,12 +4701,12 @@ import confirm from "@inquirer/confirm";
4627
4701
  async function regenerateCommand(options) {
4628
4702
  const config = loadConfig();
4629
4703
  if (!config) {
4630
- console.log(chalk7.red("No LLM provider configured. Run `caliber config` (e.g. choose Cursor) or set ANTHROPIC_API_KEY."));
4704
+ console.log(chalk7.red("No LLM provider configured. Run ") + chalk7.hex("#83D1EB")("caliber config") + chalk7.red(" (e.g. choose Cursor) or set ANTHROPIC_API_KEY."));
4631
4705
  throw new Error("__exit__");
4632
4706
  }
4633
4707
  const manifest = readManifest();
4634
4708
  if (!manifest) {
4635
- console.log(chalk7.yellow("No existing setup found. Run `caliber onboard` first."));
4709
+ console.log(chalk7.yellow("No existing setup found. Run ") + chalk7.hex("#83D1EB")("caliber onboard") + chalk7.yellow(" first."));
4636
4710
  throw new Error("__exit__");
4637
4711
  }
4638
4712
  const spinner = ora3("Re-analyzing project...").start();
@@ -4700,13 +4774,13 @@ import { mkdirSync, readFileSync as readFileSync7, readdirSync as readdirSync5,
4700
4774
  import { join as join8, dirname as dirname2 } from "path";
4701
4775
 
4702
4776
  // src/scanner/index.ts
4703
- import fs19 from "fs";
4704
- import path16 from "path";
4777
+ import fs20 from "fs";
4778
+ import path17 from "path";
4705
4779
  import crypto2 from "crypto";
4706
4780
  function scanLocalState(dir) {
4707
4781
  const items = [];
4708
- const claudeMdPath = path16.join(dir, "CLAUDE.md");
4709
- if (fs19.existsSync(claudeMdPath)) {
4782
+ const claudeMdPath = path17.join(dir, "CLAUDE.md");
4783
+ if (fs20.existsSync(claudeMdPath)) {
4710
4784
  items.push({
4711
4785
  type: "rule",
4712
4786
  platform: "claude",
@@ -4715,10 +4789,10 @@ function scanLocalState(dir) {
4715
4789
  path: claudeMdPath
4716
4790
  });
4717
4791
  }
4718
- const skillsDir = path16.join(dir, ".claude", "skills");
4719
- if (fs19.existsSync(skillsDir)) {
4720
- for (const file of fs19.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4721
- const filePath = path16.join(skillsDir, file);
4792
+ const skillsDir = path17.join(dir, ".claude", "skills");
4793
+ if (fs20.existsSync(skillsDir)) {
4794
+ for (const file of fs20.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
4795
+ const filePath = path17.join(skillsDir, file);
4722
4796
  items.push({
4723
4797
  type: "skill",
4724
4798
  platform: "claude",
@@ -4728,10 +4802,10 @@ function scanLocalState(dir) {
4728
4802
  });
4729
4803
  }
4730
4804
  }
4731
- const mcpJsonPath = path16.join(dir, ".mcp.json");
4732
- if (fs19.existsSync(mcpJsonPath)) {
4805
+ const mcpJsonPath = path17.join(dir, ".mcp.json");
4806
+ if (fs20.existsSync(mcpJsonPath)) {
4733
4807
  try {
4734
- const mcpJson = JSON.parse(fs19.readFileSync(mcpJsonPath, "utf-8"));
4808
+ const mcpJson = JSON.parse(fs20.readFileSync(mcpJsonPath, "utf-8"));
4735
4809
  if (mcpJson.mcpServers) {
4736
4810
  for (const name of Object.keys(mcpJson.mcpServers)) {
4737
4811
  items.push({
@@ -4746,8 +4820,8 @@ function scanLocalState(dir) {
4746
4820
  } catch {
4747
4821
  }
4748
4822
  }
4749
- const cursorrulesPath = path16.join(dir, ".cursorrules");
4750
- if (fs19.existsSync(cursorrulesPath)) {
4823
+ const cursorrulesPath = path17.join(dir, ".cursorrules");
4824
+ if (fs20.existsSync(cursorrulesPath)) {
4751
4825
  items.push({
4752
4826
  type: "rule",
4753
4827
  platform: "cursor",
@@ -4756,10 +4830,10 @@ function scanLocalState(dir) {
4756
4830
  path: cursorrulesPath
4757
4831
  });
4758
4832
  }
4759
- const cursorRulesDir = path16.join(dir, ".cursor", "rules");
4760
- if (fs19.existsSync(cursorRulesDir)) {
4761
- for (const file of fs19.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4762
- const filePath = path16.join(cursorRulesDir, file);
4833
+ const cursorRulesDir = path17.join(dir, ".cursor", "rules");
4834
+ if (fs20.existsSync(cursorRulesDir)) {
4835
+ for (const file of fs20.readdirSync(cursorRulesDir).filter((f) => f.endsWith(".mdc"))) {
4836
+ const filePath = path17.join(cursorRulesDir, file);
4763
4837
  items.push({
4764
4838
  type: "rule",
4765
4839
  platform: "cursor",
@@ -4769,12 +4843,12 @@ function scanLocalState(dir) {
4769
4843
  });
4770
4844
  }
4771
4845
  }
4772
- const cursorSkillsDir = path16.join(dir, ".cursor", "skills");
4773
- if (fs19.existsSync(cursorSkillsDir)) {
4846
+ const cursorSkillsDir = path17.join(dir, ".cursor", "skills");
4847
+ if (fs20.existsSync(cursorSkillsDir)) {
4774
4848
  try {
4775
- for (const name of fs19.readdirSync(cursorSkillsDir)) {
4776
- const skillFile = path16.join(cursorSkillsDir, name, "SKILL.md");
4777
- if (fs19.existsSync(skillFile)) {
4849
+ for (const name of fs20.readdirSync(cursorSkillsDir)) {
4850
+ const skillFile = path17.join(cursorSkillsDir, name, "SKILL.md");
4851
+ if (fs20.existsSync(skillFile)) {
4778
4852
  items.push({
4779
4853
  type: "skill",
4780
4854
  platform: "cursor",
@@ -4787,10 +4861,10 @@ function scanLocalState(dir) {
4787
4861
  } catch {
4788
4862
  }
4789
4863
  }
4790
- const cursorMcpPath = path16.join(dir, ".cursor", "mcp.json");
4791
- if (fs19.existsSync(cursorMcpPath)) {
4864
+ const cursorMcpPath = path17.join(dir, ".cursor", "mcp.json");
4865
+ if (fs20.existsSync(cursorMcpPath)) {
4792
4866
  try {
4793
- const mcpJson = JSON.parse(fs19.readFileSync(cursorMcpPath, "utf-8"));
4867
+ const mcpJson = JSON.parse(fs20.readFileSync(cursorMcpPath, "utf-8"));
4794
4868
  if (mcpJson.mcpServers) {
4795
4869
  for (const name of Object.keys(mcpJson.mcpServers)) {
4796
4870
  items.push({
@@ -4808,7 +4882,7 @@ function scanLocalState(dir) {
4808
4882
  return items;
4809
4883
  }
4810
4884
  function hashFile(filePath) {
4811
- const text = fs19.readFileSync(filePath, "utf-8");
4885
+ const text = fs20.readFileSync(filePath, "utf-8");
4812
4886
  return crypto2.createHash("sha256").update(JSON.stringify({ text })).digest("hex");
4813
4887
  }
4814
4888
  function hashJson(obj) {
@@ -5374,18 +5448,18 @@ async function scoreCommand(options) {
5374
5448
  const separator = chalk9.gray(" " + "\u2500".repeat(53));
5375
5449
  console.log(separator);
5376
5450
  if (result.score < 40) {
5377
- console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber onboard") + chalk9.gray(" to generate a complete, optimized setup."));
5451
+ console.log(chalk9.gray(" Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.gray(" to generate a complete, optimized setup."));
5378
5452
  } else if (result.score < 70) {
5379
- console.log(chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber onboard") + chalk9.gray(" to improve your setup."));
5453
+ console.log(chalk9.gray(" Run ") + chalk9.hex("#83D1EB")("caliber onboard") + chalk9.gray(" to improve your setup."));
5380
5454
  } else {
5381
- console.log(chalk9.green(" Looking good!") + chalk9.gray(" Run ") + chalk9.hex("#f97316")("caliber update") + chalk9.gray(" to keep it fresh."));
5455
+ console.log(chalk9.green(" Looking good!") + chalk9.gray(" Run ") + chalk9.hex("#83D1EB")("caliber update") + chalk9.gray(" to keep it fresh."));
5382
5456
  }
5383
5457
  console.log("");
5384
5458
  }
5385
5459
 
5386
5460
  // src/commands/refresh.ts
5387
- import fs21 from "fs";
5388
- import path18 from "path";
5461
+ import fs22 from "fs";
5462
+ import path19 from "path";
5389
5463
  import chalk10 from "chalk";
5390
5464
  import ora5 from "ora";
5391
5465
 
@@ -5462,37 +5536,37 @@ function collectDiff(lastSha) {
5462
5536
  }
5463
5537
 
5464
5538
  // src/writers/refresh.ts
5465
- import fs20 from "fs";
5466
- import path17 from "path";
5539
+ import fs21 from "fs";
5540
+ import path18 from "path";
5467
5541
  function writeRefreshDocs(docs) {
5468
5542
  const written = [];
5469
5543
  if (docs.claudeMd) {
5470
- fs20.writeFileSync("CLAUDE.md", docs.claudeMd);
5544
+ fs21.writeFileSync("CLAUDE.md", docs.claudeMd);
5471
5545
  written.push("CLAUDE.md");
5472
5546
  }
5473
5547
  if (docs.readmeMd) {
5474
- fs20.writeFileSync("README.md", docs.readmeMd);
5548
+ fs21.writeFileSync("README.md", docs.readmeMd);
5475
5549
  written.push("README.md");
5476
5550
  }
5477
5551
  if (docs.cursorrules) {
5478
- fs20.writeFileSync(".cursorrules", docs.cursorrules);
5552
+ fs21.writeFileSync(".cursorrules", docs.cursorrules);
5479
5553
  written.push(".cursorrules");
5480
5554
  }
5481
5555
  if (docs.cursorRules) {
5482
- const rulesDir = path17.join(".cursor", "rules");
5483
- if (!fs20.existsSync(rulesDir)) fs20.mkdirSync(rulesDir, { recursive: true });
5556
+ const rulesDir = path18.join(".cursor", "rules");
5557
+ if (!fs21.existsSync(rulesDir)) fs21.mkdirSync(rulesDir, { recursive: true });
5484
5558
  for (const rule of docs.cursorRules) {
5485
- const filePath = path17.join(rulesDir, rule.filename);
5486
- fs20.writeFileSync(filePath, rule.content);
5559
+ const filePath = path18.join(rulesDir, rule.filename);
5560
+ fs21.writeFileSync(filePath, rule.content);
5487
5561
  written.push(filePath);
5488
5562
  }
5489
5563
  }
5490
5564
  if (docs.claudeSkills) {
5491
- const skillsDir = path17.join(".claude", "skills");
5492
- if (!fs20.existsSync(skillsDir)) fs20.mkdirSync(skillsDir, { recursive: true });
5565
+ const skillsDir = path18.join(".claude", "skills");
5566
+ if (!fs21.existsSync(skillsDir)) fs21.mkdirSync(skillsDir, { recursive: true });
5493
5567
  for (const skill of docs.claudeSkills) {
5494
- const filePath = path17.join(skillsDir, skill.filename);
5495
- fs20.writeFileSync(filePath, skill.content);
5568
+ const filePath = path18.join(skillsDir, skill.filename);
5569
+ fs21.writeFileSync(filePath, skill.content);
5496
5570
  written.push(filePath);
5497
5571
  }
5498
5572
  }
@@ -5567,11 +5641,11 @@ function log(quiet, ...args) {
5567
5641
  function discoverGitRepos(parentDir) {
5568
5642
  const repos = [];
5569
5643
  try {
5570
- const entries = fs21.readdirSync(parentDir, { withFileTypes: true });
5644
+ const entries = fs22.readdirSync(parentDir, { withFileTypes: true });
5571
5645
  for (const entry of entries) {
5572
5646
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
5573
- const childPath = path18.join(parentDir, entry.name);
5574
- if (fs21.existsSync(path18.join(childPath, ".git"))) {
5647
+ const childPath = path19.join(parentDir, entry.name);
5648
+ if (fs22.existsSync(path19.join(childPath, ".git"))) {
5575
5649
  repos.push(childPath);
5576
5650
  }
5577
5651
  }
@@ -5649,7 +5723,7 @@ async function refreshCommand(options) {
5649
5723
  const config = loadConfig();
5650
5724
  if (!config) {
5651
5725
  if (quiet) return;
5652
- console.log(chalk10.red("No LLM provider configured. Run `caliber config` (e.g. choose Cursor) or set an API key."));
5726
+ console.log(chalk10.red("No LLM provider configured. Run ") + chalk10.hex("#83D1EB")("caliber config") + chalk10.red(" (e.g. choose Cursor) or set an API key."));
5653
5727
  throw new Error("__exit__");
5654
5728
  }
5655
5729
  if (isGitRepo()) {
@@ -5666,7 +5740,7 @@ async function refreshCommand(options) {
5666
5740
  `));
5667
5741
  const originalDir = process.cwd();
5668
5742
  for (const repo of repos) {
5669
- const repoName = path18.basename(repo);
5743
+ const repoName = path19.basename(repo);
5670
5744
  try {
5671
5745
  process.chdir(repo);
5672
5746
  await refreshSingleRepo(repo, { ...options, label: repoName });
@@ -5913,8 +5987,8 @@ function readStdin() {
5913
5987
 
5914
5988
  // src/learner/storage.ts
5915
5989
  init_constants();
5916
- import fs22 from "fs";
5917
- import path19 from "path";
5990
+ import fs23 from "fs";
5991
+ import path20 from "path";
5918
5992
  var MAX_RESPONSE_LENGTH = 2e3;
5919
5993
  var DEFAULT_STATE = {
5920
5994
  sessionId: null,
@@ -5922,15 +5996,15 @@ var DEFAULT_STATE = {
5922
5996
  lastAnalysisTimestamp: null
5923
5997
  };
5924
5998
  function ensureLearningDir() {
5925
- if (!fs22.existsSync(LEARNING_DIR)) {
5926
- fs22.mkdirSync(LEARNING_DIR, { recursive: true });
5999
+ if (!fs23.existsSync(LEARNING_DIR)) {
6000
+ fs23.mkdirSync(LEARNING_DIR, { recursive: true });
5927
6001
  }
5928
6002
  }
5929
6003
  function sessionFilePath() {
5930
- return path19.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6004
+ return path20.join(LEARNING_DIR, LEARNING_SESSION_FILE);
5931
6005
  }
5932
6006
  function stateFilePath() {
5933
- return path19.join(LEARNING_DIR, LEARNING_STATE_FILE);
6007
+ return path20.join(LEARNING_DIR, LEARNING_STATE_FILE);
5934
6008
  }
5935
6009
  function truncateResponse(response) {
5936
6010
  const str = JSON.stringify(response);
@@ -5941,50 +6015,50 @@ function appendEvent(event) {
5941
6015
  ensureLearningDir();
5942
6016
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
5943
6017
  const filePath = sessionFilePath();
5944
- fs22.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6018
+ fs23.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
5945
6019
  const count = getEventCount();
5946
6020
  if (count > LEARNING_MAX_EVENTS) {
5947
- const lines = fs22.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6021
+ const lines = fs23.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
5948
6022
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
5949
- fs22.writeFileSync(filePath, kept.join("\n") + "\n");
6023
+ fs23.writeFileSync(filePath, kept.join("\n") + "\n");
5950
6024
  }
5951
6025
  }
5952
6026
  function readAllEvents() {
5953
6027
  const filePath = sessionFilePath();
5954
- if (!fs22.existsSync(filePath)) return [];
5955
- const lines = fs22.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6028
+ if (!fs23.existsSync(filePath)) return [];
6029
+ const lines = fs23.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
5956
6030
  return lines.map((line) => JSON.parse(line));
5957
6031
  }
5958
6032
  function getEventCount() {
5959
6033
  const filePath = sessionFilePath();
5960
- if (!fs22.existsSync(filePath)) return 0;
5961
- const content = fs22.readFileSync(filePath, "utf-8");
6034
+ if (!fs23.existsSync(filePath)) return 0;
6035
+ const content = fs23.readFileSync(filePath, "utf-8");
5962
6036
  return content.split("\n").filter(Boolean).length;
5963
6037
  }
5964
6038
  function clearSession() {
5965
6039
  const filePath = sessionFilePath();
5966
- if (fs22.existsSync(filePath)) fs22.unlinkSync(filePath);
6040
+ if (fs23.existsSync(filePath)) fs23.unlinkSync(filePath);
5967
6041
  }
5968
6042
  function readState2() {
5969
6043
  const filePath = stateFilePath();
5970
- if (!fs22.existsSync(filePath)) return { ...DEFAULT_STATE };
6044
+ if (!fs23.existsSync(filePath)) return { ...DEFAULT_STATE };
5971
6045
  try {
5972
- return JSON.parse(fs22.readFileSync(filePath, "utf-8"));
6046
+ return JSON.parse(fs23.readFileSync(filePath, "utf-8"));
5973
6047
  } catch {
5974
6048
  return { ...DEFAULT_STATE };
5975
6049
  }
5976
6050
  }
5977
6051
  function writeState2(state) {
5978
6052
  ensureLearningDir();
5979
- fs22.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6053
+ fs23.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
5980
6054
  }
5981
6055
  function resetState() {
5982
6056
  writeState2({ ...DEFAULT_STATE });
5983
6057
  }
5984
6058
 
5985
6059
  // src/learner/writer.ts
5986
- import fs23 from "fs";
5987
- import path20 from "path";
6060
+ import fs24 from "fs";
6061
+ import path21 from "path";
5988
6062
  var LEARNED_START = "<!-- caliber:learned -->";
5989
6063
  var LEARNED_END = "<!-- /caliber:learned -->";
5990
6064
  function writeLearnedContent(update) {
@@ -6004,8 +6078,8 @@ function writeLearnedContent(update) {
6004
6078
  function writeLearnedSection(content) {
6005
6079
  const claudeMdPath = "CLAUDE.md";
6006
6080
  let existing = "";
6007
- if (fs23.existsSync(claudeMdPath)) {
6008
- existing = fs23.readFileSync(claudeMdPath, "utf-8");
6081
+ if (fs24.existsSync(claudeMdPath)) {
6082
+ existing = fs24.readFileSync(claudeMdPath, "utf-8");
6009
6083
  }
6010
6084
  const section = `${LEARNED_START}
6011
6085
  ${content}
@@ -6019,15 +6093,15 @@ ${LEARNED_END}`;
6019
6093
  const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
6020
6094
  updated = existing + separator + "\n" + section + "\n";
6021
6095
  }
6022
- fs23.writeFileSync(claudeMdPath, updated);
6096
+ fs24.writeFileSync(claudeMdPath, updated);
6023
6097
  }
6024
6098
  function writeLearnedSkill(skill) {
6025
- const skillDir = path20.join(".claude", "skills", skill.name);
6026
- if (!fs23.existsSync(skillDir)) fs23.mkdirSync(skillDir, { recursive: true });
6027
- const skillPath = path20.join(skillDir, "SKILL.md");
6028
- if (!skill.isNew && fs23.existsSync(skillPath)) {
6029
- const existing = fs23.readFileSync(skillPath, "utf-8");
6030
- fs23.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6099
+ const skillDir = path21.join(".claude", "skills", skill.name);
6100
+ if (!fs24.existsSync(skillDir)) fs24.mkdirSync(skillDir, { recursive: true });
6101
+ const skillPath = path21.join(skillDir, "SKILL.md");
6102
+ if (!skill.isNew && fs24.existsSync(skillPath)) {
6103
+ const existing = fs24.readFileSync(skillPath, "utf-8");
6104
+ fs24.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6031
6105
  } else {
6032
6106
  const frontmatter = [
6033
6107
  "---",
@@ -6036,14 +6110,14 @@ function writeLearnedSkill(skill) {
6036
6110
  "---",
6037
6111
  ""
6038
6112
  ].join("\n");
6039
- fs23.writeFileSync(skillPath, frontmatter + skill.content);
6113
+ fs24.writeFileSync(skillPath, frontmatter + skill.content);
6040
6114
  }
6041
6115
  return skillPath;
6042
6116
  }
6043
6117
  function readLearnedSection() {
6044
6118
  const claudeMdPath = "CLAUDE.md";
6045
- if (!fs23.existsSync(claudeMdPath)) return null;
6046
- const content = fs23.readFileSync(claudeMdPath, "utf-8");
6119
+ if (!fs24.existsSync(claudeMdPath)) return null;
6120
+ const content = fs24.readFileSync(claudeMdPath, "utf-8");
6047
6121
  const startIdx = content.indexOf(LEARNED_START);
6048
6122
  const endIdx = content.indexOf(LEARNED_END);
6049
6123
  if (startIdx === -1 || endIdx === -1) return null;
@@ -6227,9 +6301,9 @@ Learned items in CLAUDE.md: ${chalk13.cyan(String(lineCount))}`);
6227
6301
  }
6228
6302
 
6229
6303
  // src/cli.ts
6230
- var __dirname = path21.dirname(fileURLToPath(import.meta.url));
6304
+ var __dirname = path22.dirname(fileURLToPath(import.meta.url));
6231
6305
  var pkg = JSON.parse(
6232
- fs24.readFileSync(path21.resolve(__dirname, "..", "package.json"), "utf-8")
6306
+ fs25.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
6233
6307
  );
6234
6308
  var program = new Command();
6235
6309
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -6251,22 +6325,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
6251
6325
  learn.command("status").description("Show learning system status").action(learnStatusCommand);
6252
6326
 
6253
6327
  // src/utils/version-check.ts
6254
- import fs25 from "fs";
6255
- import path22 from "path";
6328
+ import fs26 from "fs";
6329
+ import path23 from "path";
6256
6330
  import { fileURLToPath as fileURLToPath2 } from "url";
6257
6331
  import { execSync as execSync9 } from "child_process";
6258
6332
  import chalk14 from "chalk";
6259
6333
  import ora6 from "ora";
6260
6334
  import confirm2 from "@inquirer/confirm";
6261
- var __dirname_vc = path22.dirname(fileURLToPath2(import.meta.url));
6335
+ var __dirname_vc = path23.dirname(fileURLToPath2(import.meta.url));
6262
6336
  var pkg2 = JSON.parse(
6263
- fs25.readFileSync(path22.resolve(__dirname_vc, "..", "package.json"), "utf-8")
6337
+ fs26.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
6264
6338
  );
6265
6339
  function getInstalledVersion() {
6266
6340
  try {
6267
6341
  const globalRoot = execSync9("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
6268
- const pkgPath = path22.join(globalRoot, "@rely-ai", "caliber", "package.json");
6269
- return JSON.parse(fs25.readFileSync(pkgPath, "utf-8")).version;
6342
+ const pkgPath = path23.join(globalRoot, "@rely-ai", "caliber", "package.json");
6343
+ return JSON.parse(fs26.readFileSync(pkgPath, "utf-8")).version;
6270
6344
  } catch {
6271
6345
  return null;
6272
6346
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
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": {