@rely-ai/caliber 1.7.5 → 1.7.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.
Files changed (2) hide show
  1. package/dist/bin.js +236 -91
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -165,17 +165,18 @@ var init_constants = __esm({
165
165
 
166
166
  // src/cli.ts
167
167
  import { Command } from "commander";
168
- import fs29 from "fs";
169
- import path22 from "path";
168
+ import fs30 from "fs";
169
+ import path24 from "path";
170
170
  import { fileURLToPath } from "url";
171
171
 
172
172
  // src/commands/onboard.ts
173
+ import path19 from "path";
173
174
  import chalk8 from "chalk";
174
175
  import ora2 from "ora";
175
176
  import readline3 from "readline";
176
177
  import select5 from "@inquirer/select";
177
178
  import checkbox from "@inquirer/checkbox";
178
- import fs23 from "fs";
179
+ import fs24 from "fs";
179
180
 
180
181
  // src/fingerprint/index.ts
181
182
  import fs6 from "fs";
@@ -2680,6 +2681,11 @@ import { execSync as execSync5 } from "child_process";
2680
2681
  var _resolved = null;
2681
2682
  function resolveCaliber() {
2682
2683
  if (_resolved) return _resolved;
2684
+ const isNpx = process.argv[1]?.includes("_npx") || process.env.npm_execpath?.includes("npx");
2685
+ if (isNpx) {
2686
+ _resolved = "npx --yes @rely-ai/caliber";
2687
+ return _resolved;
2688
+ }
2683
2689
  try {
2684
2690
  const found = execSync5("which caliber", {
2685
2691
  encoding: "utf-8",
@@ -2702,6 +2708,8 @@ function resolveCaliber() {
2702
2708
  function isCaliberCommand(command, subcommandTail) {
2703
2709
  if (command === `caliber ${subcommandTail}`) return true;
2704
2710
  if (command.endsWith(`/caliber ${subcommandTail}`)) return true;
2711
+ if (command === `npx --yes @rely-ai/caliber ${subcommandTail}`) return true;
2712
+ if (command === `npx @rely-ai/caliber ${subcommandTail}`) return true;
2705
2713
  return false;
2706
2714
  }
2707
2715
 
@@ -3242,15 +3250,15 @@ function computeGrade(score) {
3242
3250
  // src/scoring/checks/coverage.ts
3243
3251
  import { readFileSync, readdirSync } from "fs";
3244
3252
  import { join } from "path";
3245
- function readFileOrNull(path24) {
3253
+ function readFileOrNull(path26) {
3246
3254
  try {
3247
- return readFileSync(path24, "utf-8");
3255
+ return readFileSync(path26, "utf-8");
3248
3256
  } catch {
3249
3257
  return null;
3250
3258
  }
3251
3259
  }
3252
- function readJsonOrNull(path24) {
3253
- const content = readFileOrNull(path24);
3260
+ function readJsonOrNull(path26) {
3261
+ const content = readFileOrNull(path26);
3254
3262
  if (!content) return null;
3255
3263
  try {
3256
3264
  return JSON.parse(content);
@@ -3618,9 +3626,9 @@ function checkExistence(dir) {
3618
3626
  // src/scoring/checks/quality.ts
3619
3627
  import { readFileSync as readFileSync3 } from "fs";
3620
3628
  import { join as join3 } from "path";
3621
- function readFileOrNull2(path24) {
3629
+ function readFileOrNull2(path26) {
3622
3630
  try {
3623
- return readFileSync3(path24, "utf-8");
3631
+ return readFileSync3(path26, "utf-8");
3624
3632
  } catch {
3625
3633
  return null;
3626
3634
  }
@@ -3773,15 +3781,15 @@ function checkQuality(dir) {
3773
3781
  // src/scoring/checks/accuracy.ts
3774
3782
  import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
3775
3783
  import { join as join4 } from "path";
3776
- function readFileOrNull3(path24) {
3784
+ function readFileOrNull3(path26) {
3777
3785
  try {
3778
- return readFileSync4(path24, "utf-8");
3786
+ return readFileSync4(path26, "utf-8");
3779
3787
  } catch {
3780
3788
  return null;
3781
3789
  }
3782
3790
  }
3783
- function readJsonOrNull2(path24) {
3784
- const content = readFileOrNull3(path24);
3791
+ function readJsonOrNull2(path26) {
3792
+ const content = readFileOrNull3(path26);
3785
3793
  if (!content) return null;
3786
3794
  try {
3787
3795
  return JSON.parse(content);
@@ -3964,9 +3972,9 @@ function checkAccuracy(dir) {
3964
3972
  // src/scoring/checks/freshness.ts
3965
3973
  import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
3966
3974
  import { join as join5 } from "path";
3967
- function readFileOrNull4(path24) {
3975
+ function readFileOrNull4(path26) {
3968
3976
  try {
3969
- return readFileSync5(path24, "utf-8");
3977
+ return readFileSync5(path26, "utf-8");
3970
3978
  } catch {
3971
3979
  return null;
3972
3980
  }
@@ -4080,9 +4088,9 @@ function checkFreshness(dir) {
4080
4088
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
4081
4089
  import { execSync as execSync8 } from "child_process";
4082
4090
  import { join as join6 } from "path";
4083
- function readFileOrNull5(path24) {
4091
+ function readFileOrNull5(path26) {
4084
4092
  try {
4085
- return readFileSync6(path24, "utf-8");
4093
+ return readFileSync6(path26, "utf-8");
4086
4094
  } catch {
4087
4095
  return null;
4088
4096
  }
@@ -5266,6 +5274,93 @@ function printSkills(recs) {
5266
5274
  console.log("");
5267
5275
  }
5268
5276
 
5277
+ // src/lib/debug-report.ts
5278
+ import fs23 from "fs";
5279
+ import path18 from "path";
5280
+ var DebugReport = class {
5281
+ sections = [];
5282
+ startTime;
5283
+ stepTimings = [];
5284
+ lastStepStart;
5285
+ lastStepName = null;
5286
+ constructor() {
5287
+ this.startTime = Date.now();
5288
+ this.lastStepStart = this.startTime;
5289
+ }
5290
+ markStep(name) {
5291
+ if (this.lastStepName) {
5292
+ this.stepTimings.push({
5293
+ step: this.lastStepName,
5294
+ durationMs: Date.now() - this.lastStepStart
5295
+ });
5296
+ }
5297
+ this.lastStepName = name;
5298
+ this.lastStepStart = Date.now();
5299
+ }
5300
+ addSection(title, content) {
5301
+ this.sections.push({ title, content });
5302
+ }
5303
+ addJson(title, data) {
5304
+ this.sections.push({
5305
+ title,
5306
+ content: "```json\n" + JSON.stringify(data, null, 2) + "\n```"
5307
+ });
5308
+ }
5309
+ addCodeBlock(title, code, lang = "text") {
5310
+ this.sections.push({
5311
+ title,
5312
+ content: "```" + lang + "\n" + code + "\n```"
5313
+ });
5314
+ }
5315
+ write(outputPath) {
5316
+ if (this.lastStepName) {
5317
+ this.stepTimings.push({
5318
+ step: this.lastStepName,
5319
+ durationMs: Date.now() - this.lastStepStart
5320
+ });
5321
+ }
5322
+ const totalMs = Date.now() - this.startTime;
5323
+ const lines = [];
5324
+ lines.push("# Caliber Debug Report");
5325
+ lines.push("");
5326
+ lines.push(`- **Generated**: ${(/* @__PURE__ */ new Date()).toISOString()}`);
5327
+ lines.push(`- **CWD**: ${process.cwd()}`);
5328
+ lines.push(`- **Node**: ${process.version}`);
5329
+ lines.push(`- **Total elapsed**: ${formatMs(totalMs)}`);
5330
+ lines.push("");
5331
+ for (const section of this.sections) {
5332
+ lines.push(`## ${section.title}`);
5333
+ lines.push("");
5334
+ lines.push(section.content);
5335
+ lines.push("");
5336
+ }
5337
+ if (this.stepTimings.length > 0) {
5338
+ lines.push("## Timing");
5339
+ lines.push("");
5340
+ lines.push("| Step | Duration |");
5341
+ lines.push("|------|----------|");
5342
+ for (const t of this.stepTimings) {
5343
+ lines.push(`| ${t.step} | ${formatMs(t.durationMs)} |`);
5344
+ }
5345
+ lines.push(`| **Total** | **${formatMs(totalMs)}** |`);
5346
+ lines.push("");
5347
+ }
5348
+ const dir = path18.dirname(outputPath);
5349
+ if (!fs23.existsSync(dir)) {
5350
+ fs23.mkdirSync(dir, { recursive: true });
5351
+ }
5352
+ fs23.writeFileSync(outputPath, lines.join("\n"));
5353
+ }
5354
+ };
5355
+ function formatMs(ms) {
5356
+ if (ms < 1e3) return `${ms}ms`;
5357
+ const secs = Math.floor(ms / 1e3);
5358
+ const mins = Math.floor(secs / 60);
5359
+ const remSecs = secs % 60;
5360
+ if (mins > 0) return `${mins}m ${remSecs}s`;
5361
+ return `${secs}s`;
5362
+ }
5363
+
5269
5364
  // src/commands/onboard.ts
5270
5365
  async function initCommand(options) {
5271
5366
  const brand = chalk8.hex("#EB9D83");
@@ -5282,6 +5377,7 @@ async function initCommand(options) {
5282
5377
  console.log(title.bold(" Welcome to Caliber\n"));
5283
5378
  console.log(chalk8.dim(" Caliber analyzes your codebase and creates tailored config files"));
5284
5379
  console.log(chalk8.dim(" so your AI coding agents understand your project from day one.\n"));
5380
+ const report = options.debugReport ? new DebugReport() : null;
5285
5381
  console.log(title.bold(" How onboarding works:\n"));
5286
5382
  console.log(chalk8.dim(" 1. Connect Set up your LLM provider"));
5287
5383
  console.log(chalk8.dim(" 2. Discover Analyze your code, dependencies, and structure"));
@@ -5313,6 +5409,12 @@ async function initCommand(options) {
5313
5409
  const fastModel = getFastModel();
5314
5410
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
5315
5411
  console.log(chalk8.dim(modelLine + "\n"));
5412
+ if (report) {
5413
+ report.markStep("Provider setup");
5414
+ report.addSection("LLM Provider", `- **Provider**: ${config.provider}
5415
+ - **Model**: ${displayModel}
5416
+ - **Fast model**: ${fastModel || "none"}`);
5417
+ }
5316
5418
  await validateModel({ fast: true });
5317
5419
  console.log(title.bold(" Step 2/6 \u2014 Discover your project\n"));
5318
5420
  console.log(chalk8.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
@@ -5323,6 +5425,16 @@ async function initCommand(options) {
5323
5425
  console.log(chalk8.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
5324
5426
  console.log(chalk8.dim(` Files: ${fingerprint.fileTree.length} found
5325
5427
  `));
5428
+ if (report) {
5429
+ report.markStep("Fingerprint");
5430
+ report.addJson("Fingerprint: Git", { remote: fingerprint.remote, packageName: fingerprint.packageName });
5431
+ report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
5432
+ report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
5433
+ report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
5434
+ if (fingerprint.codeAnalysis) {
5435
+ report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
5436
+ }
5437
+ }
5326
5438
  const targetAgent = options.agent || await promptAgent();
5327
5439
  trackInitAgentSelected(targetAgent);
5328
5440
  const preScore = computeLocalScore(process.cwd(), targetAgent);
@@ -5340,6 +5452,15 @@ async function initCommand(options) {
5340
5452
  displayScoreSummary(baselineScore);
5341
5453
  const passingCount = baselineScore.checks.filter((c) => c.passed).length;
5342
5454
  const failingCount = baselineScore.checks.filter((c) => !c.passed).length;
5455
+ if (report) {
5456
+ report.markStep("Baseline scoring");
5457
+ report.addSection("Scoring: Baseline", `**Score**: ${baselineScore.score}/100
5458
+
5459
+ | Check | Passed | Points | Max |
5460
+ |-------|--------|--------|-----|
5461
+ ` + baselineScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
5462
+ report.addSection("Generation: Target Agents", targetAgent.join(", "));
5463
+ }
5343
5464
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length || fingerprint.existingConfigs.agentsMd);
5344
5465
  const NON_LLM_CHECKS = /* @__PURE__ */ new Set(["hooks_configured", "agents_md_exists", "permissions_configured", "mcp_servers"]);
5345
5466
  if (hasExistingConfig && baselineScore.score === 100) {
@@ -5393,6 +5514,11 @@ async function initCommand(options) {
5393
5514
  console.log(chalk8.dim(" Creating config files tailored to your project.\n"));
5394
5515
  }
5395
5516
  console.log(chalk8.dim(" This can take a couple of minutes depending on your model and provider.\n"));
5517
+ if (report) {
5518
+ report.markStep("Generation");
5519
+ const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
5520
+ report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
5521
+ }
5396
5522
  trackInitGenerationStarted(!!failingChecks);
5397
5523
  const genStartTime = Date.now();
5398
5524
  const genSpinner = ora2("Generating setup...").start();
@@ -5440,6 +5566,10 @@ async function initCommand(options) {
5440
5566
  }
5441
5567
  throw new Error("__exit__");
5442
5568
  }
5569
+ if (report) {
5570
+ if (rawOutput) report.addCodeBlock("Generation: Raw LLM Response", rawOutput);
5571
+ report.addJson("Generation: Parsed Setup", generatedSetup);
5572
+ }
5443
5573
  const elapsedMs = Date.now() - genStartTime;
5444
5574
  trackInitGenerationCompleted(elapsedMs, 0);
5445
5575
  const mins = Math.floor(elapsedMs / 6e4);
@@ -5587,6 +5717,14 @@ async function initCommand(options) {
5587
5717
  console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber onboard --force") + chalk8.dim(" to override.\n"));
5588
5718
  return;
5589
5719
  }
5720
+ if (report) {
5721
+ report.markStep("Post-write scoring");
5722
+ report.addSection("Scoring: Post-Write", `**Score**: ${afterScore.score}/100 (delta: ${afterScore.score - baselineScore.score >= 0 ? "+" : ""}${afterScore.score - baselineScore.score})
5723
+
5724
+ | Check | Passed | Points | Max |
5725
+ |-------|--------|--------|-----|
5726
+ ` + afterScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
5727
+ }
5590
5728
  displayScoreDelta(baselineScore, afterScore);
5591
5729
  console.log(title.bold("\n Step 6/6 \u2014 Community skills\n"));
5592
5730
  console.log(chalk8.dim(" Search public skill registries for skills that match your tech stack.\n"));
@@ -5618,6 +5756,13 @@ async function initCommand(options) {
5618
5756
  console.log(` ${title("caliber skills")} Discover community skills for your stack`);
5619
5757
  console.log(` ${title("caliber undo")} Revert all changes from this run`);
5620
5758
  console.log("");
5759
+ if (report) {
5760
+ report.markStep("Finished");
5761
+ const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
5762
+ report.write(reportPath);
5763
+ console.log(chalk8.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
5764
+ `));
5765
+ }
5621
5766
  }
5622
5767
  async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5623
5768
  while (true) {
@@ -5662,7 +5807,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5662
5807
  }
5663
5808
  function summarizeSetup(action, setup) {
5664
5809
  const descriptions = setup.fileDescriptions;
5665
- const files = descriptions ? Object.entries(descriptions).map(([path24, desc]) => ` ${path24}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
5810
+ const files = descriptions ? Object.entries(descriptions).map(([path26, desc]) => ` ${path26}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
5666
5811
  return `${action}. Files:
5667
5812
  ${files}`;
5668
5813
  }
@@ -5775,7 +5920,7 @@ function printSetupSummary(setup) {
5775
5920
  };
5776
5921
  if (claude) {
5777
5922
  if (claude.claudeMd) {
5778
- const icon = fs23.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5923
+ const icon = fs24.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5779
5924
  const desc = getDescription("CLAUDE.md");
5780
5925
  console.log(` ${icon} ${chalk8.bold("CLAUDE.md")}`);
5781
5926
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5785,7 +5930,7 @@ function printSetupSummary(setup) {
5785
5930
  if (Array.isArray(skills) && skills.length > 0) {
5786
5931
  for (const skill of skills) {
5787
5932
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
5788
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5933
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5789
5934
  const desc = getDescription(skillPath);
5790
5935
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5791
5936
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5796,7 +5941,7 @@ function printSetupSummary(setup) {
5796
5941
  const codex = setup.codex;
5797
5942
  if (codex) {
5798
5943
  if (codex.agentsMd) {
5799
- const icon = fs23.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5944
+ const icon = fs24.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5800
5945
  const desc = getDescription("AGENTS.md");
5801
5946
  console.log(` ${icon} ${chalk8.bold("AGENTS.md")}`);
5802
5947
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5806,7 +5951,7 @@ function printSetupSummary(setup) {
5806
5951
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
5807
5952
  for (const skill of codexSkills) {
5808
5953
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
5809
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5954
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5810
5955
  const desc = getDescription(skillPath);
5811
5956
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5812
5957
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5816,7 +5961,7 @@ function printSetupSummary(setup) {
5816
5961
  }
5817
5962
  if (cursor) {
5818
5963
  if (cursor.cursorrules) {
5819
- const icon = fs23.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5964
+ const icon = fs24.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5820
5965
  const desc = getDescription(".cursorrules");
5821
5966
  console.log(` ${icon} ${chalk8.bold(".cursorrules")}`);
5822
5967
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5826,7 +5971,7 @@ function printSetupSummary(setup) {
5826
5971
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
5827
5972
  for (const skill of cursorSkills) {
5828
5973
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
5829
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5974
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5830
5975
  const desc = getDescription(skillPath);
5831
5976
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5832
5977
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5837,7 +5982,7 @@ function printSetupSummary(setup) {
5837
5982
  if (Array.isArray(rules) && rules.length > 0) {
5838
5983
  for (const rule of rules) {
5839
5984
  const rulePath = `.cursor/rules/${rule.filename}`;
5840
- const icon = fs23.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5985
+ const icon = fs24.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5841
5986
  const desc = getDescription(rulePath);
5842
5987
  console.log(` ${icon} ${chalk8.bold(rulePath)}`);
5843
5988
  if (desc) {
@@ -5850,7 +5995,7 @@ function printSetupSummary(setup) {
5850
5995
  }
5851
5996
  }
5852
5997
  }
5853
- if (!codex && !fs23.existsSync("AGENTS.md")) {
5998
+ if (!codex && !fs24.existsSync("AGENTS.md")) {
5854
5999
  console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
5855
6000
  console.log(chalk8.dim(" Cross-agent coordination file"));
5856
6001
  console.log("");
@@ -5869,8 +6014,8 @@ function ensurePermissions() {
5869
6014
  const settingsPath = ".claude/settings.json";
5870
6015
  let settings = {};
5871
6016
  try {
5872
- if (fs23.existsSync(settingsPath)) {
5873
- settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
6017
+ if (fs24.existsSync(settingsPath)) {
6018
+ settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
5874
6019
  }
5875
6020
  } catch {
5876
6021
  }
@@ -5884,8 +6029,8 @@ function ensurePermissions() {
5884
6029
  "Bash(git *)"
5885
6030
  ];
5886
6031
  settings.permissions = permissions;
5887
- if (!fs23.existsSync(".claude")) fs23.mkdirSync(".claude", { recursive: true });
5888
- fs23.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
6032
+ if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
6033
+ fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5889
6034
  }
5890
6035
 
5891
6036
  // src/commands/undo.ts
@@ -5922,7 +6067,7 @@ function undoCommand() {
5922
6067
 
5923
6068
  // src/commands/status.ts
5924
6069
  import chalk10 from "chalk";
5925
- import fs24 from "fs";
6070
+ import fs25 from "fs";
5926
6071
  init_config();
5927
6072
  async function statusCommand(options) {
5928
6073
  const config = loadConfig();
@@ -5949,7 +6094,7 @@ async function statusCommand(options) {
5949
6094
  }
5950
6095
  console.log(` Files managed: ${chalk10.cyan(manifest.entries.length.toString())}`);
5951
6096
  for (const entry of manifest.entries) {
5952
- const exists = fs24.existsSync(entry.path);
6097
+ const exists = fs25.existsSync(entry.path);
5953
6098
  const icon = exists ? chalk10.green("\u2713") : chalk10.red("\u2717");
5954
6099
  console.log(` ${icon} ${entry.path} (${entry.action})`);
5955
6100
  }
@@ -6130,8 +6275,8 @@ async function scoreCommand(options) {
6130
6275
  }
6131
6276
 
6132
6277
  // src/commands/refresh.ts
6133
- import fs26 from "fs";
6134
- import path19 from "path";
6278
+ import fs27 from "fs";
6279
+ import path21 from "path";
6135
6280
  import chalk13 from "chalk";
6136
6281
  import ora5 from "ora";
6137
6282
 
@@ -6208,37 +6353,37 @@ function collectDiff(lastSha) {
6208
6353
  }
6209
6354
 
6210
6355
  // src/writers/refresh.ts
6211
- import fs25 from "fs";
6212
- import path18 from "path";
6356
+ import fs26 from "fs";
6357
+ import path20 from "path";
6213
6358
  function writeRefreshDocs(docs) {
6214
6359
  const written = [];
6215
6360
  if (docs.claudeMd) {
6216
- fs25.writeFileSync("CLAUDE.md", docs.claudeMd);
6361
+ fs26.writeFileSync("CLAUDE.md", docs.claudeMd);
6217
6362
  written.push("CLAUDE.md");
6218
6363
  }
6219
6364
  if (docs.readmeMd) {
6220
- fs25.writeFileSync("README.md", docs.readmeMd);
6365
+ fs26.writeFileSync("README.md", docs.readmeMd);
6221
6366
  written.push("README.md");
6222
6367
  }
6223
6368
  if (docs.cursorrules) {
6224
- fs25.writeFileSync(".cursorrules", docs.cursorrules);
6369
+ fs26.writeFileSync(".cursorrules", docs.cursorrules);
6225
6370
  written.push(".cursorrules");
6226
6371
  }
6227
6372
  if (docs.cursorRules) {
6228
- const rulesDir = path18.join(".cursor", "rules");
6229
- if (!fs25.existsSync(rulesDir)) fs25.mkdirSync(rulesDir, { recursive: true });
6373
+ const rulesDir = path20.join(".cursor", "rules");
6374
+ if (!fs26.existsSync(rulesDir)) fs26.mkdirSync(rulesDir, { recursive: true });
6230
6375
  for (const rule of docs.cursorRules) {
6231
- const filePath = path18.join(rulesDir, rule.filename);
6232
- fs25.writeFileSync(filePath, rule.content);
6376
+ const filePath = path20.join(rulesDir, rule.filename);
6377
+ fs26.writeFileSync(filePath, rule.content);
6233
6378
  written.push(filePath);
6234
6379
  }
6235
6380
  }
6236
6381
  if (docs.claudeSkills) {
6237
- const skillsDir = path18.join(".claude", "skills");
6238
- if (!fs25.existsSync(skillsDir)) fs25.mkdirSync(skillsDir, { recursive: true });
6382
+ const skillsDir = path20.join(".claude", "skills");
6383
+ if (!fs26.existsSync(skillsDir)) fs26.mkdirSync(skillsDir, { recursive: true });
6239
6384
  for (const skill of docs.claudeSkills) {
6240
- const filePath = path18.join(skillsDir, skill.filename);
6241
- fs25.writeFileSync(filePath, skill.content);
6385
+ const filePath = path20.join(skillsDir, skill.filename);
6386
+ fs26.writeFileSync(filePath, skill.content);
6242
6387
  written.push(filePath);
6243
6388
  }
6244
6389
  }
@@ -6317,11 +6462,11 @@ function log(quiet, ...args) {
6317
6462
  function discoverGitRepos(parentDir) {
6318
6463
  const repos = [];
6319
6464
  try {
6320
- const entries = fs26.readdirSync(parentDir, { withFileTypes: true });
6465
+ const entries = fs27.readdirSync(parentDir, { withFileTypes: true });
6321
6466
  for (const entry of entries) {
6322
6467
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
6323
- const childPath = path19.join(parentDir, entry.name);
6324
- if (fs26.existsSync(path19.join(childPath, ".git"))) {
6468
+ const childPath = path21.join(parentDir, entry.name);
6469
+ if (fs27.existsSync(path21.join(childPath, ".git"))) {
6325
6470
  repos.push(childPath);
6326
6471
  }
6327
6472
  }
@@ -6418,7 +6563,7 @@ async function refreshCommand(options) {
6418
6563
  `));
6419
6564
  const originalDir = process.cwd();
6420
6565
  for (const repo of repos) {
6421
- const repoName = path19.basename(repo);
6566
+ const repoName = path21.basename(repo);
6422
6567
  try {
6423
6568
  process.chdir(repo);
6424
6569
  await refreshSingleRepo(repo, { ...options, label: repoName });
@@ -6673,8 +6818,8 @@ function readStdin() {
6673
6818
 
6674
6819
  // src/learner/storage.ts
6675
6820
  init_constants();
6676
- import fs27 from "fs";
6677
- import path20 from "path";
6821
+ import fs28 from "fs";
6822
+ import path22 from "path";
6678
6823
  var MAX_RESPONSE_LENGTH = 2e3;
6679
6824
  var DEFAULT_STATE = {
6680
6825
  sessionId: null,
@@ -6682,15 +6827,15 @@ var DEFAULT_STATE = {
6682
6827
  lastAnalysisTimestamp: null
6683
6828
  };
6684
6829
  function ensureLearningDir() {
6685
- if (!fs27.existsSync(LEARNING_DIR)) {
6686
- fs27.mkdirSync(LEARNING_DIR, { recursive: true });
6830
+ if (!fs28.existsSync(LEARNING_DIR)) {
6831
+ fs28.mkdirSync(LEARNING_DIR, { recursive: true });
6687
6832
  }
6688
6833
  }
6689
6834
  function sessionFilePath() {
6690
- return path20.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6835
+ return path22.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6691
6836
  }
6692
6837
  function stateFilePath() {
6693
- return path20.join(LEARNING_DIR, LEARNING_STATE_FILE);
6838
+ return path22.join(LEARNING_DIR, LEARNING_STATE_FILE);
6694
6839
  }
6695
6840
  function truncateResponse(response) {
6696
6841
  const str = JSON.stringify(response);
@@ -6701,50 +6846,50 @@ function appendEvent(event) {
6701
6846
  ensureLearningDir();
6702
6847
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
6703
6848
  const filePath = sessionFilePath();
6704
- fs27.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6849
+ fs28.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6705
6850
  const count = getEventCount();
6706
6851
  if (count > LEARNING_MAX_EVENTS) {
6707
- const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6852
+ const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6708
6853
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
6709
- fs27.writeFileSync(filePath, kept.join("\n") + "\n");
6854
+ fs28.writeFileSync(filePath, kept.join("\n") + "\n");
6710
6855
  }
6711
6856
  }
6712
6857
  function readAllEvents() {
6713
6858
  const filePath = sessionFilePath();
6714
- if (!fs27.existsSync(filePath)) return [];
6715
- const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6859
+ if (!fs28.existsSync(filePath)) return [];
6860
+ const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6716
6861
  return lines.map((line) => JSON.parse(line));
6717
6862
  }
6718
6863
  function getEventCount() {
6719
6864
  const filePath = sessionFilePath();
6720
- if (!fs27.existsSync(filePath)) return 0;
6721
- const content = fs27.readFileSync(filePath, "utf-8");
6865
+ if (!fs28.existsSync(filePath)) return 0;
6866
+ const content = fs28.readFileSync(filePath, "utf-8");
6722
6867
  return content.split("\n").filter(Boolean).length;
6723
6868
  }
6724
6869
  function clearSession() {
6725
6870
  const filePath = sessionFilePath();
6726
- if (fs27.existsSync(filePath)) fs27.unlinkSync(filePath);
6871
+ if (fs28.existsSync(filePath)) fs28.unlinkSync(filePath);
6727
6872
  }
6728
6873
  function readState2() {
6729
6874
  const filePath = stateFilePath();
6730
- if (!fs27.existsSync(filePath)) return { ...DEFAULT_STATE };
6875
+ if (!fs28.existsSync(filePath)) return { ...DEFAULT_STATE };
6731
6876
  try {
6732
- return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
6877
+ return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
6733
6878
  } catch {
6734
6879
  return { ...DEFAULT_STATE };
6735
6880
  }
6736
6881
  }
6737
6882
  function writeState2(state) {
6738
6883
  ensureLearningDir();
6739
- fs27.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6884
+ fs28.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6740
6885
  }
6741
6886
  function resetState() {
6742
6887
  writeState2({ ...DEFAULT_STATE });
6743
6888
  }
6744
6889
 
6745
6890
  // src/learner/writer.ts
6746
- import fs28 from "fs";
6747
- import path21 from "path";
6891
+ import fs29 from "fs";
6892
+ import path23 from "path";
6748
6893
  var LEARNED_START = "<!-- caliber:learned -->";
6749
6894
  var LEARNED_END = "<!-- /caliber:learned -->";
6750
6895
  function writeLearnedContent(update) {
@@ -6764,8 +6909,8 @@ function writeLearnedContent(update) {
6764
6909
  function writeLearnedSection(content) {
6765
6910
  const claudeMdPath = "CLAUDE.md";
6766
6911
  let existing = "";
6767
- if (fs28.existsSync(claudeMdPath)) {
6768
- existing = fs28.readFileSync(claudeMdPath, "utf-8");
6912
+ if (fs29.existsSync(claudeMdPath)) {
6913
+ existing = fs29.readFileSync(claudeMdPath, "utf-8");
6769
6914
  }
6770
6915
  const section = `${LEARNED_START}
6771
6916
  ${content}
@@ -6779,15 +6924,15 @@ ${LEARNED_END}`;
6779
6924
  const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
6780
6925
  updated = existing + separator + "\n" + section + "\n";
6781
6926
  }
6782
- fs28.writeFileSync(claudeMdPath, updated);
6927
+ fs29.writeFileSync(claudeMdPath, updated);
6783
6928
  }
6784
6929
  function writeLearnedSkill(skill) {
6785
- const skillDir = path21.join(".claude", "skills", skill.name);
6786
- if (!fs28.existsSync(skillDir)) fs28.mkdirSync(skillDir, { recursive: true });
6787
- const skillPath = path21.join(skillDir, "SKILL.md");
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);
6930
+ const skillDir = path23.join(".claude", "skills", skill.name);
6931
+ if (!fs29.existsSync(skillDir)) fs29.mkdirSync(skillDir, { recursive: true });
6932
+ const skillPath = path23.join(skillDir, "SKILL.md");
6933
+ if (!skill.isNew && fs29.existsSync(skillPath)) {
6934
+ const existing = fs29.readFileSync(skillPath, "utf-8");
6935
+ fs29.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6791
6936
  } else {
6792
6937
  const frontmatter = [
6793
6938
  "---",
@@ -6796,14 +6941,14 @@ function writeLearnedSkill(skill) {
6796
6941
  "---",
6797
6942
  ""
6798
6943
  ].join("\n");
6799
- fs28.writeFileSync(skillPath, frontmatter + skill.content);
6944
+ fs29.writeFileSync(skillPath, frontmatter + skill.content);
6800
6945
  }
6801
6946
  return skillPath;
6802
6947
  }
6803
6948
  function readLearnedSection() {
6804
6949
  const claudeMdPath = "CLAUDE.md";
6805
- if (!fs28.existsSync(claudeMdPath)) return null;
6806
- const content = fs28.readFileSync(claudeMdPath, "utf-8");
6950
+ if (!fs29.existsSync(claudeMdPath)) return null;
6951
+ const content = fs29.readFileSync(claudeMdPath, "utf-8");
6807
6952
  const startIdx = content.indexOf(LEARNED_START);
6808
6953
  const endIdx = content.indexOf(LEARNED_END);
6809
6954
  if (startIdx === -1 || endIdx === -1) return null;
@@ -6992,9 +7137,9 @@ Learned items in CLAUDE.md: ${chalk16.cyan(String(lineCount))}`);
6992
7137
  }
6993
7138
 
6994
7139
  // src/cli.ts
6995
- var __dirname = path22.dirname(fileURLToPath(import.meta.url));
7140
+ var __dirname = path24.dirname(fileURLToPath(import.meta.url));
6996
7141
  var pkg = JSON.parse(
6997
- fs29.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
7142
+ fs30.readFileSync(path24.resolve(__dirname, "..", "package.json"), "utf-8")
6998
7143
  );
6999
7144
  var program = new Command();
7000
7145
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -7051,7 +7196,7 @@ function parseAgentOption(value) {
7051
7196
  }
7052
7197
  return agents;
7053
7198
  }
7054
- program.command("onboard").alias("init").description("Onboard your project for AI-assisted development").option("--agent <type>", "Target agents (comma-separated): claude, cursor, codex", parseAgentOption).option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing setup without prompting").action(tracked("onboard", initCommand));
7199
+ program.command("onboard").alias("init").description("Onboard your project for AI-assisted development").option("--agent <type>", "Target agents (comma-separated): claude, cursor, codex", parseAgentOption).option("--dry-run", "Preview changes without writing files").option("--force", "Overwrite existing setup without prompting").option("--debug-report", void 0, false).action(tracked("onboard", initCommand));
7055
7200
  program.command("undo").description("Revert all config changes made by Caliber").action(tracked("undo", undoCommand));
7056
7201
  program.command("status").description("Show current Caliber setup status").option("--json", "Output as JSON").action(tracked("status", statusCommand));
7057
7202
  program.command("regenerate").alias("regen").alias("re").description("Re-analyze project and regenerate setup").option("--dry-run", "Preview changes without writing files").action(tracked("regenerate", regenerateCommand));
@@ -7068,22 +7213,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
7068
7213
  learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
7069
7214
 
7070
7215
  // src/utils/version-check.ts
7071
- import fs30 from "fs";
7072
- import path23 from "path";
7216
+ import fs31 from "fs";
7217
+ import path25 from "path";
7073
7218
  import { fileURLToPath as fileURLToPath2 } from "url";
7074
7219
  import { execSync as execSync11 } from "child_process";
7075
7220
  import chalk17 from "chalk";
7076
7221
  import ora6 from "ora";
7077
7222
  import confirm from "@inquirer/confirm";
7078
- var __dirname_vc = path23.dirname(fileURLToPath2(import.meta.url));
7223
+ var __dirname_vc = path25.dirname(fileURLToPath2(import.meta.url));
7079
7224
  var pkg2 = JSON.parse(
7080
- fs30.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7225
+ fs31.readFileSync(path25.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7081
7226
  );
7082
7227
  function getInstalledVersion() {
7083
7228
  try {
7084
7229
  const globalRoot = execSync11("npm root -g", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
7085
- const pkgPath = path23.join(globalRoot, "@rely-ai", "caliber", "package.json");
7086
- return JSON.parse(fs30.readFileSync(pkgPath, "utf-8")).version;
7230
+ const pkgPath = path25.join(globalRoot, "@rely-ai", "caliber", "package.json");
7231
+ return JSON.parse(fs31.readFileSync(pkgPath, "utf-8")).version;
7087
7232
  } catch {
7088
7233
  return null;
7089
7234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.7.5",
3
+ "version": "1.7.7",
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": {