@rely-ai/caliber 1.12.17 → 1.13.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 +75 -26
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -446,9 +446,9 @@ var CONFIG_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
|
446
446
|
var CONFIG_GLOBS_DIRS = [
|
|
447
447
|
{ dir: ".github/workflows", pattern: /\.ya?ml$/ }
|
|
448
448
|
];
|
|
449
|
-
var TOTAL_BUDGET =
|
|
450
|
-
var CONFIG_BUDGET = Math.floor(TOTAL_BUDGET * 0.
|
|
451
|
-
var SOURCE_BUDGET = Math.floor(TOTAL_BUDGET * 0.
|
|
449
|
+
var TOTAL_BUDGET = 4e5;
|
|
450
|
+
var CONFIG_BUDGET = Math.floor(TOTAL_BUDGET * 0.15);
|
|
451
|
+
var SOURCE_BUDGET = Math.floor(TOTAL_BUDGET * 0.85);
|
|
452
452
|
function analyzeCode(dir) {
|
|
453
453
|
const sourceFiles = [];
|
|
454
454
|
const configFiles = [];
|
|
@@ -465,27 +465,56 @@ function analyzeCode(dir) {
|
|
|
465
465
|
let sourceChars = 0;
|
|
466
466
|
let truncated = false;
|
|
467
467
|
const fileSummaries = [];
|
|
468
|
+
const MAX_CONTENT_LINE_COUNT = 300;
|
|
469
|
+
const CONTENT_BUDGET = Math.floor(SOURCE_BUDGET * 0.75);
|
|
470
|
+
const SUMMARY_BUDGET = SOURCE_BUDGET - CONTENT_BUDGET;
|
|
468
471
|
for (const relPath of sourceFiles) {
|
|
469
472
|
const fullPath = path3.join(dir, relPath);
|
|
470
|
-
let
|
|
473
|
+
let fileContent;
|
|
471
474
|
try {
|
|
472
|
-
|
|
475
|
+
fileContent = fs3.readFileSync(fullPath, "utf-8");
|
|
473
476
|
} catch {
|
|
474
477
|
continue;
|
|
475
478
|
}
|
|
476
|
-
const lineCount =
|
|
477
|
-
if (lineCount >
|
|
479
|
+
const lineCount = fileContent.split("\n").length;
|
|
480
|
+
if (lineCount > MAX_CONTENT_LINE_COUNT) continue;
|
|
478
481
|
const ext = path3.extname(relPath);
|
|
479
482
|
const language = resolveLanguage(ext);
|
|
480
483
|
if (!language) continue;
|
|
481
|
-
const summary = language === "py" ? extractPython(relPath,
|
|
484
|
+
const summary = language === "py" ? extractPython(relPath, fileContent) : extractTypeScriptJavaScript(relPath, fileContent, language);
|
|
485
|
+
summary.content = fileContent;
|
|
486
|
+
const entrySize = estimateSummarySize(summary) + fileContent.length;
|
|
487
|
+
if (sourceChars + entrySize > CONTENT_BUDGET) {
|
|
488
|
+
truncated = true;
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
fileSummaries.push(summary);
|
|
492
|
+
sourceChars += entrySize;
|
|
493
|
+
}
|
|
494
|
+
const processedPaths = new Set(fileSummaries.map((f) => f.path));
|
|
495
|
+
let summaryChars = 0;
|
|
496
|
+
for (const relPath of sourceFiles) {
|
|
497
|
+
if (processedPaths.has(relPath)) continue;
|
|
498
|
+
const fullPath = path3.join(dir, relPath);
|
|
499
|
+
let fileContent;
|
|
500
|
+
try {
|
|
501
|
+
fileContent = fs3.readFileSync(fullPath, "utf-8");
|
|
502
|
+
} catch {
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
const lineCount = fileContent.split("\n").length;
|
|
506
|
+
if (lineCount > 1e3) continue;
|
|
507
|
+
const ext = path3.extname(relPath);
|
|
508
|
+
const language = resolveLanguage(ext);
|
|
509
|
+
if (!language) continue;
|
|
510
|
+
const summary = language === "py" ? extractPython(relPath, fileContent) : extractTypeScriptJavaScript(relPath, fileContent, language);
|
|
482
511
|
const summarySize = estimateSummarySize(summary);
|
|
483
|
-
if (
|
|
512
|
+
if (summaryChars + summarySize > SUMMARY_BUDGET) {
|
|
484
513
|
truncated = true;
|
|
485
514
|
break;
|
|
486
515
|
}
|
|
487
516
|
fileSummaries.push(summary);
|
|
488
|
-
|
|
517
|
+
summaryChars += summarySize;
|
|
489
518
|
}
|
|
490
519
|
return { fileSummaries, configFiles: trimmedConfigs, truncated };
|
|
491
520
|
}
|
|
@@ -1701,8 +1730,9 @@ Skills serve two purposes:
|
|
|
1701
1730
|
|
|
1702
1731
|
Derive skill topics from actual code in the project. Look at existing files for the patterns being used, then create skills that replicate those patterns for new work.
|
|
1703
1732
|
|
|
1704
|
-
Skill topic description MUST
|
|
1705
|
-
|
|
1733
|
+
Skill topic description MUST follow this formula: [What it does] + [When to use it] + [Key capabilities].
|
|
1734
|
+
Include specific trigger phrases users would actually say. Also include negative triggers to prevent over-triggering.
|
|
1735
|
+
Example: "Creates a new API endpoint following the project's route pattern. Handles request validation, error responses, and DB queries. Use when user says 'add endpoint', 'new route', 'create API', or adds files to src/routes/. Do NOT use for modifying existing routes."
|
|
1706
1736
|
|
|
1707
1737
|
The "fileDescriptions" object MUST include a one-liner for every file that will be created or modified.
|
|
1708
1738
|
The "deletions" array should list files that should be removed (e.g. stale configs). Omit if empty.
|
|
@@ -1747,19 +1777,27 @@ Purpose: Skills codify repeating patterns from the codebase so every developer a
|
|
|
1747
1777
|
|
|
1748
1778
|
Structure:
|
|
1749
1779
|
1. A heading with the skill name
|
|
1750
|
-
2. "##
|
|
1751
|
-
3. "##
|
|
1752
|
-
|
|
1780
|
+
2. "## Critical" (if applicable) \u2014 put the most important rules and constraints FIRST. Things the agent must never skip, validation that must happen before any action, or project-specific constraints.
|
|
1781
|
+
3. "## Instructions" \u2014 clear, numbered steps derived from actual patterns in the codebase. Each step MUST:
|
|
1782
|
+
- Include exact file paths, naming conventions, imports, and boilerplate from existing code
|
|
1783
|
+
- Have a validation gate: "Verify X before proceeding to the next step"
|
|
1784
|
+
- Specify dependencies: "This step uses the output from Step N"
|
|
1785
|
+
4. "## Examples" \u2014 at least one example showing: User says \u2192 Actions taken \u2192 Result. The example should mirror how existing code in the project is structured.
|
|
1786
|
+
5. "## Common Issues" (required) \u2014 specific error messages and their fixes. Not "check your config" but "If you see 'Connection refused on port 5432': 1. Verify postgres is running: docker ps | grep postgres 2. Check .env has correct DATABASE_URL"
|
|
1753
1787
|
|
|
1754
1788
|
Rules:
|
|
1755
1789
|
- Max 150 lines. Focus on actionable instructions, not documentation prose.
|
|
1756
1790
|
- Study existing code in the project context to extract the real patterns being used. A skill for "create API route" should show the exact file structure, imports, error handling, and naming that existing routes use.
|
|
1791
|
+
- Be specific and actionable. GOOD: "Run \`pnpm test -- --filter=api\` to verify". BAD: "Validate the data before proceeding."
|
|
1792
|
+
- Never use ambiguous language. Instead of "handle errors properly", write "Wrap the DB call in try/catch. On failure, return { error: string, code: number } matching the ErrorResponse type in \`src/types.ts\`."
|
|
1757
1793
|
- Reference actual commands, paths, and packages from the project context provided.
|
|
1758
1794
|
- Do NOT include YAML frontmatter \u2014 it will be generated separately.
|
|
1759
1795
|
- Be specific to THIS project \u2014 avoid generic advice. The skill should produce code that looks identical to what's already in the codebase.
|
|
1760
1796
|
|
|
1797
|
+
Description field formula: [What it does] + [When to use it with trigger phrases] + [Key capabilities]. Include negative triggers ("Do NOT use for X") to prevent over-triggering.
|
|
1798
|
+
|
|
1761
1799
|
Return ONLY a JSON object:
|
|
1762
|
-
{"name": "string (kebab-case)", "description": "string (what + when)", "content": "string (markdown body)"}`;
|
|
1800
|
+
{"name": "string (kebab-case)", "description": "string (what + when + capabilities + negative triggers)", "content": "string (markdown body)"}`;
|
|
1763
1801
|
var REFINE_SYSTEM_PROMPT = `You are an expert at modifying coding agent configurations (Claude Code, Cursor, and Codex).
|
|
1764
1802
|
|
|
1765
1803
|
You will receive the current AgentSetup JSON and a user request describing what to change.
|
|
@@ -2427,15 +2465,16 @@ async function generateMonolithic(fingerprint, targetAgent, prompt, callbacks, f
|
|
|
2427
2465
|
return attemptGeneration();
|
|
2428
2466
|
}
|
|
2429
2467
|
var LIMITS = {
|
|
2430
|
-
FILE_TREE_ENTRIES:
|
|
2468
|
+
FILE_TREE_ENTRIES: 500,
|
|
2431
2469
|
EXISTING_CONFIG_CHARS: 8e3,
|
|
2432
2470
|
SKILLS_MAX: 10,
|
|
2433
2471
|
SKILL_CHARS: 3e3,
|
|
2434
2472
|
RULES_MAX: 10,
|
|
2435
|
-
CONFIG_FILES_MAX:
|
|
2436
|
-
CONFIG_FILE_CHARS:
|
|
2437
|
-
ROUTES_MAX:
|
|
2438
|
-
FILE_SUMMARIES_MAX:
|
|
2473
|
+
CONFIG_FILES_MAX: 20,
|
|
2474
|
+
CONFIG_FILE_CHARS: 5e3,
|
|
2475
|
+
ROUTES_MAX: 100,
|
|
2476
|
+
FILE_SUMMARIES_MAX: 200,
|
|
2477
|
+
FILE_CONTENT_CHARS: 8e3
|
|
2439
2478
|
};
|
|
2440
2479
|
function truncate(text, maxChars) {
|
|
2441
2480
|
if (text.length <= maxChars) return text;
|
|
@@ -2566,9 +2605,19 @@ ${truncate(cfg.content, LIMITS.CONFIG_FILE_CHARS)}`);
|
|
|
2566
2605
|
parts.push(`(${allRoutes.length - LIMITS.ROUTES_MAX} more routes omitted)`);
|
|
2567
2606
|
}
|
|
2568
2607
|
}
|
|
2569
|
-
|
|
2608
|
+
const filesWithContent = ca.fileSummaries.filter((f) => f.content);
|
|
2609
|
+
const filesWithoutContent = ca.fileSummaries.filter((f) => !f.content);
|
|
2610
|
+
if (filesWithContent.length > 0) {
|
|
2611
|
+
parts.push("\n--- Source Files (full content \u2014 use these to extract patterns for skills) ---");
|
|
2612
|
+
for (const f of filesWithContent.slice(0, LIMITS.FILE_SUMMARIES_MAX)) {
|
|
2613
|
+
parts.push(`
|
|
2614
|
+
[${f.path}] (${f.language})`);
|
|
2615
|
+
parts.push(truncate(f.content, LIMITS.FILE_CONTENT_CHARS));
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
if (filesWithoutContent.length > 0) {
|
|
2570
2619
|
parts.push("\n--- Source File Summaries ---");
|
|
2571
|
-
for (const f of
|
|
2620
|
+
for (const f of filesWithoutContent.slice(0, LIMITS.FILE_SUMMARIES_MAX)) {
|
|
2572
2621
|
const sections = [`[${f.path}] (${f.language})`];
|
|
2573
2622
|
if (f.imports.length > 0) sections.push(` imports: ${f.imports.slice(0, 10).join("; ")}`);
|
|
2574
2623
|
if (f.exports.length > 0) sections.push(` exports: ${f.exports.slice(0, 10).join(", ")}`);
|
|
@@ -2577,9 +2626,9 @@ ${truncate(cfg.content, LIMITS.CONFIG_FILE_CHARS)}`);
|
|
|
2577
2626
|
if (f.types.length > 0) sections.push(` types: ${f.types.slice(0, 10).join(", ")}`);
|
|
2578
2627
|
parts.push(sections.join("\n"));
|
|
2579
2628
|
}
|
|
2580
|
-
if (
|
|
2629
|
+
if (filesWithoutContent.length > LIMITS.FILE_SUMMARIES_MAX) {
|
|
2581
2630
|
parts.push(`
|
|
2582
|
-
(${
|
|
2631
|
+
(${filesWithoutContent.length - LIMITS.FILE_SUMMARIES_MAX} more files omitted)`);
|
|
2583
2632
|
}
|
|
2584
2633
|
}
|
|
2585
2634
|
if (ca.truncated) {
|
|
@@ -2589,7 +2638,7 @@ ${truncate(cfg.content, LIMITS.CONFIG_FILE_CHARS)}`);
|
|
|
2589
2638
|
const allDeps = extractAllDeps(process.cwd());
|
|
2590
2639
|
if (allDeps.length > 0) {
|
|
2591
2640
|
parts.push(`
|
|
2592
|
-
|
|
2641
|
+
Project dependencies (${allDeps.length}):`);
|
|
2593
2642
|
parts.push(allDeps.join(", "));
|
|
2594
2643
|
}
|
|
2595
2644
|
if (prompt) parts.push(`
|
package/package.json
CHANGED