@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.
- package/dist/bin.js +128 -163
- 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
|
|
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
|
|
2142
|
-
- "languages": array of programming languages used
|
|
2143
|
-
- "frameworks": array of frameworks and key libraries detected
|
|
2144
|
-
- "tools": array of external tools, services, and platforms the project integrates with
|
|
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
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
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,
|
|
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
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2235
|
-
|
|
2236
|
-
for (const
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
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
|
-
|
|
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
|
|
3723
|
-
content = content.replace(
|
|
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
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
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
|
|
6495
|
+
const cols = process.stdout.columns || 80;
|
|
6550
6496
|
const elapsed = task.startTime ? this.formatTime((task.endTime ?? Date.now()) - task.startTime) : "";
|
|
6551
|
-
|
|
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
|
-
|
|
6504
|
+
icon = chalk9.dim("\u25CB");
|
|
6505
|
+
nameStyle = chalk9.dim;
|
|
6506
|
+
msgStyle = chalk9.dim;
|
|
6555
6507
|
break;
|
|
6556
|
-
case "running":
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6508
|
+
case "running":
|
|
6509
|
+
icon = chalk9.cyan(SPINNER_FRAMES[this.spinnerFrame]);
|
|
6510
|
+
nameStyle = chalk9.white;
|
|
6511
|
+
msgStyle = chalk9.dim;
|
|
6560
6512
|
break;
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
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
|
-
|
|
6519
|
+
icon = chalk9.red("\u2717");
|
|
6520
|
+
nameStyle = chalk9.white;
|
|
6521
|
+
msgStyle = chalk9.red;
|
|
6569
6522
|
break;
|
|
6570
6523
|
}
|
|
6571
|
-
|
|
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}
|
|
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
|
-
|
|
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 &&
|
|
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
|
|
6893
|
-
|
|
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:
|
|
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("
|
|
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.
|
|
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": {
|