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

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 +128 -163
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -2136,37 +2136,37 @@ All markdown content inside string values must be properly escaped for JSON (new
2136
2136
 
2137
2137
  If there's nothing worth learning from the events (routine successful operations), return:
2138
2138
  {"claudeMdLearnedSection": null, "skills": null, "explanations": ["No actionable patterns found in these events."]}`;
2139
- var FINGERPRINT_SYSTEM_PROMPT = `You are an expert at detecting programming languages, frameworks, and external tools/services from project file trees and dependency files.
2139
+ var FINGERPRINT_SYSTEM_PROMPT = `You are an expert at detecting programming languages, frameworks, and external tools/services from project structure.
2140
2140
 
2141
- Analyze the provided file tree and dependency file contents. Return a JSON object with:
2142
- - "languages": array of programming languages used (e.g. "TypeScript", "Python", "Go", "Rust", "HCL")
2143
- - "frameworks": array of frameworks and key libraries detected (e.g. "FastAPI", "React", "Celery", "Django", "Express", "Next.js", "Terraform")
2144
- - "tools": array of external tools, services, and platforms the project integrates with \u2014 things that could have an MCP server or API integration (e.g. "PostgreSQL", "Redis", "Stripe", "Sentry", "AWS", "GCP", "GitHub", "Slack", "Docker", "Kubernetes", "Datadog", "PagerDuty", "MongoDB", "Elasticsearch")
2141
+ Analyze the provided file tree and file extension distribution. Return a JSON object with:
2142
+ - "languages": array of programming languages used, ordered by prominence in the project (most files first)
2143
+ - "frameworks": array of frameworks and key libraries detected, ordered by prominence
2144
+ - "tools": array of external tools, services, and platforms the project integrates with, ordered by prominence
2145
2145
 
2146
- Be thorough \u2014 look for signals in:
2147
- - Dependency files (package.json, pyproject.toml, requirements.txt, go.mod, Cargo.toml, etc.)
2148
- - File extensions and directory structure
2146
+ Use the file extension distribution to determine the ordering \u2014 technologies with more files should appear first.
2147
+
2148
+ Be thorough \u2014 reason from:
2149
+ - File extensions and their frequency distribution
2150
+ - Directory structure and naming conventions
2149
2151
  - Configuration files (e.g. next.config.js implies Next.js, .tf files imply Terraform + cloud providers)
2150
2152
  - Infrastructure-as-code files (Terraform, CloudFormation, Pulumi, Dockerfiles, k8s manifests)
2151
2153
  - CI/CD configs (.github/workflows, .gitlab-ci.yml, Jenkinsfile)
2152
- - Dockerfile base images (e.g. FROM python:3.11 implies Python, FROM node:20 implies Node.js)
2153
2154
 
2154
2155
  Only include items you're confident about. Return ONLY the JSON object.`;
2155
2156
 
2156
2157
  // src/ai/detect.ts
2157
- async function detectProjectStack(fileTree, fileContents) {
2158
+ async function detectProjectStack(fileTree, suffixCounts) {
2158
2159
  const parts = ["Analyze this project and detect languages, frameworks, and external tools/services.\n"];
2159
2160
  if (fileTree.length > 0) {
2160
2161
  const cappedTree = fileTree.slice(0, 500);
2161
2162
  parts.push(`File tree (${cappedTree.length}/${fileTree.length} entries):`);
2162
2163
  parts.push(cappedTree.join("\n"));
2163
2164
  }
2164
- if (Object.keys(fileContents).length > 0) {
2165
- parts.push("\nDependency file contents:");
2166
- for (const [filePath, content] of Object.entries(fileContents)) {
2167
- parts.push(`
2168
- [${filePath}]`);
2169
- parts.push(content);
2165
+ const sorted = Object.entries(suffixCounts).sort((a, b) => b[1] - a[1]);
2166
+ if (sorted.length > 0) {
2167
+ parts.push("\nFile extension distribution (sorted by frequency):");
2168
+ for (const [ext, count] of sorted) {
2169
+ parts.push(`${ext}: ${count}`);
2170
2170
  }
2171
2171
  }
2172
2172
  const fastModel = getFastModel();
@@ -2200,7 +2200,7 @@ async function collectFingerprint(dir) {
2200
2200
  existingConfigs,
2201
2201
  codeAnalysis
2202
2202
  };
2203
- await enrichWithLLM(fingerprint, dir);
2203
+ await enrichWithLLM(fingerprint);
2204
2204
  return fingerprint;
2205
2205
  }
2206
2206
  function readPackageName(dir) {
@@ -2213,42 +2213,20 @@ function readPackageName(dir) {
2213
2213
  return void 0;
2214
2214
  }
2215
2215
  }
2216
- var DEP_FILE_PATTERNS = [
2217
- "package.json",
2218
- "pyproject.toml",
2219
- "requirements.txt",
2220
- "setup.py",
2221
- "Pipfile",
2222
- "Cargo.toml",
2223
- "go.mod",
2224
- "Gemfile",
2225
- "build.gradle",
2226
- "pom.xml",
2227
- "composer.json"
2228
- ];
2229
- var MAX_CONTENT_SIZE = 50 * 1024;
2230
- async function enrichWithLLM(fingerprint, dir) {
2216
+ async function enrichWithLLM(fingerprint) {
2231
2217
  try {
2232
2218
  const config = loadConfig();
2233
2219
  if (!config) return;
2234
- const fileContents = {};
2235
- let totalSize = 0;
2236
- for (const treePath of fingerprint.fileTree) {
2237
- const basename = path5.basename(treePath);
2238
- if (!DEP_FILE_PATTERNS.includes(basename)) continue;
2239
- const fullPath = path5.join(dir, treePath);
2240
- if (!fs6.existsSync(fullPath)) continue;
2241
- try {
2242
- const content = fs6.readFileSync(fullPath, "utf-8");
2243
- if (totalSize + content.length > MAX_CONTENT_SIZE) break;
2244
- fileContents[treePath] = content;
2245
- totalSize += content.length;
2246
- } catch {
2247
- continue;
2220
+ if (fingerprint.fileTree.length === 0) return;
2221
+ const suffixCounts = {};
2222
+ for (const entry of fingerprint.fileTree) {
2223
+ if (entry.endsWith("/")) continue;
2224
+ const ext = path5.extname(entry).toLowerCase();
2225
+ if (ext) {
2226
+ suffixCounts[ext] = (suffixCounts[ext] || 0) + 1;
2248
2227
  }
2249
2228
  }
2250
- if (Object.keys(fileContents).length === 0 && fingerprint.fileTree.length === 0) return;
2251
- const result = await detectProjectStack(fingerprint.fileTree, fileContents);
2229
+ const result = await detectProjectStack(fingerprint.fileTree, suffixCounts);
2252
2230
  if (result.languages?.length) fingerprint.languages = result.languages;
2253
2231
  if (result.frameworks?.length) fingerprint.frameworks = result.frameworks;
2254
2232
  if (result.tools?.length) fingerprint.tools = result.tools;
@@ -3719,8 +3697,8 @@ function removePreCommitHook() {
3719
3697
  if (!content.includes(PRECOMMIT_START)) {
3720
3698
  return { removed: false, notFound: true };
3721
3699
  }
3722
- const regex2 = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
3723
- content = content.replace(regex2, "\n");
3700
+ const regex = new RegExp(`\\n?${PRECOMMIT_START}[\\s\\S]*?${PRECOMMIT_END}\\n?`);
3701
+ content = content.replace(regex, "\n");
3724
3702
  if (content.trim() === "#!/bin/sh" || content.trim() === "") {
3725
3703
  fs18.unlinkSync(hookPath);
3726
3704
  } else {
@@ -6458,31 +6436,10 @@ function formatMs(ms) {
6458
6436
 
6459
6437
  // src/utils/parallel-tasks.ts
6460
6438
  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
6439
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
6485
6440
  var SPINNER_INTERVAL_MS = 80;
6441
+ var NAME_COL_WIDTH = 26;
6442
+ var PREFIX = " ";
6486
6443
  var ParallelTaskDisplay = class {
6487
6444
  tasks = [];
6488
6445
  lineCount = 0;
@@ -6527,48 +6484,48 @@ var ParallelTaskDisplay = class {
6527
6484
  if (secs < 60) return `${secs}s`;
6528
6485
  return `${Math.floor(secs / 60)}m ${secs % 60}s`;
6529
6486
  }
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) + "...";
6487
+ smartTruncate(text, max) {
6488
+ if (text.length <= max) return text;
6489
+ const cut = text.slice(0, max - 1);
6490
+ const lastSpace = cut.lastIndexOf(" ");
6491
+ const boundary = lastSpace > max * 0.5 ? lastSpace : max - 1;
6492
+ return text.slice(0, boundary) + "\u2026";
6547
6493
  }
6548
6494
  renderLine(task) {
6549
- const maxWidth = process.stdout.columns || 80;
6495
+ const cols = process.stdout.columns || 80;
6550
6496
  const elapsed = task.startTime ? this.formatTime((task.endTime ?? Date.now()) - task.startTime) : "";
6551
- let line;
6497
+ const timeStr = elapsed ? ` ${chalk9.dim(elapsed)}` : "";
6498
+ const timePlain = elapsed ? ` ${elapsed}` : "";
6499
+ let icon;
6500
+ let nameStyle;
6501
+ let msgStyle;
6552
6502
  switch (task.status) {
6553
6503
  case "pending":
6554
- line = ` ${chalk9.dim("\u25CB")} ${chalk9.dim(task.name)}${task.message ? chalk9.dim(` \u2014 ${task.message}`) : ""}`;
6504
+ icon = chalk9.dim("\u25CB");
6505
+ nameStyle = chalk9.dim;
6506
+ msgStyle = chalk9.dim;
6555
6507
  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}`;
6508
+ case "running":
6509
+ icon = chalk9.cyan(SPINNER_FRAMES[this.spinnerFrame]);
6510
+ nameStyle = chalk9.white;
6511
+ msgStyle = chalk9.dim;
6560
6512
  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}`;
6513
+ case "done":
6514
+ icon = chalk9.green("\u2713");
6515
+ nameStyle = chalk9.white;
6516
+ msgStyle = chalk9.dim;
6565
6517
  break;
6566
- }
6567
6518
  case "failed":
6568
- line = ` ${chalk9.red("\u2717")} ${task.name}${task.message ? chalk9.red(` \u2014 ${task.message}`) : ""}`;
6519
+ icon = chalk9.red("\u2717");
6520
+ nameStyle = chalk9.white;
6521
+ msgStyle = chalk9.red;
6569
6522
  break;
6570
6523
  }
6571
- return this.truncate(line, maxWidth - 1);
6524
+ const paddedName = task.name.padEnd(NAME_COL_WIDTH);
6525
+ const usedByFixed = PREFIX.length + 2 + NAME_COL_WIDTH + timePlain.length;
6526
+ const msgMax = Math.max(cols - usedByFixed - 2, 10);
6527
+ const msg = task.message ? this.smartTruncate(task.message, msgMax) : "";
6528
+ return `${PREFIX}${icon} ${nameStyle(paddedName)}${msg ? msgStyle(msg) : ""}${timeStr}`;
6572
6529
  }
6573
6530
  draw(initial) {
6574
6531
  const { stdout } = process;
@@ -6577,9 +6534,6 @@ var ParallelTaskDisplay = class {
6577
6534
  }
6578
6535
  stdout.write("\x1B[0J");
6579
6536
  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
6537
  const output = lines.join("\n");
6584
6538
  stdout.write(output + "\n");
6585
6539
  this.lineCount = output.split("\n").length;
@@ -6719,57 +6673,59 @@ async function initCommand(options) {
6719
6673
  let genStopReason;
6720
6674
  let skillSearchResult = { results: [], contentMap: /* @__PURE__ */ new Map() };
6721
6675
  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
6676
  const display = new ParallelTaskDisplay();
6677
+ const TASK_STACK = display.add("Detecting project stack");
6768
6678
  const TASK_CONFIG = display.add("Generating configs");
6769
6679
  const TASK_SKILLS_GEN = display.add("Generating skills");
6770
6680
  const TASK_SKILLS_SEARCH = wantsSkills ? display.add("Searching community skills") : -1;
6771
6681
  display.start();
6772
6682
  try {
6683
+ display.update(TASK_STACK, "running");
6684
+ fingerprint = await collectFingerprint(process.cwd());
6685
+ const stackSummary = [
6686
+ ...fingerprint.languages,
6687
+ ...fingerprint.frameworks
6688
+ ].join(", ") || "no languages";
6689
+ display.update(TASK_STACK, "done", stackSummary);
6690
+ trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
6691
+ log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
6692
+ if (report) {
6693
+ report.addJson("Fingerprint: Git", { remote: fingerprint.gitRemoteUrl, packageName: fingerprint.packageName });
6694
+ report.addCodeBlock("Fingerprint: File Tree", fingerprint.fileTree.join("\n"));
6695
+ report.addJson("Fingerprint: Detected Stack", { languages: fingerprint.languages, frameworks: fingerprint.frameworks, tools: fingerprint.tools });
6696
+ report.addJson("Fingerprint: Existing Configs", fingerprint.existingConfigs);
6697
+ if (fingerprint.codeAnalysis) report.addJson("Fingerprint: Code Analysis", fingerprint.codeAnalysis);
6698
+ }
6699
+ const isEmpty = fingerprint.fileTree.length < 3;
6700
+ if (isEmpty) {
6701
+ display.stop();
6702
+ fingerprint.description = await promptInput("What will you build in this project?");
6703
+ display.start();
6704
+ }
6705
+ const failingForDismissal = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0);
6706
+ if (failingForDismissal.length > 0) {
6707
+ const newDismissals = await evaluateDismissals(failingForDismissal, fingerprint);
6708
+ if (newDismissals.length > 0) {
6709
+ const existing = readDismissedChecks();
6710
+ const existingIds = new Set(existing.map((d) => d.id));
6711
+ const merged = [...existing, ...newDismissals.filter((d) => !existingIds.has(d.id))];
6712
+ writeDismissedChecks(merged);
6713
+ baselineScore = computeLocalScore(process.cwd(), targetAgent);
6714
+ }
6715
+ }
6716
+ let failingChecks;
6717
+ let passingChecks;
6718
+ let currentScore;
6719
+ if (hasExistingConfig && baselineScore.score >= 95 && !options.force) {
6720
+ const currentLlmFixable = baselineScore.checks.filter((c) => !c.passed && c.maxPoints > 0 && !NON_LLM_CHECKS.has(c.id));
6721
+ failingChecks = currentLlmFixable.map((c) => ({ name: c.name, suggestion: c.suggestion, fix: c.fix }));
6722
+ passingChecks = baselineScore.checks.filter((c) => c.passed).map((c) => ({ name: c.name }));
6723
+ currentScore = baselineScore.score;
6724
+ }
6725
+ if (report) {
6726
+ const fullPrompt = buildGeneratePrompt(fingerprint, targetAgent, fingerprint.description, failingChecks, currentScore, passingChecks);
6727
+ report.addCodeBlock("Generation: Full LLM Prompt", fullPrompt);
6728
+ }
6773
6729
  display.update(TASK_CONFIG, "running");
6774
6730
  const generatePromise = (async () => {
6775
6731
  const result = await generateSetup(
@@ -6822,7 +6778,7 @@ async function initCommand(options) {
6822
6778
  ]);
6823
6779
  skillSearchResult = await searchWithTimeout;
6824
6780
  const count = skillSearchResult.results.length;
6825
- display.update(TASK_SKILLS_SEARCH, "done", count > 0 ? `${count} skills found` : "No matches");
6781
+ display.update(TASK_SKILLS_SEARCH, "done", count > 0 ? `${count} found` : "No matches");
6826
6782
  } catch (err) {
6827
6783
  const reason = err instanceof Error && err.message === "timeout" ? "Timed out" : "Search failed";
6828
6784
  display.update(TASK_SKILLS_SEARCH, "failed", reason);
@@ -6845,7 +6801,7 @@ async function initCommand(options) {
6845
6801
  const secs = Math.floor(elapsedMs % 6e4 / 1e3);
6846
6802
  const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
6847
6803
  console.log(chalk10.dim(`
6848
- Completed in ${timeStr}
6804
+ Done in ${timeStr}
6849
6805
  `));
6850
6806
  if (!generatedSetup) {
6851
6807
  console.log(chalk10.red(" Failed to generate setup."));
@@ -6878,8 +6834,9 @@ async function initCommand(options) {
6878
6834
  } else {
6879
6835
  console.log("");
6880
6836
  }
6837
+ const hasSkillResults = skillSearchResult.results.length > 0;
6881
6838
  let action;
6882
- if (totalChanges === 0 && skillSearchResult.results.length === 0) {
6839
+ if (totalChanges === 0 && !hasSkillResults) {
6883
6840
  console.log(chalk10.dim(" No changes needed \u2014 your configs are already up to date.\n"));
6884
6841
  cleanupStaging();
6885
6842
  action = "accept";
@@ -6889,13 +6846,20 @@ async function initCommand(options) {
6889
6846
  trackInitReviewAction(action, "auto-approved");
6890
6847
  } else {
6891
6848
  if (totalChanges > 0) {
6892
- const wantsReview = await promptWantsReview();
6893
- if (wantsReview) {
6849
+ const reviewChoice = await select5({
6850
+ message: "Review your tailored setup?",
6851
+ choices: [
6852
+ { name: "Yes, show me the diffs", value: "review" },
6853
+ ...hasSkillResults ? [{ name: `No, continue to community skills (${skillSearchResult.results.length} found)`, value: "skip" }] : [],
6854
+ { name: "No, continue", value: "skip" }
6855
+ ]
6856
+ });
6857
+ if (reviewChoice === "review") {
6894
6858
  const reviewMethod = await promptReviewMethod();
6895
6859
  await openReview(reviewMethod, staged.stagedFiles);
6896
6860
  }
6897
6861
  }
6898
- action = await promptReviewAction();
6862
+ action = await promptReviewAction(hasSkillResults);
6899
6863
  trackInitReviewAction(action, totalChanges > 0 ? "reviewed" : "skipped");
6900
6864
  }
6901
6865
  let refinementRound = 0;
@@ -6914,7 +6878,7 @@ async function initCommand(options) {
6914
6878
  `));
6915
6879
  printSetupSummary(generatedSetup);
6916
6880
  await openReview("terminal", restaged.stagedFiles);
6917
- action = await promptReviewAction();
6881
+ action = await promptReviewAction(hasSkillResults);
6918
6882
  trackInitReviewAction(action, "terminal");
6919
6883
  }
6920
6884
  cleanupStaging();
@@ -7214,13 +7178,14 @@ async function promptHookType(targetAgent) {
7214
7178
  choices
7215
7179
  });
7216
7180
  }
7217
- async function promptReviewAction() {
7181
+ async function promptReviewAction(hasSkillResults = false) {
7182
+ const acceptLabel = hasSkillResults ? "Accept and continue to community skills" : "Accept and apply";
7218
7183
  return select5({
7219
7184
  message: "What would you like to do?",
7220
7185
  choices: [
7221
- { name: "Accept and apply", value: "accept" },
7186
+ { name: acceptLabel, value: "accept" },
7222
7187
  { name: "Refine via chat", value: "refine" },
7223
- { name: "Decline", value: "decline" }
7188
+ { name: "Decline all changes", value: "decline" }
7224
7189
  ]
7225
7190
  });
7226
7191
  }
@@ -7230,7 +7195,7 @@ function printSetupSummary(setup) {
7230
7195
  const fileDescriptions = setup.fileDescriptions;
7231
7196
  const deletions = setup.deletions;
7232
7197
  console.log("");
7233
- console.log(chalk10.bold(" Proposed changes:\n"));
7198
+ console.log(chalk10.bold(" Your tailored setup:\n"));
7234
7199
  const getDescription = (filePath) => {
7235
7200
  return fileDescriptions?.[filePath];
7236
7201
  };
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.1773686790",
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": {