@rely-ai/caliber 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +162 -63
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -3555,10 +3555,10 @@ function checkBonus(dir) {
|
|
|
3555
3555
|
if (settingsContent) {
|
|
3556
3556
|
try {
|
|
3557
3557
|
const settings = JSON.parse(settingsContent);
|
|
3558
|
-
const
|
|
3559
|
-
if (
|
|
3558
|
+
const hooks = settings.hooks;
|
|
3559
|
+
if (hooks && Object.keys(hooks).length > 0) {
|
|
3560
3560
|
hasClaudeHooks = true;
|
|
3561
|
-
hookSources.push(`Claude Code: ${Object.keys(
|
|
3561
|
+
hookSources.push(`Claude Code: ${Object.keys(hooks).join(", ")}`);
|
|
3562
3562
|
}
|
|
3563
3563
|
} catch {
|
|
3564
3564
|
}
|
|
@@ -3796,7 +3796,9 @@ function displayScoreDelta(before, after) {
|
|
|
3796
3796
|
|
|
3797
3797
|
// src/commands/init.ts
|
|
3798
3798
|
async function initCommand(options) {
|
|
3799
|
-
|
|
3799
|
+
const brand = chalk4.hex("#EB9D83");
|
|
3800
|
+
const title = chalk4.hex("#83D1EB");
|
|
3801
|
+
console.log(brand.bold(`
|
|
3800
3802
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
3801
3803
|
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
3802
3804
|
\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
@@ -3805,17 +3807,17 @@ async function initCommand(options) {
|
|
|
3805
3807
|
\u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
3806
3808
|
`));
|
|
3807
3809
|
console.log(chalk4.dim(" Configure your coding agent environment\n"));
|
|
3808
|
-
console.log(
|
|
3810
|
+
console.log(title.bold(" What is Caliber?\n"));
|
|
3809
3811
|
console.log(chalk4.dim(" Caliber audits your AI agent configurations and suggests targeted"));
|
|
3810
3812
|
console.log(chalk4.dim(" improvements. It analyzes CLAUDE.md, .cursorrules, and skills"));
|
|
3811
3813
|
console.log(chalk4.dim(" against your actual codebase \u2014 keeping what works, fixing"));
|
|
3812
3814
|
console.log(chalk4.dim(" what's stale, and adding what's missing.\n"));
|
|
3813
|
-
console.log(
|
|
3815
|
+
console.log(title.bold(" How it works:\n"));
|
|
3814
3816
|
console.log(chalk4.dim(" 1. Scan Analyze your code, dependencies, and existing configs"));
|
|
3815
3817
|
console.log(chalk4.dim(" 2. Generate AI creates or improves config files for your project"));
|
|
3816
3818
|
console.log(chalk4.dim(" 3. Review You accept, refine, or decline the proposed changes"));
|
|
3817
3819
|
console.log(chalk4.dim(" 4. Apply Config files are written with backups\n"));
|
|
3818
|
-
console.log(
|
|
3820
|
+
console.log(title.bold(" Step 1/4 \u2014 How do you want to use Caliber?\n"));
|
|
3819
3821
|
let config = loadConfig();
|
|
3820
3822
|
if (!config) {
|
|
3821
3823
|
console.log(chalk4.dim(" No LLM provider set yet. Choose how to run Caliber:\n"));
|
|
@@ -3837,7 +3839,7 @@ async function initCommand(options) {
|
|
|
3837
3839
|
const displayModel = config.model === "default" && config.provider === "claude-cli" ? process.env.ANTHROPIC_MODEL || "default (inherited from Claude Code)" : config.model;
|
|
3838
3840
|
console.log(chalk4.dim(` Provider: ${config.provider} | Model: ${displayModel}
|
|
3839
3841
|
`));
|
|
3840
|
-
console.log(
|
|
3842
|
+
console.log(title.bold(" Step 2/4 \u2014 Scan project\n"));
|
|
3841
3843
|
console.log(chalk4.dim(" Detecting languages, dependencies, file structure, and existing configs.\n"));
|
|
3842
3844
|
const spinner = ora("Analyzing project...").start();
|
|
3843
3845
|
const fingerprint = collectFingerprint(process.cwd());
|
|
@@ -3848,7 +3850,7 @@ async function initCommand(options) {
|
|
|
3848
3850
|
`));
|
|
3849
3851
|
const targetAgent = options.agent || await promptAgent();
|
|
3850
3852
|
const baselineScore = computeLocalScore(process.cwd(), targetAgent);
|
|
3851
|
-
console.log(
|
|
3853
|
+
console.log(title.bold(" Current project score\n"));
|
|
3852
3854
|
displayScore(baselineScore);
|
|
3853
3855
|
const hasExistingConfig = !!(fingerprint.existingConfigs.claudeMd || fingerprint.existingConfigs.claudeSettings || fingerprint.existingConfigs.claudeSkills?.length || fingerprint.existingConfigs.cursorrules || fingerprint.existingConfigs.cursorRules?.length);
|
|
3854
3856
|
if (hasExistingConfig && baselineScore.score === 100) {
|
|
@@ -3868,7 +3870,7 @@ async function initCommand(options) {
|
|
|
3868
3870
|
passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
|
|
3869
3871
|
currentScore = baselineScore.score;
|
|
3870
3872
|
if (failingChecks.length > 0) {
|
|
3871
|
-
console.log(
|
|
3873
|
+
console.log(title.bold(" Step 3/4 \u2014 Targeted fixes\n"));
|
|
3872
3874
|
console.log(chalk4.dim(` Score is ${baselineScore.score}/100 \u2014 only fixing ${failingChecks.length} remaining issue${failingChecks.length === 1 ? "" : "s"}:
|
|
3873
3875
|
`));
|
|
3874
3876
|
for (const check of failingChecks) {
|
|
@@ -3877,11 +3879,11 @@ async function initCommand(options) {
|
|
|
3877
3879
|
console.log("");
|
|
3878
3880
|
}
|
|
3879
3881
|
} else if (hasExistingConfig) {
|
|
3880
|
-
console.log(
|
|
3882
|
+
console.log(title.bold(" Step 3/4 \u2014 Auditing your configs\n"));
|
|
3881
3883
|
console.log(chalk4.dim(" AI is reviewing your existing configs against your codebase"));
|
|
3882
3884
|
console.log(chalk4.dim(" and suggesting improvements.\n"));
|
|
3883
3885
|
} else {
|
|
3884
|
-
console.log(
|
|
3886
|
+
console.log(title.bold(" Step 3/4 \u2014 Generating configs\n"));
|
|
3885
3887
|
console.log(chalk4.dim(" AI is creating agent config files tailored to your project.\n"));
|
|
3886
3888
|
}
|
|
3887
3889
|
console.log(chalk4.dim(" This can take a couple of minutes depending on your model and provider.\n"));
|
|
@@ -3937,7 +3939,7 @@ async function initCommand(options) {
|
|
|
3937
3939
|
const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
|
|
3938
3940
|
genSpinner.succeed(`Setup generated ${chalk4.dim(`in ${timeStr}`)}`);
|
|
3939
3941
|
printSetupSummary(generatedSetup);
|
|
3940
|
-
console.log(
|
|
3942
|
+
console.log(title.bold(" Step 4/4 \u2014 Review\n"));
|
|
3941
3943
|
const setupFiles = collectSetupFiles(generatedSetup);
|
|
3942
3944
|
const staged = stageFiles(setupFiles, process.cwd());
|
|
3943
3945
|
console.log(chalk4.dim(` ${chalk4.green(`${staged.newFiles} new`)} / ${chalk4.yellow(`${staged.modifiedFiles} modified`)} file${staged.newFiles + staged.modifiedFiles !== 1 ? "s" : ""}
|
|
@@ -4061,7 +4063,7 @@ async function initCommand(options) {
|
|
|
4061
4063
|
console.log(chalk4.bold.green(" Setup complete! Your coding agent is now configured."));
|
|
4062
4064
|
console.log(chalk4.dim(" Run `caliber undo` to revert changes.\n"));
|
|
4063
4065
|
console.log(chalk4.bold(" Next steps:\n"));
|
|
4064
|
-
console.log(` ${
|
|
4066
|
+
console.log(` ${title("caliber undo")} Revert all changes from this run`);
|
|
4065
4067
|
console.log("");
|
|
4066
4068
|
}
|
|
4067
4069
|
async function refineLoop(currentSetup, _targetAgent) {
|
|
@@ -5465,60 +5467,162 @@ async function refreshCommand(options) {
|
|
|
5465
5467
|
|
|
5466
5468
|
// src/commands/hooks.ts
|
|
5467
5469
|
import chalk11 from "chalk";
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5470
|
+
var HOOKS = [
|
|
5471
|
+
{
|
|
5472
|
+
id: "session-end",
|
|
5473
|
+
label: "Claude Code SessionEnd",
|
|
5474
|
+
description: "Auto-refresh CLAUDE.md when a Claude Code session ends",
|
|
5475
|
+
isInstalled: isHookInstalled,
|
|
5476
|
+
install: installHook,
|
|
5477
|
+
remove: removeHook
|
|
5478
|
+
},
|
|
5479
|
+
{
|
|
5480
|
+
id: "pre-commit",
|
|
5481
|
+
label: "Git pre-commit",
|
|
5482
|
+
description: "Auto-refresh CLAUDE.md before each git commit",
|
|
5483
|
+
isInstalled: isPreCommitHookInstalled,
|
|
5484
|
+
install: installPreCommitHook,
|
|
5485
|
+
remove: removePreCommitHook
|
|
5473
5486
|
}
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5487
|
+
];
|
|
5488
|
+
function printStatus() {
|
|
5489
|
+
console.log(chalk11.bold("\n Hooks\n"));
|
|
5490
|
+
for (const hook of HOOKS) {
|
|
5491
|
+
const installed = hook.isInstalled();
|
|
5492
|
+
const icon = installed ? chalk11.green("\u2713") : chalk11.dim("\u2717");
|
|
5493
|
+
const state = installed ? chalk11.green("enabled") : chalk11.dim("disabled");
|
|
5494
|
+
console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
|
|
5495
|
+
console.log(chalk11.dim(` ${hook.description}`));
|
|
5482
5496
|
}
|
|
5483
|
-
console.log(
|
|
5497
|
+
console.log("");
|
|
5484
5498
|
}
|
|
5485
|
-
async function
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5499
|
+
async function hooksCommand(options) {
|
|
5500
|
+
if (options.install) {
|
|
5501
|
+
for (const hook of HOOKS) {
|
|
5502
|
+
const result = hook.install();
|
|
5503
|
+
if (result.alreadyInstalled) {
|
|
5504
|
+
console.log(chalk11.dim(` ${hook.label} already enabled.`));
|
|
5505
|
+
} else {
|
|
5506
|
+
console.log(chalk11.green(" \u2713") + ` ${hook.label} enabled`);
|
|
5507
|
+
}
|
|
5508
|
+
}
|
|
5489
5509
|
return;
|
|
5490
5510
|
}
|
|
5491
|
-
if (
|
|
5492
|
-
|
|
5511
|
+
if (options.remove) {
|
|
5512
|
+
for (const hook of HOOKS) {
|
|
5513
|
+
const result = hook.remove();
|
|
5514
|
+
if (result.notFound) {
|
|
5515
|
+
console.log(chalk11.dim(` ${hook.label} already disabled.`));
|
|
5516
|
+
} else {
|
|
5517
|
+
console.log(chalk11.green(" \u2713") + ` ${hook.label} removed`);
|
|
5518
|
+
}
|
|
5519
|
+
}
|
|
5493
5520
|
return;
|
|
5494
5521
|
}
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
}
|
|
5498
|
-
async function hooksRemovePrecommitCommand() {
|
|
5499
|
-
const result = removePreCommitHook();
|
|
5500
|
-
if (result.notFound) {
|
|
5501
|
-
console.log(chalk11.dim("Pre-commit hook not found."));
|
|
5522
|
+
if (!process.stdin.isTTY) {
|
|
5523
|
+
printStatus();
|
|
5502
5524
|
return;
|
|
5503
5525
|
}
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
const
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5526
|
+
const { stdin, stdout } = process;
|
|
5527
|
+
let cursor = 0;
|
|
5528
|
+
let lineCount = 0;
|
|
5529
|
+
const states = HOOKS.map((h) => h.isInstalled());
|
|
5530
|
+
function render() {
|
|
5531
|
+
const lines = [];
|
|
5532
|
+
lines.push(chalk11.bold(" Hooks"));
|
|
5533
|
+
lines.push("");
|
|
5534
|
+
for (let i = 0; i < HOOKS.length; i++) {
|
|
5535
|
+
const hook = HOOKS[i];
|
|
5536
|
+
const enabled = states[i];
|
|
5537
|
+
const toggle = enabled ? chalk11.green("[on] ") : chalk11.dim("[off]");
|
|
5538
|
+
const ptr = i === cursor ? chalk11.cyan(">") : " ";
|
|
5539
|
+
lines.push(` ${ptr} ${toggle} ${hook.label}`);
|
|
5540
|
+
lines.push(chalk11.dim(` ${hook.description}`));
|
|
5541
|
+
}
|
|
5542
|
+
lines.push("");
|
|
5543
|
+
lines.push(chalk11.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
|
|
5544
|
+
return lines.join("\n");
|
|
5518
5545
|
}
|
|
5519
|
-
|
|
5520
|
-
|
|
5546
|
+
function draw(initial) {
|
|
5547
|
+
if (!initial && lineCount > 0) {
|
|
5548
|
+
stdout.write(`\x1B[${lineCount}A`);
|
|
5549
|
+
}
|
|
5550
|
+
stdout.write("\x1B[0J");
|
|
5551
|
+
const output = render();
|
|
5552
|
+
stdout.write(output + "\n");
|
|
5553
|
+
lineCount = output.split("\n").length;
|
|
5521
5554
|
}
|
|
5555
|
+
return new Promise((resolve2) => {
|
|
5556
|
+
console.log("");
|
|
5557
|
+
draw(true);
|
|
5558
|
+
stdin.setRawMode(true);
|
|
5559
|
+
stdin.resume();
|
|
5560
|
+
stdin.setEncoding("utf8");
|
|
5561
|
+
function cleanup() {
|
|
5562
|
+
stdin.removeListener("data", onData);
|
|
5563
|
+
stdin.setRawMode(false);
|
|
5564
|
+
stdin.pause();
|
|
5565
|
+
}
|
|
5566
|
+
function apply() {
|
|
5567
|
+
let changed = 0;
|
|
5568
|
+
for (let i = 0; i < HOOKS.length; i++) {
|
|
5569
|
+
const hook = HOOKS[i];
|
|
5570
|
+
const wasInstalled = hook.isInstalled();
|
|
5571
|
+
const wantEnabled = states[i];
|
|
5572
|
+
if (wantEnabled && !wasInstalled) {
|
|
5573
|
+
hook.install();
|
|
5574
|
+
console.log(chalk11.green(" \u2713") + ` ${hook.label} enabled`);
|
|
5575
|
+
changed++;
|
|
5576
|
+
} else if (!wantEnabled && wasInstalled) {
|
|
5577
|
+
hook.remove();
|
|
5578
|
+
console.log(chalk11.green(" \u2713") + ` ${hook.label} disabled`);
|
|
5579
|
+
changed++;
|
|
5580
|
+
}
|
|
5581
|
+
}
|
|
5582
|
+
if (changed === 0) {
|
|
5583
|
+
console.log(chalk11.dim(" No changes."));
|
|
5584
|
+
}
|
|
5585
|
+
console.log("");
|
|
5586
|
+
}
|
|
5587
|
+
function onData(key) {
|
|
5588
|
+
switch (key) {
|
|
5589
|
+
case "\x1B[A":
|
|
5590
|
+
cursor = (cursor - 1 + HOOKS.length) % HOOKS.length;
|
|
5591
|
+
draw(false);
|
|
5592
|
+
break;
|
|
5593
|
+
case "\x1B[B":
|
|
5594
|
+
cursor = (cursor + 1) % HOOKS.length;
|
|
5595
|
+
draw(false);
|
|
5596
|
+
break;
|
|
5597
|
+
case " ":
|
|
5598
|
+
states[cursor] = !states[cursor];
|
|
5599
|
+
draw(false);
|
|
5600
|
+
break;
|
|
5601
|
+
case "a":
|
|
5602
|
+
states.fill(true);
|
|
5603
|
+
draw(false);
|
|
5604
|
+
break;
|
|
5605
|
+
case "n":
|
|
5606
|
+
states.fill(false);
|
|
5607
|
+
draw(false);
|
|
5608
|
+
break;
|
|
5609
|
+
case "\r":
|
|
5610
|
+
case "\n":
|
|
5611
|
+
cleanup();
|
|
5612
|
+
apply();
|
|
5613
|
+
resolve2();
|
|
5614
|
+
break;
|
|
5615
|
+
case "q":
|
|
5616
|
+
case "\x1B":
|
|
5617
|
+
case "":
|
|
5618
|
+
cleanup();
|
|
5619
|
+
console.log(chalk11.dim("\n Cancelled.\n"));
|
|
5620
|
+
resolve2();
|
|
5621
|
+
break;
|
|
5622
|
+
}
|
|
5623
|
+
}
|
|
5624
|
+
stdin.on("data", onData);
|
|
5625
|
+
});
|
|
5522
5626
|
}
|
|
5523
5627
|
|
|
5524
5628
|
// src/commands/config.ts
|
|
@@ -5918,12 +6022,7 @@ program.command("config").description("Configure LLM provider, API key, and mode
|
|
|
5918
6022
|
program.command("recommend").description("Discover and install skill recommendations").option("--generate", "Force fresh recommendation search").action(recommendCommand);
|
|
5919
6023
|
program.command("score").description("Score your current agent config setup (deterministic, no network)").option("--json", "Output as JSON").option("--quiet", "One-line output for scripts/hooks").option("--agent <type>", "Target agent: claude, cursor, or both").action(scoreCommand);
|
|
5920
6024
|
program.command("refresh").description("Update docs based on recent code changes").option("--quiet", "Suppress output (for use in hooks)").option("--dry-run", "Preview changes without writing files").action(refreshCommand);
|
|
5921
|
-
|
|
5922
|
-
hooks.command("install").description("Install Claude Code SessionEnd auto-refresh hook").action(hooksInstallCommand);
|
|
5923
|
-
hooks.command("remove").description("Remove Claude Code SessionEnd auto-refresh hook").action(hooksRemoveCommand);
|
|
5924
|
-
hooks.command("install-precommit").description("Install git pre-commit hook for auto-refresh").action(hooksInstallPrecommitCommand);
|
|
5925
|
-
hooks.command("remove-precommit").description("Remove git pre-commit hook").action(hooksRemovePrecommitCommand);
|
|
5926
|
-
hooks.command("status").description("Check installed hooks status").action(hooksStatusCommand);
|
|
6025
|
+
program.command("hooks").description("Manage auto-refresh hooks (toggle interactively)").option("--install", "Enable all hooks non-interactively").option("--remove", "Disable all hooks non-interactively").action(hooksCommand);
|
|
5927
6026
|
var learn = program.command("learn").description("Session learning \u2014 observe tool usage and extract reusable instructions");
|
|
5928
6027
|
learn.command("observe").description("Record a tool event from stdin (called by hooks)").option("--failure", "Mark event as a tool failure").action(learnObserveCommand);
|
|
5929
6028
|
learn.command("finalize").description("Analyze session events and update CLAUDE.md (called on SessionEnd)").action(learnFinalizeCommand);
|
package/package.json
CHANGED