@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.
- package/dist/bin.js +236 -91
- 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
|
|
169
|
-
import
|
|
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
|
|
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(
|
|
3253
|
+
function readFileOrNull(path26) {
|
|
3246
3254
|
try {
|
|
3247
|
-
return readFileSync(
|
|
3255
|
+
return readFileSync(path26, "utf-8");
|
|
3248
3256
|
} catch {
|
|
3249
3257
|
return null;
|
|
3250
3258
|
}
|
|
3251
3259
|
}
|
|
3252
|
-
function readJsonOrNull(
|
|
3253
|
-
const content = readFileOrNull(
|
|
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(
|
|
3629
|
+
function readFileOrNull2(path26) {
|
|
3622
3630
|
try {
|
|
3623
|
-
return readFileSync3(
|
|
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(
|
|
3784
|
+
function readFileOrNull3(path26) {
|
|
3777
3785
|
try {
|
|
3778
|
-
return readFileSync4(
|
|
3786
|
+
return readFileSync4(path26, "utf-8");
|
|
3779
3787
|
} catch {
|
|
3780
3788
|
return null;
|
|
3781
3789
|
}
|
|
3782
3790
|
}
|
|
3783
|
-
function readJsonOrNull2(
|
|
3784
|
-
const content = readFileOrNull3(
|
|
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(
|
|
3975
|
+
function readFileOrNull4(path26) {
|
|
3968
3976
|
try {
|
|
3969
|
-
return readFileSync5(
|
|
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(
|
|
4091
|
+
function readFileOrNull5(path26) {
|
|
4084
4092
|
try {
|
|
4085
|
-
return readFileSync6(
|
|
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(([
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 && !
|
|
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 (
|
|
5873
|
-
settings = JSON.parse(
|
|
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 (!
|
|
5888
|
-
|
|
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
|
|
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 =
|
|
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
|
|
6134
|
-
import
|
|
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
|
|
6212
|
-
import
|
|
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
|
-
|
|
6361
|
+
fs26.writeFileSync("CLAUDE.md", docs.claudeMd);
|
|
6217
6362
|
written.push("CLAUDE.md");
|
|
6218
6363
|
}
|
|
6219
6364
|
if (docs.readmeMd) {
|
|
6220
|
-
|
|
6365
|
+
fs26.writeFileSync("README.md", docs.readmeMd);
|
|
6221
6366
|
written.push("README.md");
|
|
6222
6367
|
}
|
|
6223
6368
|
if (docs.cursorrules) {
|
|
6224
|
-
|
|
6369
|
+
fs26.writeFileSync(".cursorrules", docs.cursorrules);
|
|
6225
6370
|
written.push(".cursorrules");
|
|
6226
6371
|
}
|
|
6227
6372
|
if (docs.cursorRules) {
|
|
6228
|
-
const rulesDir =
|
|
6229
|
-
if (!
|
|
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 =
|
|
6232
|
-
|
|
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 =
|
|
6238
|
-
if (!
|
|
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 =
|
|
6241
|
-
|
|
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 =
|
|
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 =
|
|
6324
|
-
if (
|
|
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 =
|
|
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
|
|
6677
|
-
import
|
|
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 (!
|
|
6686
|
-
|
|
6830
|
+
if (!fs28.existsSync(LEARNING_DIR)) {
|
|
6831
|
+
fs28.mkdirSync(LEARNING_DIR, { recursive: true });
|
|
6687
6832
|
}
|
|
6688
6833
|
}
|
|
6689
6834
|
function sessionFilePath() {
|
|
6690
|
-
return
|
|
6835
|
+
return path22.join(LEARNING_DIR, LEARNING_SESSION_FILE);
|
|
6691
6836
|
}
|
|
6692
6837
|
function stateFilePath() {
|
|
6693
|
-
return
|
|
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
|
-
|
|
6849
|
+
fs28.appendFileSync(filePath, JSON.stringify(truncated) + "\n");
|
|
6705
6850
|
const count = getEventCount();
|
|
6706
6851
|
if (count > LEARNING_MAX_EVENTS) {
|
|
6707
|
-
const lines =
|
|
6852
|
+
const lines = fs28.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
6708
6853
|
const kept = lines.slice(lines.length - LEARNING_MAX_EVENTS);
|
|
6709
|
-
|
|
6854
|
+
fs28.writeFileSync(filePath, kept.join("\n") + "\n");
|
|
6710
6855
|
}
|
|
6711
6856
|
}
|
|
6712
6857
|
function readAllEvents() {
|
|
6713
6858
|
const filePath = sessionFilePath();
|
|
6714
|
-
if (!
|
|
6715
|
-
const lines =
|
|
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 (!
|
|
6721
|
-
const content =
|
|
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 (
|
|
6871
|
+
if (fs28.existsSync(filePath)) fs28.unlinkSync(filePath);
|
|
6727
6872
|
}
|
|
6728
6873
|
function readState2() {
|
|
6729
6874
|
const filePath = stateFilePath();
|
|
6730
|
-
if (!
|
|
6875
|
+
if (!fs28.existsSync(filePath)) return { ...DEFAULT_STATE };
|
|
6731
6876
|
try {
|
|
6732
|
-
return JSON.parse(
|
|
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
|
-
|
|
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
|
|
6747
|
-
import
|
|
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 (
|
|
6768
|
-
existing =
|
|
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
|
-
|
|
6927
|
+
fs29.writeFileSync(claudeMdPath, updated);
|
|
6783
6928
|
}
|
|
6784
6929
|
function writeLearnedSkill(skill) {
|
|
6785
|
-
const skillDir =
|
|
6786
|
-
if (!
|
|
6787
|
-
const skillPath =
|
|
6788
|
-
if (!skill.isNew &&
|
|
6789
|
-
const existing =
|
|
6790
|
-
|
|
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
|
-
|
|
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 (!
|
|
6806
|
-
const content =
|
|
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 =
|
|
7140
|
+
var __dirname = path24.dirname(fileURLToPath(import.meta.url));
|
|
6996
7141
|
var pkg = JSON.parse(
|
|
6997
|
-
|
|
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
|
|
7072
|
-
import
|
|
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 =
|
|
7223
|
+
var __dirname_vc = path25.dirname(fileURLToPath2(import.meta.url));
|
|
7079
7224
|
var pkg2 = JSON.parse(
|
|
7080
|
-
|
|
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 =
|
|
7086
|
-
return JSON.parse(
|
|
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