@rely-ai/caliber 1.13.1 → 1.14.1
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 +169 -298
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -408,117 +408,145 @@ var IGNORE_DIRS2 = /* @__PURE__ */ new Set([
|
|
|
408
408
|
".caliber",
|
|
409
409
|
"__pycache__",
|
|
410
410
|
".venv",
|
|
411
|
+
"venv",
|
|
412
|
+
"env",
|
|
411
413
|
"vendor",
|
|
412
|
-
"target"
|
|
414
|
+
"target",
|
|
415
|
+
".parcel-cache",
|
|
416
|
+
".nyc_output",
|
|
417
|
+
".claude",
|
|
418
|
+
".cursor",
|
|
419
|
+
".agents",
|
|
420
|
+
".codex"
|
|
413
421
|
]);
|
|
414
|
-
var
|
|
415
|
-
|
|
416
|
-
"
|
|
417
|
-
"
|
|
418
|
-
"
|
|
419
|
-
"
|
|
420
|
-
"
|
|
421
|
-
"
|
|
422
|
-
"
|
|
423
|
-
"
|
|
424
|
-
"
|
|
425
|
-
"
|
|
426
|
-
"
|
|
427
|
-
"
|
|
428
|
-
"
|
|
429
|
-
"
|
|
430
|
-
"
|
|
431
|
-
"
|
|
432
|
-
"
|
|
433
|
-
"
|
|
434
|
-
"
|
|
435
|
-
"
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
440
|
-
"
|
|
441
|
-
"
|
|
442
|
-
"
|
|
443
|
-
"
|
|
444
|
-
"
|
|
422
|
+
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
423
|
+
".ts",
|
|
424
|
+
".tsx",
|
|
425
|
+
".js",
|
|
426
|
+
".jsx",
|
|
427
|
+
".mjs",
|
|
428
|
+
".cjs",
|
|
429
|
+
".py",
|
|
430
|
+
".pyw",
|
|
431
|
+
".go",
|
|
432
|
+
".rs",
|
|
433
|
+
".rb",
|
|
434
|
+
".java",
|
|
435
|
+
".kt",
|
|
436
|
+
".scala",
|
|
437
|
+
".cs",
|
|
438
|
+
".c",
|
|
439
|
+
".cpp",
|
|
440
|
+
".h",
|
|
441
|
+
".hpp",
|
|
442
|
+
".swift",
|
|
443
|
+
".m",
|
|
444
|
+
".php",
|
|
445
|
+
".lua",
|
|
446
|
+
".r",
|
|
447
|
+
".jl",
|
|
448
|
+
".ex",
|
|
449
|
+
".exs",
|
|
450
|
+
".erl",
|
|
451
|
+
".hs",
|
|
452
|
+
".sh",
|
|
453
|
+
".bash",
|
|
454
|
+
".zsh",
|
|
455
|
+
".fish",
|
|
456
|
+
".sql",
|
|
457
|
+
".graphql",
|
|
458
|
+
".gql",
|
|
459
|
+
".prisma",
|
|
460
|
+
".html",
|
|
461
|
+
".css",
|
|
462
|
+
".scss",
|
|
463
|
+
".sass",
|
|
464
|
+
".less",
|
|
465
|
+
".svelte",
|
|
466
|
+
".vue",
|
|
467
|
+
".astro",
|
|
468
|
+
".json",
|
|
469
|
+
".yaml",
|
|
470
|
+
".yml",
|
|
471
|
+
".toml",
|
|
472
|
+
".ini",
|
|
473
|
+
".cfg",
|
|
474
|
+
".env",
|
|
475
|
+
".xml",
|
|
476
|
+
".plist",
|
|
477
|
+
".md",
|
|
478
|
+
".mdx",
|
|
479
|
+
".txt",
|
|
480
|
+
".rst",
|
|
481
|
+
".tf",
|
|
482
|
+
".hcl",
|
|
483
|
+
".proto",
|
|
484
|
+
".mdc"
|
|
445
485
|
]);
|
|
446
|
-
var
|
|
447
|
-
|
|
486
|
+
var SKIP_FILES = /* @__PURE__ */ new Set([
|
|
487
|
+
"package-lock.json",
|
|
488
|
+
"yarn.lock",
|
|
489
|
+
"pnpm-lock.yaml",
|
|
490
|
+
"bun.lockb",
|
|
491
|
+
"Cargo.lock",
|
|
492
|
+
"Gemfile.lock",
|
|
493
|
+
"poetry.lock",
|
|
494
|
+
"composer.lock",
|
|
495
|
+
".DS_Store",
|
|
496
|
+
"Thumbs.db"
|
|
497
|
+
]);
|
|
498
|
+
var SKIP_PATTERNS = [
|
|
499
|
+
/\.min\.(js|css)$/,
|
|
500
|
+
/\.bundle\.(js|css)$/,
|
|
501
|
+
/\.map$/,
|
|
502
|
+
/\.d\.ts$/,
|
|
503
|
+
/\.generated\./,
|
|
504
|
+
/\.snap$/
|
|
448
505
|
];
|
|
449
|
-
var
|
|
450
|
-
var
|
|
451
|
-
var SOURCE_BUDGET = Math.floor(TOTAL_BUDGET * 0.85);
|
|
506
|
+
var TOKEN_BUDGET = 18e4;
|
|
507
|
+
var CHAR_BUDGET = TOKEN_BUDGET * 4;
|
|
452
508
|
function analyzeCode(dir) {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
let
|
|
458
|
-
const trimmedConfigs = [];
|
|
459
|
-
for (const cfg of configFiles) {
|
|
460
|
-
const size = cfg.path.length + cfg.content.length;
|
|
461
|
-
if (configChars + size > CONFIG_BUDGET) break;
|
|
462
|
-
trimmedConfigs.push(cfg);
|
|
463
|
-
configChars += size;
|
|
464
|
-
}
|
|
465
|
-
let sourceChars = 0;
|
|
509
|
+
const allFiles = [];
|
|
510
|
+
walkDir(dir, "", 0, 10, allFiles);
|
|
511
|
+
sortByPriority(allFiles);
|
|
512
|
+
let totalChars = 0;
|
|
513
|
+
let includedChars = 0;
|
|
466
514
|
let truncated = false;
|
|
467
|
-
const
|
|
468
|
-
const
|
|
469
|
-
const
|
|
470
|
-
const SUMMARY_BUDGET = SOURCE_BUDGET - CONTENT_BUDGET;
|
|
471
|
-
for (const relPath of sourceFiles) {
|
|
472
|
-
const fullPath = path3.join(dir, relPath);
|
|
473
|
-
let fileContent;
|
|
515
|
+
const files = [];
|
|
516
|
+
const fileSizes = /* @__PURE__ */ new Map();
|
|
517
|
+
for (const relPath of allFiles) {
|
|
474
518
|
try {
|
|
475
|
-
|
|
519
|
+
const stat = fs3.statSync(path3.join(dir, relPath));
|
|
520
|
+
fileSizes.set(relPath, stat.size);
|
|
521
|
+
totalChars += stat.size;
|
|
476
522
|
} catch {
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
const lineCount = fileContent.split("\n").length;
|
|
480
|
-
if (lineCount > MAX_CONTENT_LINE_COUNT) continue;
|
|
481
|
-
const ext = path3.extname(relPath);
|
|
482
|
-
const language = resolveLanguage(ext);
|
|
483
|
-
if (!language) continue;
|
|
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
523
|
}
|
|
491
|
-
fileSummaries.push(summary);
|
|
492
|
-
sourceChars += entrySize;
|
|
493
524
|
}
|
|
494
|
-
const
|
|
495
|
-
let summaryChars = 0;
|
|
496
|
-
for (const relPath of sourceFiles) {
|
|
497
|
-
if (processedPaths.has(relPath)) continue;
|
|
525
|
+
for (const relPath of allFiles) {
|
|
498
526
|
const fullPath = path3.join(dir, relPath);
|
|
499
|
-
let
|
|
527
|
+
let content;
|
|
500
528
|
try {
|
|
501
|
-
|
|
529
|
+
content = fs3.readFileSync(fullPath, "utf-8");
|
|
502
530
|
} catch {
|
|
503
531
|
continue;
|
|
504
532
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
const language = resolveLanguage(ext);
|
|
509
|
-
if (!language) continue;
|
|
510
|
-
const summary = language === "py" ? extractPython(relPath, fileContent) : extractTypeScriptJavaScript(relPath, fileContent, language);
|
|
511
|
-
const summarySize = estimateSummarySize(summary);
|
|
512
|
-
if (summaryChars + summarySize > SUMMARY_BUDGET) {
|
|
533
|
+
if (content.split("\n").length > 500) continue;
|
|
534
|
+
const entrySize = relPath.length + content.length + 10;
|
|
535
|
+
if (includedChars + entrySize > CHAR_BUDGET) {
|
|
513
536
|
truncated = true;
|
|
514
|
-
|
|
537
|
+
continue;
|
|
515
538
|
}
|
|
516
|
-
|
|
517
|
-
|
|
539
|
+
files.push({ path: relPath, content, size: content.length });
|
|
540
|
+
includedChars += entrySize;
|
|
518
541
|
}
|
|
519
|
-
return {
|
|
542
|
+
return {
|
|
543
|
+
files,
|
|
544
|
+
truncated,
|
|
545
|
+
totalProjectTokens: Math.ceil(totalChars / 4),
|
|
546
|
+
includedTokens: Math.ceil(includedChars / 4)
|
|
547
|
+
};
|
|
520
548
|
}
|
|
521
|
-
function walkDir(base, rel, depth, maxDepth,
|
|
549
|
+
function walkDir(base, rel, depth, maxDepth, files) {
|
|
522
550
|
if (depth > maxDepth) return;
|
|
523
551
|
const fullPath = path3.join(base, rel);
|
|
524
552
|
let entries;
|
|
@@ -532,171 +560,52 @@ function walkDir(base, rel, depth, maxDepth, sourceFiles, configFiles, rootDir)
|
|
|
532
560
|
if (entry.name.startsWith(".") && depth === 0 && entry.isDirectory()) continue;
|
|
533
561
|
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
534
562
|
if (entry.isDirectory()) {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
);
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
} else {
|
|
543
|
-
if (CONFIG_FILE_NAMES.has(entry.name)) {
|
|
544
|
-
try {
|
|
545
|
-
const content = fs3.readFileSync(path3.join(base, relPath), "utf-8");
|
|
546
|
-
configFiles.push({ path: relPath, content });
|
|
547
|
-
} catch {
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
const ext = path3.extname(entry.name);
|
|
551
|
-
if (SOURCE_EXTENSIONS.has(ext) && !entry.name.endsWith(".d.ts")) {
|
|
552
|
-
sourceFiles.push(relPath);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
function collectConfigsFromDir(base, relDir, pattern, configFiles) {
|
|
558
|
-
const fullDir = path3.join(base, relDir);
|
|
559
|
-
let entries;
|
|
560
|
-
try {
|
|
561
|
-
entries = fs3.readdirSync(fullDir, { withFileTypes: true });
|
|
562
|
-
} catch {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
for (const entry of entries) {
|
|
566
|
-
if (entry.isFile() && pattern.test(entry.name)) {
|
|
567
|
-
const relPath = `${relDir}/${entry.name}`;
|
|
568
|
-
try {
|
|
569
|
-
const content = fs3.readFileSync(path3.join(base, relPath), "utf-8");
|
|
570
|
-
configFiles.push({ path: relPath, content });
|
|
571
|
-
} catch {
|
|
563
|
+
walkDir(base, relPath, depth + 1, maxDepth, files);
|
|
564
|
+
} else if (entry.isFile()) {
|
|
565
|
+
if (SKIP_FILES.has(entry.name)) continue;
|
|
566
|
+
if (SKIP_PATTERNS.some((p) => p.test(entry.name))) continue;
|
|
567
|
+
const ext = path3.extname(entry.name).toLowerCase();
|
|
568
|
+
if (TEXT_EXTENSIONS.has(ext) || depth === 0 && !ext && !entry.name.startsWith(".")) {
|
|
569
|
+
files.push(relPath);
|
|
572
570
|
}
|
|
573
571
|
}
|
|
574
572
|
}
|
|
575
573
|
}
|
|
576
574
|
function sortByPriority(files) {
|
|
577
|
-
const entryPointNames = /* @__PURE__ */ new Set([
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
575
|
+
const entryPointNames = /* @__PURE__ */ new Set([
|
|
576
|
+
"index.ts",
|
|
577
|
+
"index.js",
|
|
578
|
+
"index.tsx",
|
|
579
|
+
"index.jsx",
|
|
580
|
+
"main.ts",
|
|
581
|
+
"main.py",
|
|
582
|
+
"main.go",
|
|
583
|
+
"main.rs",
|
|
584
|
+
"app.ts",
|
|
585
|
+
"app.js",
|
|
586
|
+
"app.py",
|
|
587
|
+
"server.ts",
|
|
588
|
+
"server.js",
|
|
589
|
+
"mod.rs",
|
|
590
|
+
"lib.rs"
|
|
591
|
+
]);
|
|
592
|
+
const configPattern = /\.(json|ya?ml|toml|ini|cfg|env)$|config\.|Makefile|Dockerfile/i;
|
|
593
|
+
const routePattern = /(route|api|controller|endpoint|handler)/i;
|
|
594
|
+
const schemaPattern = /(types|schema|models|entities|migration)/i;
|
|
595
|
+
const servicePattern = /(service|lib|utils|helper|middleware)/i;
|
|
596
|
+
const testPattern = /(test|spec|__tests__|_test\.|\.test\.)/i;
|
|
582
597
|
function priority(filePath) {
|
|
583
598
|
const base = path3.basename(filePath);
|
|
584
599
|
if (entryPointNames.has(base)) return 0;
|
|
585
|
-
if (
|
|
586
|
-
if (
|
|
587
|
-
if (
|
|
588
|
-
if (
|
|
589
|
-
return
|
|
600
|
+
if (configPattern.test(filePath)) return 1;
|
|
601
|
+
if (routePattern.test(filePath)) return 2;
|
|
602
|
+
if (schemaPattern.test(filePath)) return 3;
|
|
603
|
+
if (servicePattern.test(filePath)) return 4;
|
|
604
|
+
if (testPattern.test(filePath)) return 6;
|
|
605
|
+
return 5;
|
|
590
606
|
}
|
|
591
607
|
files.sort((a, b) => priority(a) - priority(b));
|
|
592
608
|
}
|
|
593
|
-
function resolveLanguage(ext) {
|
|
594
|
-
if (ext === ".ts" || ext === ".tsx") return "ts";
|
|
595
|
-
if (ext === ".js" || ext === ".jsx") return "js";
|
|
596
|
-
if (ext === ".py") return "py";
|
|
597
|
-
return null;
|
|
598
|
-
}
|
|
599
|
-
function extractTypeScriptJavaScript(filePath, content, language) {
|
|
600
|
-
const lines = content.split("\n");
|
|
601
|
-
const imports = [];
|
|
602
|
-
const exports = [];
|
|
603
|
-
const functions = [];
|
|
604
|
-
const classes = [];
|
|
605
|
-
const types = [];
|
|
606
|
-
const routes = [];
|
|
607
|
-
for (const line of lines) {
|
|
608
|
-
const trimmed = line.trim();
|
|
609
|
-
if (/^import\s+/.test(trimmed)) {
|
|
610
|
-
imports.push(trimmed);
|
|
611
|
-
continue;
|
|
612
|
-
}
|
|
613
|
-
const exportMatch = trimmed.match(
|
|
614
|
-
/^export\s+(?:default\s+)?(?:async\s+)?(function|const|class|interface|type|enum)\s+(\w+)/
|
|
615
|
-
);
|
|
616
|
-
if (exportMatch) {
|
|
617
|
-
exports.push(`${exportMatch[1]} ${exportMatch[2]}`);
|
|
618
|
-
if (exportMatch[1] === "class") classes.push(exportMatch[2]);
|
|
619
|
-
if (exportMatch[1] === "interface" || exportMatch[1] === "type") types.push(exportMatch[2]);
|
|
620
|
-
if (exportMatch[1] === "function") functions.push(exportMatch[2]);
|
|
621
|
-
continue;
|
|
622
|
-
}
|
|
623
|
-
const fnMatch = trimmed.match(/^(?:async\s+)?function\s+(\w+)/);
|
|
624
|
-
if (fnMatch && !trimmed.startsWith("export")) {
|
|
625
|
-
functions.push(fnMatch[1]);
|
|
626
|
-
continue;
|
|
627
|
-
}
|
|
628
|
-
const arrowMatch = trimmed.match(/^(?:export\s+)?const\s+(\w+)\s*=\s*(?:async\s*)?\(/);
|
|
629
|
-
if (arrowMatch && !exports.some((e) => e.endsWith(arrowMatch[1]))) {
|
|
630
|
-
functions.push(arrowMatch[1]);
|
|
631
|
-
}
|
|
632
|
-
const classMatch = trimmed.match(/^class\s+(\w+)/);
|
|
633
|
-
if (classMatch && !trimmed.startsWith("export")) {
|
|
634
|
-
classes.push(classMatch[1]);
|
|
635
|
-
continue;
|
|
636
|
-
}
|
|
637
|
-
const ifaceMatch = trimmed.match(/^(?:interface|type)\s+(\w+)/);
|
|
638
|
-
if (ifaceMatch && !trimmed.startsWith("export")) {
|
|
639
|
-
types.push(ifaceMatch[1]);
|
|
640
|
-
continue;
|
|
641
|
-
}
|
|
642
|
-
const routeMatch = trimmed.match(
|
|
643
|
-
/(?:router|app|server)\.(get|post|put|patch|delete|all|use)\s*\(\s*['"`]([^'"`]+)['"`]/
|
|
644
|
-
);
|
|
645
|
-
if (routeMatch) {
|
|
646
|
-
routes.push(`${routeMatch[1].toUpperCase()} ${routeMatch[2]}`);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return { path: filePath, language, imports, exports, functions, classes, types, routes };
|
|
650
|
-
}
|
|
651
|
-
function extractPython(filePath, content) {
|
|
652
|
-
const lines = content.split("\n");
|
|
653
|
-
const imports = [];
|
|
654
|
-
const functions = [];
|
|
655
|
-
const classes = [];
|
|
656
|
-
const routes = [];
|
|
657
|
-
let prevLine = "";
|
|
658
|
-
for (const line of lines) {
|
|
659
|
-
const trimmed = line.trim();
|
|
660
|
-
if (/^import\s+/.test(trimmed) || /^from\s+/.test(trimmed)) {
|
|
661
|
-
imports.push(trimmed);
|
|
662
|
-
continue;
|
|
663
|
-
}
|
|
664
|
-
const defMatch = trimmed.match(/^def\s+(\w+)\s*\(([^)]*)\)/);
|
|
665
|
-
if (defMatch) {
|
|
666
|
-
functions.push(`${defMatch[1]}(${defMatch[2]})`);
|
|
667
|
-
}
|
|
668
|
-
const classMatch = trimmed.match(/^class\s+(\w+)/);
|
|
669
|
-
if (classMatch) {
|
|
670
|
-
classes.push(classMatch[1]);
|
|
671
|
-
}
|
|
672
|
-
const decoratorRoute = prevLine.match(
|
|
673
|
-
/@(?:app|router)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"]([^'"]+)['"]/
|
|
674
|
-
);
|
|
675
|
-
if (decoratorRoute && defMatch) {
|
|
676
|
-
routes.push(`${decoratorRoute[1].toUpperCase()} ${decoratorRoute[2]}`);
|
|
677
|
-
}
|
|
678
|
-
const includeRouter = trimmed.match(
|
|
679
|
-
/include_router\s*\([^,]+,\s*prefix\s*=\s*['"]([^'"]+)['"]/
|
|
680
|
-
);
|
|
681
|
-
if (includeRouter) {
|
|
682
|
-
routes.push(`ROUTER ${includeRouter[1]}`);
|
|
683
|
-
}
|
|
684
|
-
prevLine = trimmed;
|
|
685
|
-
}
|
|
686
|
-
return {
|
|
687
|
-
path: filePath,
|
|
688
|
-
language: "py",
|
|
689
|
-
imports,
|
|
690
|
-
exports: [],
|
|
691
|
-
functions,
|
|
692
|
-
classes,
|
|
693
|
-
types: [],
|
|
694
|
-
routes
|
|
695
|
-
};
|
|
696
|
-
}
|
|
697
|
-
function estimateSummarySize(summary) {
|
|
698
|
-
return summary.path.length + summary.imports.reduce((s, i) => s + i.length, 0) + summary.exports.reduce((s, e) => s + e.length, 0) + summary.functions.reduce((s, f) => s + f.length, 0) + summary.classes.reduce((s, c) => s + c.length, 0) + summary.types.reduce((s, t) => s + t.length, 0) + summary.routes.reduce((s, r) => s + r.length, 0);
|
|
699
|
-
}
|
|
700
609
|
|
|
701
610
|
// src/llm/index.ts
|
|
702
611
|
init_config();
|
|
@@ -2469,12 +2378,7 @@ var LIMITS = {
|
|
|
2469
2378
|
EXISTING_CONFIG_CHARS: 8e3,
|
|
2470
2379
|
SKILLS_MAX: 10,
|
|
2471
2380
|
SKILL_CHARS: 3e3,
|
|
2472
|
-
RULES_MAX: 10
|
|
2473
|
-
CONFIG_FILES_MAX: 20,
|
|
2474
|
-
CONFIG_FILE_CHARS: 5e3,
|
|
2475
|
-
ROUTES_MAX: 100,
|
|
2476
|
-
FILE_SUMMARIES_MAX: 200,
|
|
2477
|
-
FILE_CONTENT_CHARS: 8e3
|
|
2381
|
+
RULES_MAX: 10
|
|
2478
2382
|
};
|
|
2479
2383
|
function truncate(text, maxChars) {
|
|
2480
2384
|
if (text.length <= maxChars) return text;
|
|
@@ -2587,52 +2491,19 @@ ${truncate(skill.content, LIMITS.SKILL_CHARS)}`);
|
|
|
2587
2491
|
}
|
|
2588
2492
|
if (fingerprint.codeAnalysis) {
|
|
2589
2493
|
const ca = fingerprint.codeAnalysis;
|
|
2590
|
-
if (ca.configFiles.length > 0) {
|
|
2591
|
-
parts.push("\n--- Project Config Files ---");
|
|
2592
|
-
for (const cfg of ca.configFiles.slice(0, LIMITS.CONFIG_FILES_MAX)) {
|
|
2593
|
-
parts.push(`
|
|
2594
|
-
[${cfg.path}]
|
|
2595
|
-
${truncate(cfg.content, LIMITS.CONFIG_FILE_CHARS)}`);
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
const allRoutes = ca.fileSummaries.filter((f) => f.routes.length > 0).flatMap((f) => f.routes.map((r) => `${r} (${f.path})`));
|
|
2599
|
-
if (allRoutes.length > 0) {
|
|
2600
|
-
parts.push("\n--- API Routes ---");
|
|
2601
|
-
for (const route of allRoutes.slice(0, LIMITS.ROUTES_MAX)) {
|
|
2602
|
-
parts.push(`- ${route}`);
|
|
2603
|
-
}
|
|
2604
|
-
if (allRoutes.length > LIMITS.ROUTES_MAX) {
|
|
2605
|
-
parts.push(`(${allRoutes.length - LIMITS.ROUTES_MAX} more routes omitted)`);
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
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) {
|
|
2619
|
-
parts.push("\n--- Source File Summaries ---");
|
|
2620
|
-
for (const f of filesWithoutContent.slice(0, LIMITS.FILE_SUMMARIES_MAX)) {
|
|
2621
|
-
const sections = [`[${f.path}] (${f.language})`];
|
|
2622
|
-
if (f.imports.length > 0) sections.push(` imports: ${f.imports.slice(0, 10).join("; ")}`);
|
|
2623
|
-
if (f.exports.length > 0) sections.push(` exports: ${f.exports.slice(0, 10).join(", ")}`);
|
|
2624
|
-
if (f.functions.length > 0) sections.push(` functions: ${f.functions.slice(0, 10).join(", ")}`);
|
|
2625
|
-
if (f.classes.length > 0) sections.push(` classes: ${f.classes.join(", ")}`);
|
|
2626
|
-
if (f.types.length > 0) sections.push(` types: ${f.types.slice(0, 10).join(", ")}`);
|
|
2627
|
-
parts.push(sections.join("\n"));
|
|
2628
|
-
}
|
|
2629
|
-
if (filesWithoutContent.length > LIMITS.FILE_SUMMARIES_MAX) {
|
|
2630
|
-
parts.push(`
|
|
2631
|
-
(${filesWithoutContent.length - LIMITS.FILE_SUMMARIES_MAX} more files omitted)`);
|
|
2632
|
-
}
|
|
2633
|
-
}
|
|
2634
2494
|
if (ca.truncated) {
|
|
2635
|
-
|
|
2495
|
+
const pct = ca.totalProjectTokens > 0 ? Math.round(ca.includedTokens / ca.totalProjectTokens * 100) : 100;
|
|
2496
|
+
parts.push(`
|
|
2497
|
+
--- Project Files (trimmed to ~${ca.includedTokens.toLocaleString()}/${ca.totalProjectTokens.toLocaleString()} tokens, ${pct}% of total) ---`);
|
|
2498
|
+
} else {
|
|
2499
|
+
parts.push(`
|
|
2500
|
+
--- Project Files (${ca.files.length} files, ~${ca.includedTokens.toLocaleString()} tokens) ---`);
|
|
2501
|
+
}
|
|
2502
|
+
parts.push("Study these files to extract patterns for skills. Use the exact code patterns you see here.\n");
|
|
2503
|
+
for (const f of ca.files) {
|
|
2504
|
+
parts.push(`[${f.path}]`);
|
|
2505
|
+
parts.push(f.content);
|
|
2506
|
+
parts.push("");
|
|
2636
2507
|
}
|
|
2637
2508
|
}
|
|
2638
2509
|
const allDeps = extractAllDeps(process.cwd());
|
|
@@ -6149,7 +6020,7 @@ async function initCommand(options) {
|
|
|
6149
6020
|
spinner.succeed("Project analyzed");
|
|
6150
6021
|
log(options.verbose, `Fingerprint: ${fingerprint.languages.length} languages, ${fingerprint.frameworks.length} frameworks, ${fingerprint.fileTree.length} files`);
|
|
6151
6022
|
if (options.verbose && fingerprint.codeAnalysis) {
|
|
6152
|
-
log(options.verbose, `Code analysis: ${fingerprint.codeAnalysis.
|
|
6023
|
+
log(options.verbose, `Code analysis: ${fingerprint.codeAnalysis.files.length} files, ~${fingerprint.codeAnalysis.includedTokens.toLocaleString()} tokens${fingerprint.codeAnalysis.truncated ? ` (trimmed from ~${fingerprint.codeAnalysis.totalProjectTokens.toLocaleString()})` : ""}`);
|
|
6153
6024
|
}
|
|
6154
6025
|
trackInitProjectDiscovered(fingerprint.languages.length, fingerprint.frameworks.length, fingerprint.fileTree.length);
|
|
6155
6026
|
console.log(chalk8.dim(` Languages: ${fingerprint.languages.join(", ") || "none detected"}`));
|
package/package.json
CHANGED