@rely-ai/caliber 1.7.5 → 1.7.6

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 +229 -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";
@@ -3242,15 +3243,15 @@ function computeGrade(score) {
3242
3243
  // src/scoring/checks/coverage.ts
3243
3244
  import { readFileSync, readdirSync } from "fs";
3244
3245
  import { join } from "path";
3245
- function readFileOrNull(path24) {
3246
+ function readFileOrNull(path26) {
3246
3247
  try {
3247
- return readFileSync(path24, "utf-8");
3248
+ return readFileSync(path26, "utf-8");
3248
3249
  } catch {
3249
3250
  return null;
3250
3251
  }
3251
3252
  }
3252
- function readJsonOrNull(path24) {
3253
- const content = readFileOrNull(path24);
3253
+ function readJsonOrNull(path26) {
3254
+ const content = readFileOrNull(path26);
3254
3255
  if (!content) return null;
3255
3256
  try {
3256
3257
  return JSON.parse(content);
@@ -3618,9 +3619,9 @@ function checkExistence(dir) {
3618
3619
  // src/scoring/checks/quality.ts
3619
3620
  import { readFileSync as readFileSync3 } from "fs";
3620
3621
  import { join as join3 } from "path";
3621
- function readFileOrNull2(path24) {
3622
+ function readFileOrNull2(path26) {
3622
3623
  try {
3623
- return readFileSync3(path24, "utf-8");
3624
+ return readFileSync3(path26, "utf-8");
3624
3625
  } catch {
3625
3626
  return null;
3626
3627
  }
@@ -3773,15 +3774,15 @@ function checkQuality(dir) {
3773
3774
  // src/scoring/checks/accuracy.ts
3774
3775
  import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync3, statSync } from "fs";
3775
3776
  import { join as join4 } from "path";
3776
- function readFileOrNull3(path24) {
3777
+ function readFileOrNull3(path26) {
3777
3778
  try {
3778
- return readFileSync4(path24, "utf-8");
3779
+ return readFileSync4(path26, "utf-8");
3779
3780
  } catch {
3780
3781
  return null;
3781
3782
  }
3782
3783
  }
3783
- function readJsonOrNull2(path24) {
3784
- const content = readFileOrNull3(path24);
3784
+ function readJsonOrNull2(path26) {
3785
+ const content = readFileOrNull3(path26);
3785
3786
  if (!content) return null;
3786
3787
  try {
3787
3788
  return JSON.parse(content);
@@ -3964,9 +3965,9 @@ function checkAccuracy(dir) {
3964
3965
  // src/scoring/checks/freshness.ts
3965
3966
  import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
3966
3967
  import { join as join5 } from "path";
3967
- function readFileOrNull4(path24) {
3968
+ function readFileOrNull4(path26) {
3968
3969
  try {
3969
- return readFileSync5(path24, "utf-8");
3970
+ return readFileSync5(path26, "utf-8");
3970
3971
  } catch {
3971
3972
  return null;
3972
3973
  }
@@ -4080,9 +4081,9 @@ function checkFreshness(dir) {
4080
4081
  import { existsSync as existsSync7, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
4081
4082
  import { execSync as execSync8 } from "child_process";
4082
4083
  import { join as join6 } from "path";
4083
- function readFileOrNull5(path24) {
4084
+ function readFileOrNull5(path26) {
4084
4085
  try {
4085
- return readFileSync6(path24, "utf-8");
4086
+ return readFileSync6(path26, "utf-8");
4086
4087
  } catch {
4087
4088
  return null;
4088
4089
  }
@@ -5266,6 +5267,93 @@ function printSkills(recs) {
5266
5267
  console.log("");
5267
5268
  }
5268
5269
 
5270
+ // src/lib/debug-report.ts
5271
+ import fs23 from "fs";
5272
+ import path18 from "path";
5273
+ var DebugReport = class {
5274
+ sections = [];
5275
+ startTime;
5276
+ stepTimings = [];
5277
+ lastStepStart;
5278
+ lastStepName = null;
5279
+ constructor() {
5280
+ this.startTime = Date.now();
5281
+ this.lastStepStart = this.startTime;
5282
+ }
5283
+ markStep(name) {
5284
+ if (this.lastStepName) {
5285
+ this.stepTimings.push({
5286
+ step: this.lastStepName,
5287
+ durationMs: Date.now() - this.lastStepStart
5288
+ });
5289
+ }
5290
+ this.lastStepName = name;
5291
+ this.lastStepStart = Date.now();
5292
+ }
5293
+ addSection(title, content) {
5294
+ this.sections.push({ title, content });
5295
+ }
5296
+ addJson(title, data) {
5297
+ this.sections.push({
5298
+ title,
5299
+ content: "```json\n" + JSON.stringify(data, null, 2) + "\n```"
5300
+ });
5301
+ }
5302
+ addCodeBlock(title, code, lang = "text") {
5303
+ this.sections.push({
5304
+ title,
5305
+ content: "```" + lang + "\n" + code + "\n```"
5306
+ });
5307
+ }
5308
+ write(outputPath) {
5309
+ if (this.lastStepName) {
5310
+ this.stepTimings.push({
5311
+ step: this.lastStepName,
5312
+ durationMs: Date.now() - this.lastStepStart
5313
+ });
5314
+ }
5315
+ const totalMs = Date.now() - this.startTime;
5316
+ const lines = [];
5317
+ lines.push("# Caliber Debug Report");
5318
+ lines.push("");
5319
+ lines.push(`- **Generated**: ${(/* @__PURE__ */ new Date()).toISOString()}`);
5320
+ lines.push(`- **CWD**: ${process.cwd()}`);
5321
+ lines.push(`- **Node**: ${process.version}`);
5322
+ lines.push(`- **Total elapsed**: ${formatMs(totalMs)}`);
5323
+ lines.push("");
5324
+ for (const section of this.sections) {
5325
+ lines.push(`## ${section.title}`);
5326
+ lines.push("");
5327
+ lines.push(section.content);
5328
+ lines.push("");
5329
+ }
5330
+ if (this.stepTimings.length > 0) {
5331
+ lines.push("## Timing");
5332
+ lines.push("");
5333
+ lines.push("| Step | Duration |");
5334
+ lines.push("|------|----------|");
5335
+ for (const t of this.stepTimings) {
5336
+ lines.push(`| ${t.step} | ${formatMs(t.durationMs)} |`);
5337
+ }
5338
+ lines.push(`| **Total** | **${formatMs(totalMs)}** |`);
5339
+ lines.push("");
5340
+ }
5341
+ const dir = path18.dirname(outputPath);
5342
+ if (!fs23.existsSync(dir)) {
5343
+ fs23.mkdirSync(dir, { recursive: true });
5344
+ }
5345
+ fs23.writeFileSync(outputPath, lines.join("\n"));
5346
+ }
5347
+ };
5348
+ function formatMs(ms) {
5349
+ if (ms < 1e3) return `${ms}ms`;
5350
+ const secs = Math.floor(ms / 1e3);
5351
+ const mins = Math.floor(secs / 60);
5352
+ const remSecs = secs % 60;
5353
+ if (mins > 0) return `${mins}m ${remSecs}s`;
5354
+ return `${secs}s`;
5355
+ }
5356
+
5269
5357
  // src/commands/onboard.ts
5270
5358
  async function initCommand(options) {
5271
5359
  const brand = chalk8.hex("#EB9D83");
@@ -5282,6 +5370,7 @@ async function initCommand(options) {
5282
5370
  console.log(title.bold(" Welcome to Caliber\n"));
5283
5371
  console.log(chalk8.dim(" Caliber analyzes your codebase and creates tailored config files"));
5284
5372
  console.log(chalk8.dim(" so your AI coding agents understand your project from day one.\n"));
5373
+ const report = options.debugReport ? new DebugReport() : null;
5285
5374
  console.log(title.bold(" How onboarding works:\n"));
5286
5375
  console.log(chalk8.dim(" 1. Connect Set up your LLM provider"));
5287
5376
  console.log(chalk8.dim(" 2. Discover Analyze your code, dependencies, and structure"));
@@ -5313,6 +5402,12 @@ async function initCommand(options) {
5313
5402
  const fastModel = getFastModel();
5314
5403
  const modelLine = fastModel ? ` Provider: ${config.provider} | Model: ${displayModel} | Scan: ${fastModel}` : ` Provider: ${config.provider} | Model: ${displayModel}`;
5315
5404
  console.log(chalk8.dim(modelLine + "\n"));
5405
+ if (report) {
5406
+ report.markStep("Provider setup");
5407
+ report.addSection("LLM Provider", `- **Provider**: ${config.provider}
5408
+ - **Model**: ${displayModel}
5409
+ - **Fast model**: ${fastModel || "none"}`);
5410
+ }
5316
5411
  await validateModel({ fast: true });
5317
5412
  console.log(title.bold(" Step 2/6 \u2014 Discover your project\n"));
5318
5413
  console.log(chalk8.dim(" Learning about your languages, dependencies, structure, and existing configs.\n"));
@@ -5323,6 +5418,16 @@ async function initCommand(options) {
5323
5418
  console.log(chalk8.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
5324
5419
  console.log(chalk8.dim(` Files: ${fingerprint.fileTree.length} found
5325
5420
  `));
5421
+ if (report) {
5422
+ report.markStep("Fingerprint");
5423
+ report.addJson("Fingerprint: Git", { remote: fingerprint.remote, packageName: fingerprint.packageName });
5424
+ report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
5425
+ report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
5426
+ report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
5427
+ if (fingerprint.codeAnalysis) {
5428
+ report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
5429
+ }
5430
+ }
5326
5431
  const targetAgent = options.agent || await promptAgent();
5327
5432
  trackInitAgentSelected(targetAgent);
5328
5433
  const preScore = computeLocalScore(process.cwd(), targetAgent);
@@ -5340,6 +5445,15 @@ async function initCommand(options) {
5340
5445
  displayScoreSummary(baselineScore);
5341
5446
  const passingCount = baselineScore.checks.filter((c) => c.passed).length;
5342
5447
  const failingCount = baselineScore.checks.filter((c) => !c.passed).length;
5448
+ if (report) {
5449
+ report.markStep("Baseline scoring");
5450
+ report.addSection("Scoring: Baseline", `**Score**: ${baselineScore.score}/100
5451
+
5452
+ | Check | Passed | Points | Max |
5453
+ |-------|--------|--------|-----|
5454
+ ` + baselineScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
5455
+ report.addSection("Generation: Target Agents", targetAgent.join(", "));
5456
+ }
5343
5457
  const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length || fingerprint.existingConfigs.agentsMd);
5344
5458
  const NON_LLM_CHECKS = /* @__PURE__ */ new Set(["hooks_configured", "agents_md_exists", "permissions_configured", "mcp_servers"]);
5345
5459
  if (hasExistingConfig && baselineScore.score === 100) {
@@ -5393,6 +5507,11 @@ async function initCommand(options) {
5393
5507
  console.log(chalk8.dim(" Creating config files tailored to your project.\n"));
5394
5508
  }
5395
5509
  console.log(chalk8.dim(" This can take a couple of minutes depending on your model and provider.\n"));
5510
+ if (report) {
5511
+ report.markStep("Generation");
5512
+ const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
5513
+ report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
5514
+ }
5396
5515
  trackInitGenerationStarted(!!failingChecks);
5397
5516
  const genStartTime = Date.now();
5398
5517
  const genSpinner = ora2("Generating setup...").start();
@@ -5440,6 +5559,10 @@ async function initCommand(options) {
5440
5559
  }
5441
5560
  throw new Error("__exit__");
5442
5561
  }
5562
+ if (report) {
5563
+ if (rawOutput) report.addCodeBlock("Generation: Raw LLM Response", rawOutput);
5564
+ report.addJson("Generation: Parsed Setup", generatedSetup);
5565
+ }
5443
5566
  const elapsedMs = Date.now() - genStartTime;
5444
5567
  trackInitGenerationCompleted(elapsedMs, 0);
5445
5568
  const mins = Math.floor(elapsedMs / 6e4);
@@ -5587,6 +5710,14 @@ async function initCommand(options) {
5587
5710
  console.log(chalk8.dim(" Run ") + chalk8.hex("#83D1EB")("caliber onboard --force") + chalk8.dim(" to override.\n"));
5588
5711
  return;
5589
5712
  }
5713
+ if (report) {
5714
+ report.markStep("Post-write scoring");
5715
+ report.addSection("Scoring: Post-Write", `**Score**: ${afterScore.score}/100 (delta: ${afterScore.score - baselineScore.score >= 0 ? "+" : ""}${afterScore.score - baselineScore.score})
5716
+
5717
+ | Check | Passed | Points | Max |
5718
+ |-------|--------|--------|-----|
5719
+ ` + afterScore.checks.map((c) => `| ${c.name} | ${c.passed ? "Yes" : "No"} | ${c.points} | ${c.maxPoints} |`).join("\n"));
5720
+ }
5590
5721
  displayScoreDelta(baselineScore, afterScore);
5591
5722
  console.log(title.bold("\n Step 6/6 \u2014 Community skills\n"));
5592
5723
  console.log(chalk8.dim(" Search public skill registries for skills that match your tech stack.\n"));
@@ -5618,6 +5749,13 @@ async function initCommand(options) {
5618
5749
  console.log(` ${title("caliber skills")} Discover community skills for your stack`);
5619
5750
  console.log(` ${title("caliber undo")} Revert all changes from this run`);
5620
5751
  console.log("");
5752
+ if (report) {
5753
+ report.markStep("Finished");
5754
+ const reportPath = path19.join(process.cwd(), ".caliber", "debug-report.md");
5755
+ report.write(reportPath);
5756
+ console.log(chalk8.dim(` Debug report written to ${path19.relative(process.cwd(), reportPath)}
5757
+ `));
5758
+ }
5621
5759
  }
5622
5760
  async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5623
5761
  while (true) {
@@ -5662,7 +5800,7 @@ async function refineLoop(currentSetup, _targetAgent, sessionHistory) {
5662
5800
  }
5663
5801
  function summarizeSetup(action, setup) {
5664
5802
  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(", ");
5803
+ const files = descriptions ? Object.entries(descriptions).map(([path26, desc]) => ` ${path26}: ${desc}`).join("\n") : Object.keys(setup).filter((k) => k !== "targetAgent" && k !== "fileDescriptions").join(", ");
5666
5804
  return `${action}. Files:
5667
5805
  ${files}`;
5668
5806
  }
@@ -5775,7 +5913,7 @@ function printSetupSummary(setup) {
5775
5913
  };
5776
5914
  if (claude) {
5777
5915
  if (claude.claudeMd) {
5778
- const icon = fs23.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5916
+ const icon = fs24.existsSync("CLAUDE.md") ? chalk8.yellow("~") : chalk8.green("+");
5779
5917
  const desc = getDescription("CLAUDE.md");
5780
5918
  console.log(` ${icon} ${chalk8.bold("CLAUDE.md")}`);
5781
5919
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5785,7 +5923,7 @@ function printSetupSummary(setup) {
5785
5923
  if (Array.isArray(skills) && skills.length > 0) {
5786
5924
  for (const skill of skills) {
5787
5925
  const skillPath = `.claude/skills/${skill.name}/SKILL.md`;
5788
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5926
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5789
5927
  const desc = getDescription(skillPath);
5790
5928
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5791
5929
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5796,7 +5934,7 @@ function printSetupSummary(setup) {
5796
5934
  const codex = setup.codex;
5797
5935
  if (codex) {
5798
5936
  if (codex.agentsMd) {
5799
- const icon = fs23.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5937
+ const icon = fs24.existsSync("AGENTS.md") ? chalk8.yellow("~") : chalk8.green("+");
5800
5938
  const desc = getDescription("AGENTS.md");
5801
5939
  console.log(` ${icon} ${chalk8.bold("AGENTS.md")}`);
5802
5940
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5806,7 +5944,7 @@ function printSetupSummary(setup) {
5806
5944
  if (Array.isArray(codexSkills) && codexSkills.length > 0) {
5807
5945
  for (const skill of codexSkills) {
5808
5946
  const skillPath = `.agents/skills/${skill.name}/SKILL.md`;
5809
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5947
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5810
5948
  const desc = getDescription(skillPath);
5811
5949
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5812
5950
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5816,7 +5954,7 @@ function printSetupSummary(setup) {
5816
5954
  }
5817
5955
  if (cursor) {
5818
5956
  if (cursor.cursorrules) {
5819
- const icon = fs23.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5957
+ const icon = fs24.existsSync(".cursorrules") ? chalk8.yellow("~") : chalk8.green("+");
5820
5958
  const desc = getDescription(".cursorrules");
5821
5959
  console.log(` ${icon} ${chalk8.bold(".cursorrules")}`);
5822
5960
  if (desc) console.log(chalk8.dim(` ${desc}`));
@@ -5826,7 +5964,7 @@ function printSetupSummary(setup) {
5826
5964
  if (Array.isArray(cursorSkills) && cursorSkills.length > 0) {
5827
5965
  for (const skill of cursorSkills) {
5828
5966
  const skillPath = `.cursor/skills/${skill.name}/SKILL.md`;
5829
- const icon = fs23.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5967
+ const icon = fs24.existsSync(skillPath) ? chalk8.yellow("~") : chalk8.green("+");
5830
5968
  const desc = getDescription(skillPath);
5831
5969
  console.log(` ${icon} ${chalk8.bold(skillPath)}`);
5832
5970
  console.log(chalk8.dim(` ${desc || skill.description || skill.name}`));
@@ -5837,7 +5975,7 @@ function printSetupSummary(setup) {
5837
5975
  if (Array.isArray(rules) && rules.length > 0) {
5838
5976
  for (const rule of rules) {
5839
5977
  const rulePath = `.cursor/rules/${rule.filename}`;
5840
- const icon = fs23.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5978
+ const icon = fs24.existsSync(rulePath) ? chalk8.yellow("~") : chalk8.green("+");
5841
5979
  const desc = getDescription(rulePath);
5842
5980
  console.log(` ${icon} ${chalk8.bold(rulePath)}`);
5843
5981
  if (desc) {
@@ -5850,7 +5988,7 @@ function printSetupSummary(setup) {
5850
5988
  }
5851
5989
  }
5852
5990
  }
5853
- if (!codex && !fs23.existsSync("AGENTS.md")) {
5991
+ if (!codex && !fs24.existsSync("AGENTS.md")) {
5854
5992
  console.log(` ${chalk8.green("+")} ${chalk8.bold("AGENTS.md")}`);
5855
5993
  console.log(chalk8.dim(" Cross-agent coordination file"));
5856
5994
  console.log("");
@@ -5869,8 +6007,8 @@ function ensurePermissions() {
5869
6007
  const settingsPath = ".claude/settings.json";
5870
6008
  let settings = {};
5871
6009
  try {
5872
- if (fs23.existsSync(settingsPath)) {
5873
- settings = JSON.parse(fs23.readFileSync(settingsPath, "utf-8"));
6010
+ if (fs24.existsSync(settingsPath)) {
6011
+ settings = JSON.parse(fs24.readFileSync(settingsPath, "utf-8"));
5874
6012
  }
5875
6013
  } catch {
5876
6014
  }
@@ -5884,8 +6022,8 @@ function ensurePermissions() {
5884
6022
  "Bash(git *)"
5885
6023
  ];
5886
6024
  settings.permissions = permissions;
5887
- if (!fs23.existsSync(".claude")) fs23.mkdirSync(".claude", { recursive: true });
5888
- fs23.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
6025
+ if (!fs24.existsSync(".claude")) fs24.mkdirSync(".claude", { recursive: true });
6026
+ fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5889
6027
  }
5890
6028
 
5891
6029
  // src/commands/undo.ts
@@ -5922,7 +6060,7 @@ function undoCommand() {
5922
6060
 
5923
6061
  // src/commands/status.ts
5924
6062
  import chalk10 from "chalk";
5925
- import fs24 from "fs";
6063
+ import fs25 from "fs";
5926
6064
  init_config();
5927
6065
  async function statusCommand(options) {
5928
6066
  const config = loadConfig();
@@ -5949,7 +6087,7 @@ async function statusCommand(options) {
5949
6087
  }
5950
6088
  console.log(` Files managed: ${chalk10.cyan(manifest.entries.length.toString())}`);
5951
6089
  for (const entry of manifest.entries) {
5952
- const exists = fs24.existsSync(entry.path);
6090
+ const exists = fs25.existsSync(entry.path);
5953
6091
  const icon = exists ? chalk10.green("\u2713") : chalk10.red("\u2717");
5954
6092
  console.log(` ${icon} ${entry.path} (${entry.action})`);
5955
6093
  }
@@ -6130,8 +6268,8 @@ async function scoreCommand(options) {
6130
6268
  }
6131
6269
 
6132
6270
  // src/commands/refresh.ts
6133
- import fs26 from "fs";
6134
- import path19 from "path";
6271
+ import fs27 from "fs";
6272
+ import path21 from "path";
6135
6273
  import chalk13 from "chalk";
6136
6274
  import ora5 from "ora";
6137
6275
 
@@ -6208,37 +6346,37 @@ function collectDiff(lastSha) {
6208
6346
  }
6209
6347
 
6210
6348
  // src/writers/refresh.ts
6211
- import fs25 from "fs";
6212
- import path18 from "path";
6349
+ import fs26 from "fs";
6350
+ import path20 from "path";
6213
6351
  function writeRefreshDocs(docs) {
6214
6352
  const written = [];
6215
6353
  if (docs.claudeMd) {
6216
- fs25.writeFileSync("CLAUDE.md", docs.claudeMd);
6354
+ fs26.writeFileSync("CLAUDE.md", docs.claudeMd);
6217
6355
  written.push("CLAUDE.md");
6218
6356
  }
6219
6357
  if (docs.readmeMd) {
6220
- fs25.writeFileSync("README.md", docs.readmeMd);
6358
+ fs26.writeFileSync("README.md", docs.readmeMd);
6221
6359
  written.push("README.md");
6222
6360
  }
6223
6361
  if (docs.cursorrules) {
6224
- fs25.writeFileSync(".cursorrules", docs.cursorrules);
6362
+ fs26.writeFileSync(".cursorrules", docs.cursorrules);
6225
6363
  written.push(".cursorrules");
6226
6364
  }
6227
6365
  if (docs.cursorRules) {
6228
- const rulesDir = path18.join(".cursor", "rules");
6229
- if (!fs25.existsSync(rulesDir)) fs25.mkdirSync(rulesDir, { recursive: true });
6366
+ const rulesDir = path20.join(".cursor", "rules");
6367
+ if (!fs26.existsSync(rulesDir)) fs26.mkdirSync(rulesDir, { recursive: true });
6230
6368
  for (const rule of docs.cursorRules) {
6231
- const filePath = path18.join(rulesDir, rule.filename);
6232
- fs25.writeFileSync(filePath, rule.content);
6369
+ const filePath = path20.join(rulesDir, rule.filename);
6370
+ fs26.writeFileSync(filePath, rule.content);
6233
6371
  written.push(filePath);
6234
6372
  }
6235
6373
  }
6236
6374
  if (docs.claudeSkills) {
6237
- const skillsDir = path18.join(".claude", "skills");
6238
- if (!fs25.existsSync(skillsDir)) fs25.mkdirSync(skillsDir, { recursive: true });
6375
+ const skillsDir = path20.join(".claude", "skills");
6376
+ if (!fs26.existsSync(skillsDir)) fs26.mkdirSync(skillsDir, { recursive: true });
6239
6377
  for (const skill of docs.claudeSkills) {
6240
- const filePath = path18.join(skillsDir, skill.filename);
6241
- fs25.writeFileSync(filePath, skill.content);
6378
+ const filePath = path20.join(skillsDir, skill.filename);
6379
+ fs26.writeFileSync(filePath, skill.content);
6242
6380
  written.push(filePath);
6243
6381
  }
6244
6382
  }
@@ -6317,11 +6455,11 @@ function log(quiet, ...args) {
6317
6455
  function discoverGitRepos(parentDir) {
6318
6456
  const repos = [];
6319
6457
  try {
6320
- const entries = fs26.readdirSync(parentDir, { withFileTypes: true });
6458
+ const entries = fs27.readdirSync(parentDir, { withFileTypes: true });
6321
6459
  for (const entry of entries) {
6322
6460
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
6323
- const childPath = path19.join(parentDir, entry.name);
6324
- if (fs26.existsSync(path19.join(childPath, ".git"))) {
6461
+ const childPath = path21.join(parentDir, entry.name);
6462
+ if (fs27.existsSync(path21.join(childPath, ".git"))) {
6325
6463
  repos.push(childPath);
6326
6464
  }
6327
6465
  }
@@ -6418,7 +6556,7 @@ async function refreshCommand(options) {
6418
6556
  `));
6419
6557
  const originalDir = process.cwd();
6420
6558
  for (const repo of repos) {
6421
- const repoName = path19.basename(repo);
6559
+ const repoName = path21.basename(repo);
6422
6560
  try {
6423
6561
  process.chdir(repo);
6424
6562
  await refreshSingleRepo(repo, { ...options, label: repoName });
@@ -6673,8 +6811,8 @@ function readStdin() {
6673
6811
 
6674
6812
  // src/learner/storage.ts
6675
6813
  init_constants();
6676
- import fs27 from "fs";
6677
- import path20 from "path";
6814
+ import fs28 from "fs";
6815
+ import path22 from "path";
6678
6816
  var MAX_RESPONSE_LENGTH = 2e3;
6679
6817
  var DEFAULT_STATE = {
6680
6818
  sessionId: null,
@@ -6682,15 +6820,15 @@ var DEFAULT_STATE = {
6682
6820
  lastAnalysisTimestamp: null
6683
6821
  };
6684
6822
  function ensureLearningDir() {
6685
- if (!fs27.existsSync(LEARNING_DIR)) {
6686
- fs27.mkdirSync(LEARNING_DIR, { recursive: true });
6823
+ if (!fs28.existsSync(LEARNING_DIR)) {
6824
+ fs28.mkdirSync(LEARNING_DIR, { recursive: true });
6687
6825
  }
6688
6826
  }
6689
6827
  function sessionFilePath() {
6690
- return path20.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6828
+ return path22.join(LEARNING_DIR, LEARNING_SESSION_FILE);
6691
6829
  }
6692
6830
  function stateFilePath() {
6693
- return path20.join(LEARNING_DIR, LEARNING_STATE_FILE);
6831
+ return path22.join(LEARNING_DIR, LEARNING_STATE_FILE);
6694
6832
  }
6695
6833
  function truncateResponse(response) {
6696
6834
  const str = JSON.stringify(response);
@@ -6701,50 +6839,50 @@ function appendEvent(event) {
6701
6839
  ensureLearningDir();
6702
6840
  const truncated = { ...event, tool_response: truncateResponse(event.tool_response) };
6703
6841
  const filePath = sessionFilePath();
6704
- fs27.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6842
+ fs28.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
6705
6843
  const count = getEventCount();
6706
6844
  if (count > LEARNING_MAX_EVENTS) {
6707
- const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6845
+ const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6708
6846
  const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
6709
- fs27.writeFileSync(filePath, kept.join("\n") + "\n");
6847
+ fs28.writeFileSync(filePath, kept.join("\n") + "\n");
6710
6848
  }
6711
6849
  }
6712
6850
  function readAllEvents() {
6713
6851
  const filePath = sessionFilePath();
6714
- if (!fs27.existsSync(filePath)) return [];
6715
- const lines = fs27.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6852
+ if (!fs28.existsSync(filePath)) return [];
6853
+ const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
6716
6854
  return lines.map((line) => JSON.parse(line));
6717
6855
  }
6718
6856
  function getEventCount() {
6719
6857
  const filePath = sessionFilePath();
6720
- if (!fs27.existsSync(filePath)) return 0;
6721
- const content = fs27.readFileSync(filePath, "utf-8");
6858
+ if (!fs28.existsSync(filePath)) return 0;
6859
+ const content = fs28.readFileSync(filePath, "utf-8");
6722
6860
  return content.split("\n").filter(Boolean).length;
6723
6861
  }
6724
6862
  function clearSession() {
6725
6863
  const filePath = sessionFilePath();
6726
- if (fs27.existsSync(filePath)) fs27.unlinkSync(filePath);
6864
+ if (fs28.existsSync(filePath)) fs28.unlinkSync(filePath);
6727
6865
  }
6728
6866
  function readState2() {
6729
6867
  const filePath = stateFilePath();
6730
- if (!fs27.existsSync(filePath)) return { ...DEFAULT_STATE };
6868
+ if (!fs28.existsSync(filePath)) return { ...DEFAULT_STATE };
6731
6869
  try {
6732
- return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
6870
+ return JSON.parse(fs28.readFileSync(filePath, "utf-8"));
6733
6871
  } catch {
6734
6872
  return { ...DEFAULT_STATE };
6735
6873
  }
6736
6874
  }
6737
6875
  function writeState2(state) {
6738
6876
  ensureLearningDir();
6739
- fs27.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6877
+ fs28.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2));
6740
6878
  }
6741
6879
  function resetState() {
6742
6880
  writeState2({ ...DEFAULT_STATE });
6743
6881
  }
6744
6882
 
6745
6883
  // src/learner/writer.ts
6746
- import fs28 from "fs";
6747
- import path21 from "path";
6884
+ import fs29 from "fs";
6885
+ import path23 from "path";
6748
6886
  var LEARNED_START = "<!-- caliber:learned -->";
6749
6887
  var LEARNED_END = "<!-- /caliber:learned -->";
6750
6888
  function writeLearnedContent(update) {
@@ -6764,8 +6902,8 @@ function writeLearnedContent(update) {
6764
6902
  function writeLearnedSection(content) {
6765
6903
  const claudeMdPath = "CLAUDE.md";
6766
6904
  let existing = "";
6767
- if (fs28.existsSync(claudeMdPath)) {
6768
- existing = fs28.readFileSync(claudeMdPath, "utf-8");
6905
+ if (fs29.existsSync(claudeMdPath)) {
6906
+ existing = fs29.readFileSync(claudeMdPath, "utf-8");
6769
6907
  }
6770
6908
  const section = `${LEARNED_START}
6771
6909
  ${content}
@@ -6779,15 +6917,15 @@ ${LEARNED_END}`;
6779
6917
  const separator = existing.endsWith("\n") || existing === "" ? "" : "\n";
6780
6918
  updated = existing + separator + "\n" + section + "\n";
6781
6919
  }
6782
- fs28.writeFileSync(claudeMdPath, updated);
6920
+ fs29.writeFileSync(claudeMdPath, updated);
6783
6921
  }
6784
6922
  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);
6923
+ const skillDir = path23.join(".claude", "skills", skill.name);
6924
+ if (!fs29.existsSync(skillDir)) fs29.mkdirSync(skillDir, { recursive: true });
6925
+ const skillPath = path23.join(skillDir, "SKILL.md");
6926
+ if (!skill.isNew && fs29.existsSync(skillPath)) {
6927
+ const existing = fs29.readFileSync(skillPath, "utf-8");
6928
+ fs29.writeFileSync(skillPath, existing.trimEnd() + "\n\n" + skill.content);
6791
6929
  } else {
6792
6930
  const frontmatter = [
6793
6931
  "---",
@@ -6796,14 +6934,14 @@ function writeLearnedSkill(skill) {
6796
6934
  "---",
6797
6935
  ""
6798
6936
  ].join("\n");
6799
- fs28.writeFileSync(skillPath, frontmatter + skill.content);
6937
+ fs29.writeFileSync(skillPath, frontmatter + skill.content);
6800
6938
  }
6801
6939
  return skillPath;
6802
6940
  }
6803
6941
  function readLearnedSection() {
6804
6942
  const claudeMdPath = "CLAUDE.md";
6805
- if (!fs28.existsSync(claudeMdPath)) return null;
6806
- const content = fs28.readFileSync(claudeMdPath, "utf-8");
6943
+ if (!fs29.existsSync(claudeMdPath)) return null;
6944
+ const content = fs29.readFileSync(claudeMdPath, "utf-8");
6807
6945
  const startIdx = content.indexOf(LEARNED_START);
6808
6946
  const endIdx = content.indexOf(LEARNED_END);
6809
6947
  if (startIdx === -1 || endIdx === -1) return null;
@@ -6992,9 +7130,9 @@ Learned items in CLAUDE.md: ${chalk16.cyan(String(lineCount))}`);
6992
7130
  }
6993
7131
 
6994
7132
  // src/cli.ts
6995
- var __dirname = path22.dirname(fileURLToPath(import.meta.url));
7133
+ var __dirname = path24.dirname(fileURLToPath(import.meta.url));
6996
7134
  var pkg = JSON.parse(
6997
- fs29.readFileSync(path22.resolve(__dirname, "..", "package.json"), "utf-8")
7135
+ fs30.readFileSync(path24.resolve(__dirname, "..", "package.json"), "utf-8")
6998
7136
  );
6999
7137
  var program = new Command();
7000
7138
  var displayVersion = process.env.CALIBER_LOCAL ? `${pkg.version}-local` : pkg.version;
@@ -7051,7 +7189,7 @@ function parseAgentOption(value) {
7051
7189
  }
7052
7190
  return agents;
7053
7191
  }
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));
7192
+ 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
7193
  program.command("undo").description("Revert all config changes made by Caliber").action(tracked("undo", undoCommand));
7056
7194
  program.command("status").description("Show current Caliber setup status").option("--json", "Output as JSON").action(tracked("status", statusCommand));
7057
7195
  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 +7206,22 @@ learn.command("remove").description("Remove learning hooks from .claude/settings
7068
7206
  learn.command("status").description("Show learning system status").action(tracked("learn:status", learnStatusCommand));
7069
7207
 
7070
7208
  // src/utils/version-check.ts
7071
- import fs30 from "fs";
7072
- import path23 from "path";
7209
+ import fs31 from "fs";
7210
+ import path25 from "path";
7073
7211
  import { fileURLToPath as fileURLToPath2 } from "url";
7074
7212
  import { execSync as execSync11 } from "child_process";
7075
7213
  import chalk17 from "chalk";
7076
7214
  import ora6 from "ora";
7077
7215
  import confirm from "@inquirer/confirm";
7078
- var __dirname_vc = path23.dirname(fileURLToPath2(import.meta.url));
7216
+ var __dirname_vc = path25.dirname(fileURLToPath2(import.meta.url));
7079
7217
  var pkg2 = JSON.parse(
7080
- fs30.readFileSync(path23.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7218
+ fs31.readFileSync(path25.resolve(__dirname_vc, "..", "package.json"), "utf-8")
7081
7219
  );
7082
7220
  function getInstalledVersion() {
7083
7221
  try {
7084
7222
  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;
7223
+ const pkgPath = path25.join(globalRoot, "@rely-ai", "caliber", "package.json");
7224
+ return JSON.parse(fs31.readFileSync(pkgPath, "utf-8")).version;
7087
7225
  } catch {
7088
7226
  return null;
7089
7227
  }
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.6",
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": {