@rely-ai/caliber 0.5.2 → 0.5.3

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 +149 -52
  2. 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 hooks2 = settings.hooks;
3559
- if (hooks2 && Object.keys(hooks2).length > 0) {
3558
+ const hooks = settings.hooks;
3559
+ if (hooks && Object.keys(hooks).length > 0) {
3560
3560
  hasClaudeHooks = true;
3561
- hookSources.push(`Claude Code: ${Object.keys(hooks2).join(", ")}`);
3561
+ hookSources.push(`Claude Code: ${Object.keys(hooks).join(", ")}`);
3562
3562
  }
3563
3563
  } catch {
3564
3564
  }
@@ -5465,60 +5465,162 @@ async function refreshCommand(options) {
5465
5465
 
5466
5466
  // src/commands/hooks.ts
5467
5467
  import chalk11 from "chalk";
5468
- async function hooksInstallCommand() {
5469
- const result = installHook();
5470
- if (result.alreadyInstalled) {
5471
- console.log(chalk11.dim("Claude Code hook already installed."));
5472
- return;
5468
+ var HOOKS = [
5469
+ {
5470
+ id: "session-end",
5471
+ label: "Claude Code SessionEnd",
5472
+ description: "Auto-refresh CLAUDE.md when a Claude Code session ends",
5473
+ isInstalled: isHookInstalled,
5474
+ install: installHook,
5475
+ remove: removeHook
5476
+ },
5477
+ {
5478
+ id: "pre-commit",
5479
+ label: "Git pre-commit",
5480
+ description: "Auto-refresh CLAUDE.md before each git commit",
5481
+ isInstalled: isPreCommitHookInstalled,
5482
+ install: installPreCommitHook,
5483
+ remove: removePreCommitHook
5473
5484
  }
5474
- console.log(chalk11.green("\u2713") + " SessionEnd hook installed in .claude/settings.json");
5475
- console.log(chalk11.dim(" Docs will auto-refresh when Claude Code sessions end."));
5476
- }
5477
- async function hooksRemoveCommand() {
5478
- const result = removeHook();
5479
- if (result.notFound) {
5480
- console.log(chalk11.dim("Claude Code hook not found."));
5481
- return;
5485
+ ];
5486
+ function printStatus() {
5487
+ console.log(chalk11.bold("\n Hooks\n"));
5488
+ for (const hook of HOOKS) {
5489
+ const installed = hook.isInstalled();
5490
+ const icon = installed ? chalk11.green("\u2713") : chalk11.dim("\u2717");
5491
+ const state = installed ? chalk11.green("enabled") : chalk11.dim("disabled");
5492
+ console.log(` ${icon} ${hook.label.padEnd(26)} ${state}`);
5493
+ console.log(chalk11.dim(` ${hook.description}`));
5482
5494
  }
5483
- console.log(chalk11.green("\u2713") + " SessionEnd hook removed from .claude/settings.json");
5495
+ console.log("");
5484
5496
  }
5485
- async function hooksInstallPrecommitCommand() {
5486
- const result = installPreCommitHook();
5487
- if (result.alreadyInstalled) {
5488
- console.log(chalk11.dim("Pre-commit hook already installed."));
5497
+ async function hooksCommand(options) {
5498
+ if (options.install) {
5499
+ for (const hook of HOOKS) {
5500
+ const result = hook.install();
5501
+ if (result.alreadyInstalled) {
5502
+ console.log(chalk11.dim(` ${hook.label} already enabled.`));
5503
+ } else {
5504
+ console.log(chalk11.green(" \u2713") + ` ${hook.label} enabled`);
5505
+ }
5506
+ }
5489
5507
  return;
5490
5508
  }
5491
- if (!result.installed) {
5492
- console.log(chalk11.red("Failed to install pre-commit hook (not a git repository?)."));
5509
+ if (options.remove) {
5510
+ for (const hook of HOOKS) {
5511
+ const result = hook.remove();
5512
+ if (result.notFound) {
5513
+ console.log(chalk11.dim(` ${hook.label} already disabled.`));
5514
+ } else {
5515
+ console.log(chalk11.green(" \u2713") + ` ${hook.label} removed`);
5516
+ }
5517
+ }
5493
5518
  return;
5494
5519
  }
5495
- console.log(chalk11.green("\u2713") + " Pre-commit hook installed in .git/hooks/pre-commit");
5496
- console.log(chalk11.dim(" Docs will auto-refresh before each commit via LLM."));
5497
- }
5498
- async function hooksRemovePrecommitCommand() {
5499
- const result = removePreCommitHook();
5500
- if (result.notFound) {
5501
- console.log(chalk11.dim("Pre-commit hook not found."));
5520
+ if (!process.stdin.isTTY) {
5521
+ printStatus();
5502
5522
  return;
5503
5523
  }
5504
- console.log(chalk11.green("\u2713") + " Pre-commit hook removed from .git/hooks/pre-commit");
5505
- }
5506
- async function hooksStatusCommand() {
5507
- const claudeInstalled = isHookInstalled();
5508
- const precommitInstalled = isPreCommitHookInstalled();
5509
- if (claudeInstalled) {
5510
- console.log(chalk11.green("\u2713") + " Claude Code hook is " + chalk11.green("installed"));
5511
- } else {
5512
- console.log(chalk11.dim("\u2717") + " Claude Code hook is " + chalk11.yellow("not installed"));
5513
- }
5514
- if (precommitInstalled) {
5515
- console.log(chalk11.green("\u2713") + " Pre-commit hook is " + chalk11.green("installed"));
5516
- } else {
5517
- console.log(chalk11.dim("\u2717") + " Pre-commit hook is " + chalk11.yellow("not installed"));
5524
+ const { stdin, stdout } = process;
5525
+ let cursor = 0;
5526
+ let lineCount = 0;
5527
+ const states = HOOKS.map((h) => h.isInstalled());
5528
+ function render() {
5529
+ const lines = [];
5530
+ lines.push(chalk11.bold(" Hooks"));
5531
+ lines.push("");
5532
+ for (let i = 0; i < HOOKS.length; i++) {
5533
+ const hook = HOOKS[i];
5534
+ const enabled = states[i];
5535
+ const toggle = enabled ? chalk11.green("[on] ") : chalk11.dim("[off]");
5536
+ const ptr = i === cursor ? chalk11.cyan(">") : " ";
5537
+ lines.push(` ${ptr} ${toggle} ${hook.label}`);
5538
+ lines.push(chalk11.dim(` ${hook.description}`));
5539
+ }
5540
+ lines.push("");
5541
+ lines.push(chalk11.dim(" \u2191\u2193 navigate \u23B5 toggle a all on n all off \u23CE apply q cancel"));
5542
+ return lines.join("\n");
5518
5543
  }
5519
- if (!claudeInstalled && !precommitInstalled) {
5520
- console.log(chalk11.dim("\n Run `caliber hooks install` or `caliber hooks install-precommit` to enable auto-refresh."));
5544
+ function draw(initial) {
5545
+ if (!initial && lineCount > 0) {
5546
+ stdout.write(`\x1B[${lineCount}A`);
5547
+ }
5548
+ stdout.write("\x1B[0J");
5549
+ const output = render();
5550
+ stdout.write(output + "\n");
5551
+ lineCount = output.split("\n").length;
5521
5552
  }
5553
+ return new Promise((resolve2) => {
5554
+ console.log("");
5555
+ draw(true);
5556
+ stdin.setRawMode(true);
5557
+ stdin.resume();
5558
+ stdin.setEncoding("utf8");
5559
+ function cleanup() {
5560
+ stdin.removeListener("data", onData);
5561
+ stdin.setRawMode(false);
5562
+ stdin.pause();
5563
+ }
5564
+ function apply() {
5565
+ let changed = 0;
5566
+ for (let i = 0; i < HOOKS.length; i++) {
5567
+ const hook = HOOKS[i];
5568
+ const wasInstalled = hook.isInstalled();
5569
+ const wantEnabled = states[i];
5570
+ if (wantEnabled && !wasInstalled) {
5571
+ hook.install();
5572
+ console.log(chalk11.green(" \u2713") + ` ${hook.label} enabled`);
5573
+ changed++;
5574
+ } else if (!wantEnabled && wasInstalled) {
5575
+ hook.remove();
5576
+ console.log(chalk11.green(" \u2713") + ` ${hook.label} disabled`);
5577
+ changed++;
5578
+ }
5579
+ }
5580
+ if (changed === 0) {
5581
+ console.log(chalk11.dim(" No changes."));
5582
+ }
5583
+ console.log("");
5584
+ }
5585
+ function onData(key) {
5586
+ switch (key) {
5587
+ case "\x1B[A":
5588
+ cursor = (cursor - 1 + HOOKS.length) % HOOKS.length;
5589
+ draw(false);
5590
+ break;
5591
+ case "\x1B[B":
5592
+ cursor = (cursor + 1) % HOOKS.length;
5593
+ draw(false);
5594
+ break;
5595
+ case " ":
5596
+ states[cursor] = !states[cursor];
5597
+ draw(false);
5598
+ break;
5599
+ case "a":
5600
+ states.fill(true);
5601
+ draw(false);
5602
+ break;
5603
+ case "n":
5604
+ states.fill(false);
5605
+ draw(false);
5606
+ break;
5607
+ case "\r":
5608
+ case "\n":
5609
+ cleanup();
5610
+ apply();
5611
+ resolve2();
5612
+ break;
5613
+ case "q":
5614
+ case "\x1B":
5615
+ case "":
5616
+ cleanup();
5617
+ console.log(chalk11.dim("\n Cancelled.\n"));
5618
+ resolve2();
5619
+ break;
5620
+ }
5621
+ }
5622
+ stdin.on("data", onData);
5623
+ });
5522
5624
  }
5523
5625
 
5524
5626
  // src/commands/config.ts
@@ -5918,12 +6020,7 @@ program.command("config").description("Configure LLM provider, API key, and mode
5918
6020
  program.command("recommend").description("Discover and install skill recommendations").option("--generate", "Force fresh recommendation search").action(recommendCommand);
5919
6021
  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
6022
  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
- var hooks = program.command("hooks").description("Manage auto-refresh hooks (Claude Code and git pre-commit)");
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);
6023
+ 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
6024
  var learn = program.command("learn").description("Session learning \u2014 observe tool usage and extract reusable instructions");
5928
6025
  learn.command("observe").description("Record a tool event from stdin (called by hooks)").option("--failure", "Mark event as a tool failure").action(learnObserveCommand);
5929
6026
  learn.command("finalize").description("Analyze session events and update CLAUDE.md (called on SessionEnd)").action(learnFinalizeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
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": {