@rely-ai/caliber 1.20.0-dev.1773686430 → 1.20.0-dev.1773686772

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 +102 -115
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -3719,8 +3719,8 @@ function removePreCommitHook() {
3719
3719
  if (!content.includes(PRECOMMIT_START)) {
3720
3720
  return { removed: false, notFound: true };
3721
3721
  }
3722
- const regex2 = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
3723
- content = content.replace(regex2, "\n");
3722
+ const regex = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
3723
+ content = content.replace(regex, "\n");
3724
3724
  if (content.trim() === "#!/bin/sh" || content.trim() === "") {
3725
3725
  fs18.unlinkSync(hookPath);
3726
3726
  } else {
@@ -6458,31 +6458,10 @@ function formatMs(ms) {
6458
6458
 
6459
6459
  // src/utils/parallel-tasks.ts
6460
6460
  import chalk9 from "chalk";
6461
-
6462
- // node_modules/ansi-regex/index.js
6463
- function ansiRegex({ onlyFirst = false } = {}) {
6464
- const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
6465
- const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
6466
- const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
6467
- const pattern = `${osc}|${csi}`;
6468
- return new RegExp(pattern, onlyFirst ? void 0 : "g");
6469
- }
6470
-
6471
- // node_modules/strip-ansi/index.js
6472
- var regex = ansiRegex();
6473
- function stripAnsi(string) {
6474
- if (typeof string !== "string") {
6475
- throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
6476
- }
6477
- if (!string.includes("\x1B") && !string.includes("\x9B")) {
6478
- return string;
6479
- }
6480
- return string.replace(regex, "");
6481
- }
6482
-
6483
- // src/utils/parallel-tasks.ts
6484
6461
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
6485
6462
  var SPINNER_INTERVAL_MS = 80;
6463
+ var NAME_COL_WIDTH = 26;
6464
+ var PREFIX = " ";
6486
6465
  var ParallelTaskDisplay = class {
6487
6466
  tasks = [];
6488
6467
  lineCount = 0;
@@ -6527,48 +6506,48 @@ var ParallelTaskDisplay = class {
6527
6506
  if (secs < 60) return `${secs}s`;
6528
6507
  return `${Math.floor(secs / 60)}m ${secs % 60}s`;
6529
6508
  }
6530
- truncate(text, maxVisible) {
6531
- const plain = stripAnsi(text);
6532
- if (plain.length <= maxVisible) return text;
6533
- let visible = 0;
6534
- let i = 0;
6535
- while (i < text.length && visible < maxVisible - 3) {
6536
- if (text[i] === "\x1B") {
6537
- const end = text.indexOf("m", i);
6538
- if (end !== -1) {
6539
- i = end + 1;
6540
- continue;
6541
- }
6542
- }
6543
- visible++;
6544
- i++;
6545
- }
6546
- return text.slice(0, i) + "...";
6509
+ smartTruncate(text, max) {
6510
+ if (text.length <= max) return text;
6511
+ const cut = text.slice(0, max - 1);
6512
+ const lastSpace = cut.lastIndexOf(" ");
6513
+ const boundary = lastSpace > max * 0.5 ? lastSpace : max - 1;
6514
+ return text.slice(0, boundary) + "\u2026";
6547
6515
  }
6548
6516
  renderLine(task) {
6549
- const maxWidth = process.stdout.columns || 80;
6517
+ const cols = process.stdout.columns || 80;
6550
6518
  const elapsed = task.startTime ? this.formatTime((task.endTime ?? Date.now()) - task.startTime) : "";
6551
- let line;
6519
+ const timeStr = elapsed ? ` ${chalk9.dim(elapsed)}` : "";
6520
+ const timePlain = elapsed ? ` ${elapsed}` : "";
6521
+ let icon;
6522
+ let nameStyle;
6523
+ let msgStyle;
6552
6524
  switch (task.status) {
6553
6525
  case "pending":
6554
- line = ` ${chalk9.dim("\u25CB")} ${chalk9.dim(task.name)}${task.message ? chalk9.dim(` \u2014 ${task.message}`) : ""}`;
6526
+ icon = chalk9.dim("\u25CB");
6527
+ nameStyle = chalk9.dim;
6528
+ msgStyle = chalk9.dim;
6555
6529
  break;
6556
- case "running": {
6557
- const spinner = chalk9.cyan(SPINNER_FRAMES[this.spinnerFrame]);
6558
- const time = elapsed ? chalk9.dim(` (${elapsed})`) : "";
6559
- line = ` ${spinner} ${task.name}${task.message ? chalk9.dim(` \u2014 ${task.message}`) : ""}${time}`;
6530
+ case "running":
6531
+ icon = chalk9.cyan(SPINNER_FRAMES[this.spinnerFrame]);
6532
+ nameStyle = chalk9.white;
6533
+ msgStyle = chalk9.dim;
6560
6534
  break;
6561
- }
6562
- case "done": {
6563
- const time = elapsed ? chalk9.dim(` (${elapsed})`) : "";
6564
- line = ` ${chalk9.green("\u2713")} ${task.name}${task.message ? chalk9.dim(` \u2014 ${task.message}`) : ""}${time}`;
6535
+ case "done":
6536
+ icon = chalk9.green("\u2713");
6537
+ nameStyle = chalk9.white;
6538
+ msgStyle = chalk9.dim;
6565
6539
  break;
6566
- }
6567
6540
  case "failed":
6568
- line = ` ${chalk9.red("\u2717")} ${task.name}${task.message ? chalk9.red(` \u2014 ${task.message}`) : ""}`;
6541
+ icon = chalk9.red("\u2717");
6542
+ nameStyle = chalk9.white;
6543
+ msgStyle = chalk9.red;
6569
6544
  break;
6570
6545
  }
6571
- return this.truncate(line, maxWidth - 1);
6546
+ const paddedName = task.name.padEnd(NAME_COL_WIDTH);
6547
+ const usedByFixed = PREFIX.length + 2 + NAME_COL_WIDTH + timePlain.length;
6548
+ const msgMax = Math.max(cols - usedByFixed - 2, 10);
6549
+ const msg = task.message ? this.smartTruncate(task.message, msgMax) : "";
6550
+ return `${PREFIX}${icon} ${nameStyle(paddedName)}${msg ? msgStyle(msg) : ""}${timeStr}`;
6572
6551
  }
6573
6552
  draw(initial) {
6574
6553
  const { stdout } = process;
@@ -6577,9 +6556,6 @@ var ParallelTaskDisplay = class {
6577
6556
  }
6578
6557
  stdout.write("\x1B[0J");
6579
6558
  const lines = this.tasks.map((t) => this.renderLine(t));
6580
- const totalElapsed = this.formatTime(Date.now() - this.startTime);
6581
- lines.push(chalk9.dim(`
6582
- Total: ${totalElapsed}`));
6583
6559
  const output = lines.join("\n");
6584
6560
  stdout.write(output + "\n");
6585
6561
  this.lineCount = output.split("\n").length;
@@ -6719,57 +6695,59 @@ async function initCommand(options) {
6719
6695
  let genStopReason;
6720
6696
  let skillSearchResult = { results: [], contentMap: /* @__PURE__ */ new Map() };
6721
6697
  let fingerprint;
6722
- const fpSpinner = ora2("Scanning project...").start();
6723
- try {
6724
- fingerprint = await collectFingerprint(process.cwd());
6725
- fpSpinner.succeed(`Stack detected \u2014 ${fingerprint.languages.join(", ") || "no languages"}${fingerprint.frameworks.length > 0 ? `, ${fingerprint.frameworks.join(", ")}` : ""}`);
6726
- } catch (err) {
6727
- fpSpinner.fail("Failed to scan project");
6728
- throw new Error("__exit__");
6729
- }
6730
- trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
6731
- log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
6732
- if (report) {
6733
- report.addJson("Fingerprint: Git", { remote: fingerprint.gitRemoteUrl, packageName: fingerprint.packageName });
6734
- report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
6735
- report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
6736
- report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
6737
- if (fingerprint.codeAnalysis) report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
6738
- }
6739
- const isEmpty = fingerprint.fileTree.length < 3;
6740
- if (isEmpty) {
6741
- fingerprint.description = await promptInput("What will you build in this project?");
6742
- }
6743
- const failingForDismissal = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
6744
- if (failingForDismissal.length > 0) {
6745
- const newDismissals = await evaluateDismissals(failingForDismissal, fingerprint);
6746
- if (newDismissals.length > 0) {
6747
- const existing = readDismissedChecks();
6748
- const existingIds = new Set(existing.map((d) => d.id));
6749
- const merged = [...existing, ...newDismissals.filter((d) => !existingIds.has(d.id))];
6750
- writeDismissedChecks(merged);
6751
- baselineScore = computeLocalScore(process.cwd(), targetAgent);
6752
- }
6753
- }
6754
- let failingChecks;
6755
- let passingChecks;
6756
- let currentScore;
6757
- if (hasExistingConfig && baselineScore.score >= 95 && !options.force) {
6758
- const currentLlmFixable = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0 && !NON_LLM_CHECKS.has(c.id));
6759
- failingChecks = currentLlmFixable.map((c) => ({ name: c.name, suggestion: c.suggestion, fix: c.fix }));
6760
- passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
6761
- currentScore = baselineScore.score;
6762
- }
6763
- if (report) {
6764
- const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
6765
- report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
6766
- }
6767
6698
  const display = new ParallelTaskDisplay();
6699
+ const TASK_STACK = display.add("Detecting project stack");
6768
6700
  const TASK_CONFIG = display.add("Generating configs");
6769
6701
  const TASK_SKILLS_GEN = display.add("Generating skills");
6770
6702
  const TASK_SKILLS_SEARCH = wantsSkills ? display.add("Searching community skills") : -1;
6771
6703
  display.start();
6772
6704
  try {
6705
+ display.update(TASK_STACK, "running");
6706
+ fingerprint = await collectFingerprint(process.cwd());
6707
+ const stackSummary = [
6708
+ ...fingerprint.languages,
6709
+ ...fingerprint.frameworks
6710
+ ].join(", ") || "no languages";
6711
+ display.update(TASK_STACK, "done", stackSummary);
6712
+ trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
6713
+ log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
6714
+ if (report) {
6715
+ report.addJson("Fingerprint: Git", { remote: fingerprint.gitRemoteUrl, packageName: fingerprint.packageName });
6716
+ report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
6717
+ report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
6718
+ report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
6719
+ if (fingerprint.codeAnalysis) report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
6720
+ }
6721
+ const isEmpty = fingerprint.fileTree.length < 3;
6722
+ if (isEmpty) {
6723
+ display.stop();
6724
+ fingerprint.description = await promptInput("What will you build in this project?");
6725
+ display.start();
6726
+ }
6727
+ const failingForDismissal = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
6728
+ if (failingForDismissal.length > 0) {
6729
+ const newDismissals = await evaluateDismissals(failingForDismissal, fingerprint);
6730
+ if (newDismissals.length > 0) {
6731
+ const existing = readDismissedChecks();
6732
+ const existingIds = new Set(existing.map((d) => d.id));
6733
+ const merged = [...existing, ...newDismissals.filter((d) => !existingIds.has(d.id))];
6734
+ writeDismissedChecks(merged);
6735
+ baselineScore = computeLocalScore(process.cwd(), targetAgent);
6736
+ }
6737
+ }
6738
+ let failingChecks;
6739
+ let passingChecks;
6740
+ let currentScore;
6741
+ if (hasExistingConfig && baselineScore.score >= 95 && !options.force) {
6742
+ const currentLlmFixable = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0 && !NON_LLM_CHECKS.has(c.id));
6743
+ failingChecks = currentLlmFixable.map((c) => ({ name: c.name, suggestion: c.suggestion, fix: c.fix }));
6744
+ passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
6745
+ currentScore = baselineScore.score;
6746
+ }
6747
+ if (report) {
6748
+ const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
6749
+ report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
6750
+ }
6773
6751
  display.update(TASK_CONFIG, "running");
6774
6752
  const generatePromise = (async () => {
6775
6753
  const result = await generateSetup(
@@ -6822,7 +6800,7 @@ async function initCommand(options) {
6822
6800
  ]);
6823
6801
  skillSearchResult = await searchWithTimeout;
6824
6802
  const count = skillSearchResult.results.length;
6825
- display.update(TASK_SKILLS_SEARCH, "done", count > 0 ? `${count} skills found` : "No matches");
6803
+ display.update(TASK_SKILLS_SEARCH, "done", count > 0 ? `${count} found` : "No matches");
6826
6804
  } catch (err) {
6827
6805
  const reason = err instanceof Error && err.message === "timeout" ? "Timed out" : "Search failed";
6828
6806
  display.update(TASK_SKILLS_SEARCH, "failed", reason);
@@ -6845,7 +6823,7 @@ async function initCommand(options) {
6845
6823
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
6846
6824
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
6847
6825
  console.log(chalk10.dim(`
6848
- Completed in ${timeStr}
6826
+ Done in ${timeStr}
6849
6827
  `));
6850
6828
  if (!generatedSetup) {
6851
6829
  console.log(chalk10.red(" Failed to generate setup."));
@@ -6878,8 +6856,9 @@ async function initCommand(options) {
6878
6856
  } else {
6879
6857
  console.log("");
6880
6858
  }
6859
+ const hasSkillResults = skillSearchResult.results.length > 0;
6881
6860
  let action;
6882
- if (totalChanges === 0 && skillSearchResult.results.length === 0) {
6861
+ if (totalChanges === 0 && !hasSkillResults) {
6883
6862
  console.log(chalk10.dim(" No changes needed \u2014 your configs are already up to date.\n"));
6884
6863
  cleanupStaging();
6885
6864
  action = "accept";
@@ -6889,13 +6868,20 @@ async function initCommand(options) {
6889
6868
  trackInitReviewAction(action, "auto-approved");
6890
6869
  } else {
6891
6870
  if (totalChanges > 0) {
6892
- const wantsReview = await promptWantsReview();
6893
- if (wantsReview) {
6871
+ const reviewChoice = await select5({
6872
+ message: "Review your tailored setup?",
6873
+ choices: [
6874
+ { name: "Yes, show me the diffs", value: "review" },
6875
+ ...hasSkillResults ? [{ name: `No, continue to community skills (${skillSearchResult.results.length} found)`, value: "skip" }] : [],
6876
+ { name: "No, continue", value: "skip" }
6877
+ ]
6878
+ });
6879
+ if (reviewChoice === "review") {
6894
6880
  const reviewMethod = await promptReviewMethod();
6895
6881
  await openReview(reviewMethod, staged.stagedFiles);
6896
6882
  }
6897
6883
  }
6898
- action = await promptReviewAction();
6884
+ action = await promptReviewAction(hasSkillResults);
6899
6885
  trackInitReviewAction(action, totalChanges > 0 ? "reviewed" : "skipped");
6900
6886
  }
6901
6887
  let refinementRound = 0;
@@ -6914,7 +6900,7 @@ async function initCommand(options) {
6914
6900
  `));
6915
6901
  printSetupSummary(generatedSetup);
6916
6902
  await openReview("terminal", restaged.stagedFiles);
6917
- action = await promptReviewAction();
6903
+ action = await promptReviewAction(hasSkillResults);
6918
6904
  trackInitReviewAction(action, "terminal");
6919
6905
  }
6920
6906
  cleanupStaging();
@@ -7214,13 +7200,14 @@ async function promptHookType(targetAgent) {
7214
7200
  choices
7215
7201
  });
7216
7202
  }
7217
- async function promptReviewAction() {
7203
+ async function promptReviewAction(hasSkillResults = false) {
7204
+ const acceptLabel = hasSkillResults ? "Accept and continue to community skills" : "Accept and apply";
7218
7205
  return select5({
7219
7206
  message: "What would you like to do?",
7220
7207
  choices: [
7221
- { name: "Accept and apply", value: "accept" },
7208
+ { name: acceptLabel, value: "accept" },
7222
7209
  { name: "Refine via chat", value: "refine" },
7223
- { name: "Decline", value: "decline" }
7210
+ { name: "Decline all changes", value: "decline" }
7224
7211
  ]
7225
7212
  });
7226
7213
  }
@@ -7230,7 +7217,7 @@ function printSetupSummary(setup) {
7230
7217
  const fileDescriptions = setup.fileDescriptions;
7231
7218
  const deletions = setup.deletions;
7232
7219
  console.log("");
7233
- console.log(chalk10.bold(" Proposed changes:\n"));
7220
+ console.log(chalk10.bold(" Your tailored setup:\n"));
7234
7221
  const getDescription = (filePath) => {
7235
7222
  return fileDescriptions?.[filePath];
7236
7223
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.20.0-dev.1773686430",
3
+ "version": "1.20.0-dev.1773686772",
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": {