@rely-ai/caliber 1.22.0 → 1.22.1-dev.1773778672
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 +109 -30
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -285,9 +285,26 @@ var IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
|
285
285
|
"target"
|
|
286
286
|
]);
|
|
287
287
|
function getFileTree(dir, maxDepth = 3) {
|
|
288
|
+
const entries = [];
|
|
289
|
+
scan(dir, "", 0, maxDepth, entries);
|
|
290
|
+
const dirs = [];
|
|
288
291
|
const files = [];
|
|
289
|
-
|
|
290
|
-
|
|
292
|
+
for (const e of entries) {
|
|
293
|
+
(e.isDir ? dirs : files).push(e);
|
|
294
|
+
}
|
|
295
|
+
for (const d of dirs) {
|
|
296
|
+
const prefix = d.relPath;
|
|
297
|
+
let maxChildMtime = d.mtime;
|
|
298
|
+
for (const f of files) {
|
|
299
|
+
if (f.relPath.startsWith(prefix) && f.mtime > maxChildMtime) {
|
|
300
|
+
maxChildMtime = f.mtime;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
d.mtime = maxChildMtime;
|
|
304
|
+
}
|
|
305
|
+
dirs.sort((a, b) => b.mtime - a.mtime);
|
|
306
|
+
files.sort((a, b) => b.mtime - a.mtime);
|
|
307
|
+
return [...dirs.map((e) => e.relPath), ...files.map((e) => e.relPath)];
|
|
291
308
|
}
|
|
292
309
|
function scan(base, rel, depth, maxDepth, result) {
|
|
293
310
|
if (depth > maxDepth) return;
|
|
@@ -302,11 +319,17 @@ function scan(base, rel, depth, maxDepth, result) {
|
|
|
302
319
|
if (entry.name.startsWith(".") && depth === 0 && entry.isDirectory()) continue;
|
|
303
320
|
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
304
321
|
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
322
|
+
const entryPath = path.join(base, relPath);
|
|
323
|
+
let mtime = 0;
|
|
324
|
+
try {
|
|
325
|
+
mtime = fs.statSync(entryPath).mtimeMs;
|
|
326
|
+
} catch {
|
|
327
|
+
}
|
|
305
328
|
if (entry.isDirectory()) {
|
|
306
|
-
result.push(`${relPath}
|
|
329
|
+
result.push({ relPath: `${relPath}/`, isDir: true, mtime });
|
|
307
330
|
scan(base, relPath, depth + 1, maxDepth, result);
|
|
308
331
|
} else {
|
|
309
|
-
result.push(relPath);
|
|
332
|
+
result.push({ relPath, isDir: false, mtime });
|
|
310
333
|
}
|
|
311
334
|
}
|
|
312
335
|
}
|
|
@@ -584,7 +607,7 @@ var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
584
607
|
".swift",
|
|
585
608
|
".php"
|
|
586
609
|
]);
|
|
587
|
-
var TOKEN_BUDGET =
|
|
610
|
+
var TOKEN_BUDGET = 8e4;
|
|
588
611
|
var CHAR_BUDGET = TOKEN_BUDGET * 4;
|
|
589
612
|
function compressContent(content, ext) {
|
|
590
613
|
const cp = EXT_COMMENT[ext] ? COMMENT_LINE[EXT_COMMENT[ext]] : null;
|
|
@@ -829,7 +852,7 @@ function analyzeCode(dir) {
|
|
|
829
852
|
const repFP = structuralFingerprint(rep.compressed, rep.ext);
|
|
830
853
|
const similar = group.slice(1).filter((f) => structuralFingerprint(f.compressed, f.ext) === repFP);
|
|
831
854
|
const unique = group.slice(1).filter((f) => structuralFingerprint(f.compressed, f.ext) !== repFP);
|
|
832
|
-
const repEntry = { path: rep.path, content: rep.compressed, size: rep.compressed.length };
|
|
855
|
+
const repEntry = { path: rep.path, content: rep.compressed, size: rep.compressed.length, priority: rep.score };
|
|
833
856
|
const repSize = rep.path.length + rep.compressed.length + 10;
|
|
834
857
|
if (includedChars + repSize <= CHAR_BUDGET) {
|
|
835
858
|
result.push(repEntry);
|
|
@@ -841,14 +864,14 @@ function analyzeCode(dir) {
|
|
|
841
864
|
const summary = `(${similar.length} similar file${similar.length === 1 ? "" : "s"} in ${dirPath}/: ${names.join(", ")})`;
|
|
842
865
|
const summarySize = summary.length + 30;
|
|
843
866
|
if (includedChars + summarySize <= CHAR_BUDGET) {
|
|
844
|
-
result.push({ path: `[similar to ${rep.path}]`, content: summary, size: summary.length });
|
|
867
|
+
result.push({ path: `[similar to ${rep.path}]`, content: summary, size: summary.length, priority: rep.score });
|
|
845
868
|
includedChars += summarySize;
|
|
846
869
|
}
|
|
847
870
|
}
|
|
848
871
|
for (const f of unique) {
|
|
849
872
|
const skeletonSize = f.path.length + f.skeleton.length + 10;
|
|
850
873
|
if (includedChars + skeletonSize <= CHAR_BUDGET) {
|
|
851
|
-
result.push({ path: f.path, content: f.skeleton, size: f.skeleton.length });
|
|
874
|
+
result.push({ path: f.path, content: f.skeleton, size: f.skeleton.length, priority: f.score });
|
|
852
875
|
includedChars += skeletonSize;
|
|
853
876
|
}
|
|
854
877
|
}
|
|
@@ -858,7 +881,7 @@ function analyzeCode(dir) {
|
|
|
858
881
|
if (includedPaths.has(f.path)) continue;
|
|
859
882
|
const skeletonSize = f.path.length + f.skeleton.length + 10;
|
|
860
883
|
if (includedChars + skeletonSize > CHAR_BUDGET) continue;
|
|
861
|
-
result.push({ path: f.path, content: f.skeleton, size: f.skeleton.length });
|
|
884
|
+
result.push({ path: f.path, content: f.skeleton, size: f.skeleton.length, priority: f.score });
|
|
862
885
|
includedChars += skeletonSize;
|
|
863
886
|
}
|
|
864
887
|
return {
|
|
@@ -2700,6 +2723,7 @@ async function generateSkillsForSetup(setup, fingerprint, targetAgent, onStatus)
|
|
|
2700
2723
|
if (failed > 0) onStatus?.(`${succeeded} generated, ${failed} failed`);
|
|
2701
2724
|
return succeeded;
|
|
2702
2725
|
}
|
|
2726
|
+
var MAX_PROMPT_TOKENS = 12e4;
|
|
2703
2727
|
var LIMITS = {
|
|
2704
2728
|
FILE_TREE_ENTRIES: 500,
|
|
2705
2729
|
EXISTING_CONFIG_CHARS: 8e3,
|
|
@@ -2712,6 +2736,41 @@ function truncate(text, maxChars) {
|
|
|
2712
2736
|
return text.slice(0, maxChars) + `
|
|
2713
2737
|
... (truncated at ${maxChars} chars)`;
|
|
2714
2738
|
}
|
|
2739
|
+
function sampleFileTree(fileTree, codeAnalysisPaths, limit) {
|
|
2740
|
+
if (fileTree.length <= limit) return fileTree;
|
|
2741
|
+
const dirs = [];
|
|
2742
|
+
const rootFiles = [];
|
|
2743
|
+
const nestedFiles = [];
|
|
2744
|
+
for (const entry of fileTree) {
|
|
2745
|
+
if (entry.endsWith("/")) {
|
|
2746
|
+
dirs.push(entry);
|
|
2747
|
+
} else if (!entry.includes("/")) {
|
|
2748
|
+
rootFiles.push(entry);
|
|
2749
|
+
} else {
|
|
2750
|
+
nestedFiles.push(entry);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
const result = [];
|
|
2754
|
+
const included = /* @__PURE__ */ new Set();
|
|
2755
|
+
function add(entry) {
|
|
2756
|
+
if (!included.has(entry)) {
|
|
2757
|
+
included.add(entry);
|
|
2758
|
+
result.push(entry);
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
const dirBudget = Math.min(dirs.length, Math.floor(limit * 0.4));
|
|
2762
|
+
for (let i = 0; i < dirBudget; i++) add(dirs[i]);
|
|
2763
|
+
for (const f of rootFiles.slice(0, 50)) add(f);
|
|
2764
|
+
for (const p of codeAnalysisPaths) {
|
|
2765
|
+
if (result.length >= limit) break;
|
|
2766
|
+
if (fileTree.includes(p)) add(p);
|
|
2767
|
+
}
|
|
2768
|
+
for (const f of nestedFiles) {
|
|
2769
|
+
if (result.length >= limit) break;
|
|
2770
|
+
add(f);
|
|
2771
|
+
}
|
|
2772
|
+
return result.slice(0, limit);
|
|
2773
|
+
}
|
|
2715
2774
|
function buildGeneratePrompt(fingerprint, targetAgent, prompt, failingChecks, currentScore, passingChecks) {
|
|
2716
2775
|
const parts = [];
|
|
2717
2776
|
const existing = fingerprint.existingConfigs;
|
|
@@ -2763,9 +2822,10 @@ Git remote: ${fingerprint.gitRemoteUrl}`);
|
|
|
2763
2822
|
if (fingerprint.frameworks.length > 0) parts.push(`Frameworks: ${fingerprint.frameworks.join(", ")}`);
|
|
2764
2823
|
if (fingerprint.description) parts.push(`Project description: ${fingerprint.description}`);
|
|
2765
2824
|
if (fingerprint.fileTree.length > 0) {
|
|
2766
|
-
const
|
|
2825
|
+
const caPaths = fingerprint.codeAnalysis?.files.map((f) => f.path) ?? [];
|
|
2826
|
+
const tree = sampleFileTree(fingerprint.fileTree, caPaths, LIMITS.FILE_TREE_ENTRIES);
|
|
2767
2827
|
parts.push(`
|
|
2768
|
-
File tree (
|
|
2828
|
+
File tree (${tree.length}/${fingerprint.fileTree.length}):
|
|
2769
2829
|
${tree.join("\n")}`);
|
|
2770
2830
|
}
|
|
2771
2831
|
if (existing.claudeMd) parts.push(`
|
|
@@ -2816,23 +2876,6 @@ ${truncate(skill.content, LIMITS.SKILL_CHARS)}`);
|
|
|
2816
2876
|
(${existing.cursorSkills.length - LIMITS.SKILLS_MAX} more skills omitted)`);
|
|
2817
2877
|
}
|
|
2818
2878
|
}
|
|
2819
|
-
if (fingerprint.codeAnalysis) {
|
|
2820
|
-
const ca = fingerprint.codeAnalysis;
|
|
2821
|
-
if (ca.truncated) {
|
|
2822
|
-
const pct = ca.totalProjectTokens > 0 ? Math.round(ca.includedTokens / ca.totalProjectTokens * 100) : 100;
|
|
2823
|
-
parts.push(`
|
|
2824
|
-
--- Project Files (trimmed to ~${ca.includedTokens.toLocaleString()}/${ca.totalProjectTokens.toLocaleString()} tokens, ${pct}% of total) ---`);
|
|
2825
|
-
} else {
|
|
2826
|
-
parts.push(`
|
|
2827
|
-
--- Project Files (${ca.files.length} files, ~${ca.includedTokens.toLocaleString()} tokens) ---`);
|
|
2828
|
-
}
|
|
2829
|
-
parts.push("Study these files to extract patterns for skills. Use the exact code patterns you see here.\n");
|
|
2830
|
-
for (const f of ca.files) {
|
|
2831
|
-
parts.push(`[${f.path}]`);
|
|
2832
|
-
parts.push(f.content);
|
|
2833
|
-
parts.push("");
|
|
2834
|
-
}
|
|
2835
|
-
}
|
|
2836
2879
|
const allDeps = extractAllDeps(process.cwd());
|
|
2837
2880
|
if (allDeps.length > 0) {
|
|
2838
2881
|
parts.push(`
|
|
@@ -2841,6 +2884,42 @@ Project dependencies (${allDeps.length}):`);
|
|
|
2841
2884
|
}
|
|
2842
2885
|
if (prompt) parts.push(`
|
|
2843
2886
|
User instructions: ${prompt}`);
|
|
2887
|
+
if (fingerprint.codeAnalysis) {
|
|
2888
|
+
const ca = fingerprint.codeAnalysis;
|
|
2889
|
+
const basePrompt = parts.join("\n");
|
|
2890
|
+
const baseTokens = estimateTokens(basePrompt);
|
|
2891
|
+
const tokenBudgetForCode = Math.max(0, MAX_PROMPT_TOKENS - baseTokens);
|
|
2892
|
+
const codeLines = [];
|
|
2893
|
+
let codeChars = 0;
|
|
2894
|
+
codeLines.push("Study these files to extract patterns for skills. Use the exact code patterns you see here.\n");
|
|
2895
|
+
const sortedFiles = [...ca.files].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
2896
|
+
let includedFiles = 0;
|
|
2897
|
+
for (const f of sortedFiles) {
|
|
2898
|
+
const entry = `[${f.path}]
|
|
2899
|
+
${f.content}
|
|
2900
|
+
`;
|
|
2901
|
+
if (estimateTokens(codeLines.join("\n") + entry) > tokenBudgetForCode && includedFiles > 0) break;
|
|
2902
|
+
codeLines.push(entry);
|
|
2903
|
+
codeChars += f.content.length;
|
|
2904
|
+
includedFiles++;
|
|
2905
|
+
}
|
|
2906
|
+
const includedTokens = Math.ceil(codeChars / 4);
|
|
2907
|
+
let header;
|
|
2908
|
+
if (includedFiles < ca.files.length) {
|
|
2909
|
+
const pct = ca.totalProjectTokens > 0 ? Math.round(includedTokens / ca.totalProjectTokens * 100) : 100;
|
|
2910
|
+
header = `
|
|
2911
|
+
--- Project Files (trimmed to ~${includedTokens.toLocaleString()}/${ca.totalProjectTokens.toLocaleString()} tokens, ${pct}% of total) ---`;
|
|
2912
|
+
} else if (ca.truncated) {
|
|
2913
|
+
const pct = ca.totalProjectTokens > 0 ? Math.round(ca.includedTokens / ca.totalProjectTokens * 100) : 100;
|
|
2914
|
+
header = `
|
|
2915
|
+
--- Project Files (trimmed to ~${ca.includedTokens.toLocaleString()}/${ca.totalProjectTokens.toLocaleString()} tokens, ${pct}% of total) ---`;
|
|
2916
|
+
} else {
|
|
2917
|
+
header = `
|
|
2918
|
+
--- Project Files (${ca.files.length} files, ~${ca.includedTokens.toLocaleString()} tokens) ---`;
|
|
2919
|
+
}
|
|
2920
|
+
parts.push(header);
|
|
2921
|
+
parts.push(codeLines.join("\n"));
|
|
2922
|
+
}
|
|
2844
2923
|
return parts.join("\n");
|
|
2845
2924
|
}
|
|
2846
2925
|
|
|
@@ -9162,7 +9241,7 @@ function sanitizeSecrets(text) {
|
|
|
9162
9241
|
|
|
9163
9242
|
// src/ai/learn.ts
|
|
9164
9243
|
init_config();
|
|
9165
|
-
var
|
|
9244
|
+
var MAX_PROMPT_TOKENS2 = 1e5;
|
|
9166
9245
|
function formatEventsForPrompt(events) {
|
|
9167
9246
|
return events.map((e, i) => {
|
|
9168
9247
|
if (e.hook_event_name === "UserPromptSubmit") {
|
|
@@ -9210,7 +9289,7 @@ function parseAnalysisResponse(raw) {
|
|
|
9210
9289
|
}
|
|
9211
9290
|
}
|
|
9212
9291
|
async function analyzeEvents(events, existingClaudeMd, existingLearnedSection, existingSkills) {
|
|
9213
|
-
const fittedEvents = trimEventsToFit(events,
|
|
9292
|
+
const fittedEvents = trimEventsToFit(events, MAX_PROMPT_TOKENS2 - 1e4);
|
|
9214
9293
|
const eventsText = formatEventsForPrompt(fittedEvents);
|
|
9215
9294
|
const contextParts = [];
|
|
9216
9295
|
if (existingClaudeMd) {
|
package/package.json
CHANGED