sigmap 8.34.0 → 8.35.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/CHANGELOG.md +13 -0
- package/README.md +9 -9
- package/gen-context.js +217 -69
- package/llms-full.txt +6 -6
- package/llms.txt +6 -6
- package/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/extractors/cpp.js +8 -3
- package/src/extractors/csharp.js +8 -3
- package/src/extractors/css.js +1 -1
- package/src/extractors/dart.js +8 -3
- package/src/extractors/dockerfile.js +1 -1
- package/src/extractors/gdscript.js +2 -2
- package/src/extractors/go.js +13 -5
- package/src/extractors/html.js +1 -1
- package/src/extractors/javascript.js +7 -3
- package/src/extractors/kotlin.js +8 -3
- package/src/extractors/lua.js +1 -1
- package/src/extractors/markdown.js +1 -1
- package/src/extractors/php.js +8 -3
- package/src/extractors/properties.js +1 -1
- package/src/extractors/python.js +5 -2
- package/src/extractors/python_dataclass.js +3 -1
- package/src/extractors/r.js +1 -1
- package/src/extractors/ruby.js +1 -1
- package/src/extractors/rust.js +13 -5
- package/src/extractors/scala.js +8 -3
- package/src/extractors/shell.js +1 -1
- package/src/extractors/svelte.js +1 -1
- package/src/extractors/swift.js +8 -3
- package/src/extractors/toml.js +1 -1
- package/src/extractors/typescript.js +8 -4
- package/src/extractors/typescript_react.js +1 -1
- package/src/extractors/vue_sfc.js +3 -1
- package/src/extractors/xml.js +3 -1
- package/src/extractors/yaml.js +1 -1
- package/src/mcp/server.js +46 -4
- package/src/retrieval/ranker.js +14 -5
package/gen-context.js
CHANGED
|
@@ -5469,8 +5469,13 @@ __factories["./src/extractors/cpp"] = function(module, exports) {
|
|
|
5469
5469
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
5470
5470
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
5471
5471
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
5472
|
-
|
|
5473
|
-
|
|
5472
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
5473
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
5474
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
5475
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
5476
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
5477
|
+
const MEMBER_LIMIT = 120;
|
|
5478
|
+
const PER_FILE_LIMIT = 200;
|
|
5474
5479
|
|
|
5475
5480
|
/**
|
|
5476
5481
|
* Extract signatures from C/C++ source code.
|
|
@@ -5507,7 +5512,7 @@ __factories["./src/extractors/cpp"] = function(module, exports) {
|
|
|
5507
5512
|
|
|
5508
5513
|
function extractBlock(src, startIndex) {
|
|
5509
5514
|
let depth = 1, i = startIndex;
|
|
5510
|
-
const end = Math.min(src.length, startIndex +
|
|
5515
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
5511
5516
|
while (i < end && depth > 0) {
|
|
5512
5517
|
if (src[i] === '{') depth++;
|
|
5513
5518
|
else if (src[i] === '}') depth--;
|
|
@@ -5551,8 +5556,13 @@ __factories["./src/extractors/csharp"] = function(module, exports) {
|
|
|
5551
5556
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
5552
5557
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
5553
5558
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
5554
|
-
|
|
5555
|
-
|
|
5559
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
5560
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
5561
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
5562
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
5563
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
5564
|
+
const MEMBER_LIMIT = 120;
|
|
5565
|
+
const PER_FILE_LIMIT = 200;
|
|
5556
5566
|
|
|
5557
5567
|
/**
|
|
5558
5568
|
* Extract signatures from C# source code.
|
|
@@ -5587,7 +5597,7 @@ __factories["./src/extractors/csharp"] = function(module, exports) {
|
|
|
5587
5597
|
|
|
5588
5598
|
function extractBlock(src, startIndex) {
|
|
5589
5599
|
let depth = 1, i = startIndex;
|
|
5590
|
-
const end = Math.min(src.length, startIndex +
|
|
5600
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
5591
5601
|
while (i < end && depth > 0) {
|
|
5592
5602
|
if (src[i] === '{') depth++;
|
|
5593
5603
|
else if (src[i] === '}') depth--;
|
|
@@ -5632,7 +5642,7 @@ __factories["./src/extractors/css"] = function(module, exports) {
|
|
|
5632
5642
|
|
|
5633
5643
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
5634
5644
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
5635
|
-
const PER_FILE_LIMIT =
|
|
5645
|
+
const PER_FILE_LIMIT = 200;
|
|
5636
5646
|
|
|
5637
5647
|
/**
|
|
5638
5648
|
* Extract signatures from CSS/SCSS/SASS/Less source code.
|
|
@@ -5713,8 +5723,13 @@ __factories["./src/extractors/dart"] = function(module, exports) {
|
|
|
5713
5723
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
5714
5724
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
5715
5725
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
5716
|
-
|
|
5717
|
-
|
|
5726
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
5727
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
5728
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
5729
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
5730
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
5731
|
+
const MEMBER_LIMIT = 120;
|
|
5732
|
+
const PER_FILE_LIMIT = 200;
|
|
5718
5733
|
|
|
5719
5734
|
/**
|
|
5720
5735
|
* Extract signatures from Dart source code.
|
|
@@ -5768,7 +5783,7 @@ __factories["./src/extractors/dart"] = function(module, exports) {
|
|
|
5768
5783
|
|
|
5769
5784
|
function extractBlock(src, startIndex) {
|
|
5770
5785
|
let depth = 1, i = startIndex;
|
|
5771
|
-
const end = Math.min(src.length, startIndex +
|
|
5786
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
5772
5787
|
while (i < end && depth > 0) {
|
|
5773
5788
|
if (src[i] === '{') depth++;
|
|
5774
5789
|
else if (src[i] === '}') depth--;
|
|
@@ -6075,7 +6090,7 @@ __factories["./src/extractors/dockerfile"] = function(module, exports) {
|
|
|
6075
6090
|
|
|
6076
6091
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
6077
6092
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
6078
|
-
const PER_FILE_LIMIT =
|
|
6093
|
+
const PER_FILE_LIMIT = 200;
|
|
6079
6094
|
|
|
6080
6095
|
/**
|
|
6081
6096
|
* Extract signatures from Dockerfiles.
|
|
@@ -6134,10 +6149,10 @@ __factories["./src/extractors/gdscript"] = function(module, exports) {
|
|
|
6134
6149
|
|
|
6135
6150
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
6136
6151
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
6137
|
-
const PER_FILE_LIMIT =
|
|
6152
|
+
const PER_FILE_LIMIT = 200;
|
|
6138
6153
|
|
|
6139
6154
|
// Ceilings disclose what they drop rather than truncating silently (#576).
|
|
6140
|
-
const MEMBER_LIMIT =
|
|
6155
|
+
const MEMBER_LIMIT = 120;
|
|
6141
6156
|
const ENUM_LIMIT = 24;
|
|
6142
6157
|
|
|
6143
6158
|
/**
|
|
@@ -6307,11 +6322,19 @@ __factories["./src/extractors/generic"] = function(module, exports) {
|
|
|
6307
6322
|
__factories["./src/extractors/go"] = function(module, exports) {
|
|
6308
6323
|
|
|
6309
6324
|
const { lineAt, withAnchor } = __require('./src/extractors/line-anchor');
|
|
6310
|
-
const { capWithNotice } = __require('./src/util/truncate');
|
|
6325
|
+
const { capWithNotice, capMembersWithNotice } = __require('./src/util/truncate');
|
|
6311
6326
|
|
|
6312
6327
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
6313
6328
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
6314
|
-
|
|
6329
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
6330
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
6331
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
6332
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
6333
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
6334
|
+
const PER_FILE_LIMIT = 200;
|
|
6335
|
+
|
|
6336
|
+
// Per-interface member ceiling, disclosed via capMembersWithNotice (#576).
|
|
6337
|
+
const MEMBER_LIMIT = 120;
|
|
6315
6338
|
|
|
6316
6339
|
/**
|
|
6317
6340
|
* Extract signatures from Go source code.
|
|
@@ -6347,7 +6370,7 @@ __factories["./src/extractors/go"] = function(module, exports) {
|
|
|
6347
6370
|
const block = extractBlock(stripped, bodyStart);
|
|
6348
6371
|
sigs.push(hinted(withAnchor(`type ${m[1]} interface`, lineAt(stripped, m.index), lineAt(stripped, bodyStart + block.length)), m[1]));
|
|
6349
6372
|
for (const meth of extractInterfaceMethods(block)) {
|
|
6350
|
-
sigs.push(withAnchor(` ${meth.text}`, lineAt(stripped, bodyStart + meth.declIdx), lineAt(stripped, bodyStart + meth.endIdx)));
|
|
6373
|
+
sigs.push(withAnchor(` ${meth.text}`, lineAt(stripped, bodyStart + (meth.declIdx || 0)), lineAt(stripped, bodyStart + (meth.endIdx || 0))));
|
|
6351
6374
|
}
|
|
6352
6375
|
}
|
|
6353
6376
|
|
|
@@ -6365,7 +6388,7 @@ __factories["./src/extractors/go"] = function(module, exports) {
|
|
|
6365
6388
|
|
|
6366
6389
|
function extractBlock(src, startIndex) {
|
|
6367
6390
|
let depth = 1, i = startIndex;
|
|
6368
|
-
const end = Math.min(src.length, startIndex +
|
|
6391
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
6369
6392
|
while (i < end && depth > 0) {
|
|
6370
6393
|
if (src[i] === '{') depth++;
|
|
6371
6394
|
else if (src[i] === '}') depth--;
|
|
@@ -6385,7 +6408,7 @@ __factories["./src/extractors/go"] = function(module, exports) {
|
|
|
6385
6408
|
endIdx: m.index + m[0].length,
|
|
6386
6409
|
});
|
|
6387
6410
|
}
|
|
6388
|
-
return methods
|
|
6411
|
+
return capMembersWithNotice(methods, MEMBER_LIMIT, 'methods');
|
|
6389
6412
|
}
|
|
6390
6413
|
|
|
6391
6414
|
function normalizeParams(params) {
|
|
@@ -6498,7 +6521,7 @@ __factories["./src/extractors/html"] = function(module, exports) {
|
|
|
6498
6521
|
|
|
6499
6522
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
6500
6523
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
6501
|
-
const PER_FILE_LIMIT =
|
|
6524
|
+
const PER_FILE_LIMIT = 200;
|
|
6502
6525
|
|
|
6503
6526
|
/**
|
|
6504
6527
|
* Extract signatures from HTML files.
|
|
@@ -6673,6 +6696,10 @@ __factories["./src/extractors/javascript"] = function(module, exports) {
|
|
|
6673
6696
|
const { capWithNotice, capMembersWithNotice } = __require('./src/util/truncate');
|
|
6674
6697
|
const { stripComments, maskCode, readBalanced } = __require('./src/extractors/scan');
|
|
6675
6698
|
|
|
6699
|
+
// Class bodies are scanned to this many characters — guard against
|
|
6700
|
+
// pathological input only; the old 4KB window silently hid members (#576).
|
|
6701
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
6702
|
+
|
|
6676
6703
|
/**
|
|
6677
6704
|
* Extract signatures from JavaScript source code.
|
|
6678
6705
|
* Top-level declarations and class members carry a `:start-end` line anchor
|
|
@@ -6782,13 +6809,13 @@ __factories["./src/extractors/javascript"] = function(module, exports) {
|
|
|
6782
6809
|
const anchored = anchors[i] ? withAnchor(s, anchors[i][0], anchors[i][1]) : s;
|
|
6783
6810
|
return docHintFor[i] ? `${anchored} # ${docHintFor[i]}` : anchored;
|
|
6784
6811
|
});
|
|
6785
|
-
return capWithNotice(withAnchors,
|
|
6812
|
+
return capWithNotice(withAnchors, 200, 'signatures');
|
|
6786
6813
|
}
|
|
6787
6814
|
|
|
6788
6815
|
function extractBlock(src, startIndex) {
|
|
6789
6816
|
let depth = 1;
|
|
6790
6817
|
let i = startIndex;
|
|
6791
|
-
const end = Math.min(src.length, startIndex +
|
|
6818
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
6792
6819
|
while (i < end && depth > 0) {
|
|
6793
6820
|
if (src[i] === '{') depth++;
|
|
6794
6821
|
else if (src[i] === '}') depth--;
|
|
@@ -6823,7 +6850,7 @@ __factories["./src/extractors/javascript"] = function(module, exports) {
|
|
|
6823
6850
|
const retStr = formatReturnHint(returnHints.get(m[1]));
|
|
6824
6851
|
members.push({ text: `${isStatic}${isAsync}${m[1]}(${normalizeParams(params)})${retStr}`, start, end });
|
|
6825
6852
|
}
|
|
6826
|
-
return capMembersWithNotice(members,
|
|
6853
|
+
return capMembersWithNotice(members, 120, 'methods');
|
|
6827
6854
|
}
|
|
6828
6855
|
|
|
6829
6856
|
function buildReturnHints(src) {
|
|
@@ -6897,8 +6924,13 @@ __factories["./src/extractors/kotlin"] = function(module, exports) {
|
|
|
6897
6924
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
6898
6925
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
6899
6926
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
6900
|
-
|
|
6901
|
-
|
|
6927
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
6928
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
6929
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
6930
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
6931
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
6932
|
+
const MEMBER_LIMIT = 120;
|
|
6933
|
+
const PER_FILE_LIMIT = 200;
|
|
6902
6934
|
|
|
6903
6935
|
/**
|
|
6904
6936
|
* Extract signatures from Kotlin source code.
|
|
@@ -6952,7 +6984,7 @@ __factories["./src/extractors/kotlin"] = function(module, exports) {
|
|
|
6952
6984
|
|
|
6953
6985
|
function extractBlock(src, startIndex) {
|
|
6954
6986
|
let depth = 1, i = startIndex;
|
|
6955
|
-
const end = Math.min(src.length, startIndex +
|
|
6987
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
6956
6988
|
while (i < end && depth > 0) {
|
|
6957
6989
|
if (src[i] === '{') depth++;
|
|
6958
6990
|
else if (src[i] === '}') depth--;
|
|
@@ -7054,7 +7086,7 @@ __factories["./src/extractors/lua"] = function(module, exports) {
|
|
|
7054
7086
|
// Ceiling discloses what it drops rather than truncating silently (#583).
|
|
7055
7087
|
// Collection runs to completion so the marker reports the true overflow —
|
|
7056
7088
|
// stopping early made r.js report "+1 more" where 50 were hidden (#584).
|
|
7057
|
-
const PER_FILE_LIMIT =
|
|
7089
|
+
const PER_FILE_LIMIT = 200;
|
|
7058
7090
|
|
|
7059
7091
|
/**
|
|
7060
7092
|
* Extract signatures from Lua source code.
|
|
@@ -7208,7 +7240,7 @@ __factories["./src/extractors/markdown"] = function(module, exports) {
|
|
|
7208
7240
|
const { capWithNotice } = __require('./src/util/truncate');
|
|
7209
7241
|
|
|
7210
7242
|
// Ceiling discloses what it drops rather than truncating silently (#583).
|
|
7211
|
-
const PER_FILE_LIMIT =
|
|
7243
|
+
const PER_FILE_LIMIT = 200;
|
|
7212
7244
|
|
|
7213
7245
|
/**
|
|
7214
7246
|
* Lightweight markdown technical indexer.
|
|
@@ -7389,8 +7421,13 @@ __factories["./src/extractors/php"] = function(module, exports) {
|
|
|
7389
7421
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
7390
7422
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
7391
7423
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
7392
|
-
|
|
7393
|
-
|
|
7424
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
7425
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
7426
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
7427
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
7428
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
7429
|
+
const MEMBER_LIMIT = 120;
|
|
7430
|
+
const PER_FILE_LIMIT = 200;
|
|
7394
7431
|
|
|
7395
7432
|
/**
|
|
7396
7433
|
* Extract signatures from PHP source code.
|
|
@@ -7448,7 +7485,7 @@ __factories["./src/extractors/php"] = function(module, exports) {
|
|
|
7448
7485
|
|
|
7449
7486
|
function extractBlock(src, startIndex) {
|
|
7450
7487
|
let depth = 1, i = startIndex;
|
|
7451
|
-
const end = Math.min(src.length, startIndex +
|
|
7488
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
7452
7489
|
while (i < end && depth > 0) {
|
|
7453
7490
|
if (src[i] === '{') depth++;
|
|
7454
7491
|
else if (src[i] === '}') depth--;
|
|
@@ -7568,7 +7605,7 @@ __factories["./src/extractors/properties"] = function(module, exports) {
|
|
|
7568
7605
|
const { capWithNotice } = __require('./src/util/truncate');
|
|
7569
7606
|
|
|
7570
7607
|
// Ceiling discloses what it drops rather than truncating silently (#583).
|
|
7571
|
-
const PER_FILE_LIMIT =
|
|
7608
|
+
const PER_FILE_LIMIT = 200;
|
|
7572
7609
|
|
|
7573
7610
|
/**
|
|
7574
7611
|
* Extract signatures from .properties configuration files.
|
|
@@ -7684,7 +7721,10 @@ __factories["./src/extractors/python"] = function(module, exports) {
|
|
|
7684
7721
|
|
|
7685
7722
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
7686
7723
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
7687
|
-
const PER_FILE_LIMIT =
|
|
7724
|
+
const PER_FILE_LIMIT = 200;
|
|
7725
|
+
|
|
7726
|
+
// Per-class member ceiling, disclosed via capWithNotice (#576).
|
|
7727
|
+
const MEMBER_LIMIT = 120;
|
|
7688
7728
|
|
|
7689
7729
|
/**
|
|
7690
7730
|
* 1-based line of the last source line belonging to a top-level (indent 0)
|
|
@@ -7840,7 +7880,7 @@ __factories["./src/extractors/python"] = function(module, exports) {
|
|
|
7840
7880
|
methods.push(`${asyncKw}def ${m[1]}(${params})${retStr}`);
|
|
7841
7881
|
}
|
|
7842
7882
|
}
|
|
7843
|
-
return methods
|
|
7883
|
+
return capWithNotice(methods, MEMBER_LIMIT, 'methods');
|
|
7844
7884
|
}
|
|
7845
7885
|
|
|
7846
7886
|
function tryExtractDataclassFields(stripped, classIndex) {
|
|
@@ -7949,6 +7989,8 @@ __factories["./src/extractors/python"] = function(module, exports) {
|
|
|
7949
7989
|
// ── ./src/extractors/python_dataclass ──
|
|
7950
7990
|
__factories["./src/extractors/python_dataclass"] = function(module, exports) {
|
|
7951
7991
|
|
|
7992
|
+
const { capWithNotice } = __require('./src/util/truncate');
|
|
7993
|
+
|
|
7952
7994
|
/**
|
|
7953
7995
|
* Extract Python dataclass, Pydantic model, and SQLAlchemy ORM metadata.
|
|
7954
7996
|
* Focuses on model fields, validation, and relationships.
|
|
@@ -8020,7 +8062,7 @@ __factories["./src/extractors/python_dataclass"] = function(module, exports) {
|
|
|
8020
8062
|
sigs.push('config-class');
|
|
8021
8063
|
}
|
|
8022
8064
|
|
|
8023
|
-
return Array.from(new Set(sigs))
|
|
8065
|
+
return capWithNotice(Array.from(new Set(sigs)), 200, 'signatures');
|
|
8024
8066
|
}
|
|
8025
8067
|
|
|
8026
8068
|
module.exports = { extract };
|
|
@@ -8034,7 +8076,7 @@ __factories["./src/extractors/r"] = function(module, exports) {
|
|
|
8034
8076
|
|
|
8035
8077
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
8036
8078
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
8037
|
-
const PER_FILE_LIMIT =
|
|
8079
|
+
const PER_FILE_LIMIT = 200;
|
|
8038
8080
|
|
|
8039
8081
|
/**
|
|
8040
8082
|
* Extract signatures from R source code.
|
|
@@ -8313,7 +8355,7 @@ __factories["./src/extractors/ruby"] = function(module, exports) {
|
|
|
8313
8355
|
|
|
8314
8356
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
8315
8357
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
8316
|
-
const PER_FILE_LIMIT =
|
|
8358
|
+
const PER_FILE_LIMIT = 200;
|
|
8317
8359
|
|
|
8318
8360
|
/**
|
|
8319
8361
|
* Extract signatures from Ruby source code.
|
|
@@ -8374,11 +8416,19 @@ __factories["./src/extractors/ruby"] = function(module, exports) {
|
|
|
8374
8416
|
__factories["./src/extractors/rust"] = function(module, exports) {
|
|
8375
8417
|
|
|
8376
8418
|
const { lineAt, withAnchor } = __require('./src/extractors/line-anchor');
|
|
8377
|
-
const { capWithNotice } = __require('./src/util/truncate');
|
|
8419
|
+
const { capWithNotice, capMembersWithNotice } = __require('./src/util/truncate');
|
|
8378
8420
|
|
|
8379
8421
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
8380
8422
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
8381
|
-
|
|
8423
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
8424
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
8425
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
8426
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
8427
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
8428
|
+
const PER_FILE_LIMIT = 200;
|
|
8429
|
+
|
|
8430
|
+
// Per-impl member ceiling, disclosed via capMembersWithNotice (#576).
|
|
8431
|
+
const MEMBER_LIMIT = 120;
|
|
8382
8432
|
|
|
8383
8433
|
/**
|
|
8384
8434
|
* Extract signatures from Rust source code.
|
|
@@ -8436,7 +8486,7 @@ __factories["./src/extractors/rust"] = function(module, exports) {
|
|
|
8436
8486
|
const block = extractBlock(stripped, bodyStart);
|
|
8437
8487
|
sigs.push(withAnchor(`impl ${m[1]}`, lineAt(stripped, m.index), lineAt(stripped, bodyStart + block.length)));
|
|
8438
8488
|
for (const fn of extractMethods(block)) {
|
|
8439
|
-
sigs.push(hinted(withAnchor(` ${fn.text}`, lineAt(stripped, bodyStart + fn.declIdx), lineAt(stripped, bodyStart + fn.endIdx)), fn.name));
|
|
8489
|
+
sigs.push(hinted(withAnchor(` ${fn.text}`, lineAt(stripped, bodyStart + (fn.declIdx || 0)), lineAt(stripped, bodyStart + (fn.endIdx || 0))), fn.name));
|
|
8440
8490
|
}
|
|
8441
8491
|
}
|
|
8442
8492
|
|
|
@@ -8453,7 +8503,7 @@ __factories["./src/extractors/rust"] = function(module, exports) {
|
|
|
8453
8503
|
|
|
8454
8504
|
function extractBlock(src, startIndex) {
|
|
8455
8505
|
let depth = 1, i = startIndex;
|
|
8456
|
-
const end = Math.min(src.length, startIndex +
|
|
8506
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
8457
8507
|
while (i < end && depth > 0) {
|
|
8458
8508
|
if (src[i] === '{') depth++;
|
|
8459
8509
|
else if (src[i] === '}') depth--;
|
|
@@ -8474,7 +8524,7 @@ __factories["./src/extractors/rust"] = function(module, exports) {
|
|
|
8474
8524
|
endIdx: m.index + m[0].length,
|
|
8475
8525
|
});
|
|
8476
8526
|
}
|
|
8477
|
-
return methods
|
|
8527
|
+
return capMembersWithNotice(methods, MEMBER_LIMIT, 'methods');
|
|
8478
8528
|
}
|
|
8479
8529
|
|
|
8480
8530
|
function normalizeParams(params) {
|
|
@@ -8526,8 +8576,13 @@ __factories["./src/extractors/scala"] = function(module, exports) {
|
|
|
8526
8576
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
8527
8577
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
8528
8578
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
8529
|
-
|
|
8530
|
-
|
|
8579
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
8580
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
8581
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
8582
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
8583
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
8584
|
+
const MEMBER_LIMIT = 120;
|
|
8585
|
+
const PER_FILE_LIMIT = 200;
|
|
8531
8586
|
|
|
8532
8587
|
/**
|
|
8533
8588
|
* Extract signatures from Scala source code.
|
|
@@ -8574,7 +8629,7 @@ __factories["./src/extractors/scala"] = function(module, exports) {
|
|
|
8574
8629
|
|
|
8575
8630
|
function extractBlock(src, startIndex) {
|
|
8576
8631
|
let depth = 1, i = startIndex;
|
|
8577
|
-
const end = Math.min(src.length, startIndex +
|
|
8632
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
8578
8633
|
while (i < end && depth > 0) {
|
|
8579
8634
|
if (src[i] === '{') depth++;
|
|
8580
8635
|
else if (src[i] === '}') depth--;
|
|
@@ -8719,7 +8774,7 @@ __factories["./src/extractors/shell"] = function(module, exports) {
|
|
|
8719
8774
|
|
|
8720
8775
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
8721
8776
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
8722
|
-
const PER_FILE_LIMIT =
|
|
8777
|
+
const PER_FILE_LIMIT = 200;
|
|
8723
8778
|
|
|
8724
8779
|
/**
|
|
8725
8780
|
* Extract signatures from shell scripts (bash, zsh, fish).
|
|
@@ -8869,7 +8924,7 @@ __factories["./src/extractors/svelte"] = function(module, exports) {
|
|
|
8869
8924
|
|
|
8870
8925
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
8871
8926
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
8872
|
-
const PER_FILE_LIMIT =
|
|
8927
|
+
const PER_FILE_LIMIT = 200;
|
|
8873
8928
|
|
|
8874
8929
|
/**
|
|
8875
8930
|
* Extract signatures from Svelte components.
|
|
@@ -8939,8 +8994,13 @@ __factories["./src/extractors/swift"] = function(module, exports) {
|
|
|
8939
8994
|
// Ceilings sit above the default `maxSigsPerFile` so the configured budget
|
|
8940
8995
|
// governs output rather than a literal buried here, and omissions are disclosed
|
|
8941
8996
|
// — an undisclosed cap looks like a class that simply has eight methods (#576).
|
|
8942
|
-
|
|
8943
|
-
|
|
8997
|
+
// Class bodies are scanned to this many characters. Real classes routinely
|
|
8998
|
+
// run past the old 4KB scan window — truncating there silently hid every
|
|
8999
|
+
// member after ~4000 chars AND anchored class end-lines short (#576). The
|
|
9000
|
+
// ceiling only guards against pathological input (Java parity, #551).
|
|
9001
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
9002
|
+
const MEMBER_LIMIT = 120;
|
|
9003
|
+
const PER_FILE_LIMIT = 200;
|
|
8944
9004
|
|
|
8945
9005
|
/**
|
|
8946
9006
|
* Extract signatures from Swift source code.
|
|
@@ -8994,7 +9054,7 @@ __factories["./src/extractors/swift"] = function(module, exports) {
|
|
|
8994
9054
|
|
|
8995
9055
|
function extractBlock(src, startIndex) {
|
|
8996
9056
|
let depth = 1, i = startIndex;
|
|
8997
|
-
const end = Math.min(src.length, startIndex +
|
|
9057
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
8998
9058
|
while (i < end && depth > 0) {
|
|
8999
9059
|
if (src[i] === '{') depth++;
|
|
9000
9060
|
else if (src[i] === '}') depth--;
|
|
@@ -9153,7 +9213,7 @@ __factories["./src/extractors/toml"] = function(module, exports) {
|
|
|
9153
9213
|
const { capWithNotice } = __require('./src/util/truncate');
|
|
9154
9214
|
|
|
9155
9215
|
// Ceiling discloses what it drops rather than truncating silently (#583).
|
|
9156
|
-
const PER_FILE_LIMIT =
|
|
9216
|
+
const PER_FILE_LIMIT = 200;
|
|
9157
9217
|
|
|
9158
9218
|
/**
|
|
9159
9219
|
* Extract signatures from TOML configuration files.
|
|
@@ -9205,6 +9265,10 @@ __factories["./src/extractors/typescript"] = function(module, exports) {
|
|
|
9205
9265
|
const { capWithNotice, capMembersWithNotice } = __require('./src/util/truncate');
|
|
9206
9266
|
const { stripComments, maskCode, readBalanced } = __require('./src/extractors/scan');
|
|
9207
9267
|
|
|
9268
|
+
// Class bodies are scanned to this many characters — guard against
|
|
9269
|
+
// pathological input only; the old 4KB window silently hid members (#576).
|
|
9270
|
+
const MAX_CLASS_BODY_CHARS = 200000;
|
|
9271
|
+
|
|
9208
9272
|
/**
|
|
9209
9273
|
* Extract signatures from TypeScript source code.
|
|
9210
9274
|
* Top-level declarations carry a `:start-end` line anchor (see line-anchor.js);
|
|
@@ -9390,13 +9454,13 @@ __factories["./src/extractors/typescript"] = function(module, exports) {
|
|
|
9390
9454
|
const anchored = anchors[i] ? withAnchor(s, anchors[i][0], anchors[i][1]) : s;
|
|
9391
9455
|
return docHintFor[i] ? `${anchored} # ${docHintFor[i]}` : anchored;
|
|
9392
9456
|
});
|
|
9393
|
-
return capWithNotice(withAnchors,
|
|
9457
|
+
return capWithNotice(withAnchors, 200, 'signatures');
|
|
9394
9458
|
}
|
|
9395
9459
|
|
|
9396
9460
|
function extractBlock(src, startIndex) {
|
|
9397
9461
|
let depth = 1;
|
|
9398
9462
|
let i = startIndex;
|
|
9399
|
-
const end = Math.min(src.length, startIndex +
|
|
9463
|
+
const end = Math.min(src.length, startIndex + MAX_CLASS_BODY_CHARS);
|
|
9400
9464
|
while (i < end && depth > 0) {
|
|
9401
9465
|
if (src[i] === '{') depth++;
|
|
9402
9466
|
else if (src[i] === '}') depth--;
|
|
@@ -9424,7 +9488,7 @@ __factories["./src/extractors/typescript"] = function(module, exports) {
|
|
|
9424
9488
|
const start = m.index + (m[0].length - m[0].replace(/^\s+/, '').length);
|
|
9425
9489
|
members.push({ text: `${m[1]}(${normalizeParams(block.slice(openIdx + 1, closeIdx))})`, start, end: closeIdx + 1 });
|
|
9426
9490
|
}
|
|
9427
|
-
return capMembersWithNotice(members,
|
|
9491
|
+
return capMembersWithNotice(members, 120, 'members');
|
|
9428
9492
|
}
|
|
9429
9493
|
|
|
9430
9494
|
const _CTRL_KEYWORDS = new Set(['if', 'for', 'while', 'switch', 'do', 'try', 'catch', 'finally', 'else', 'return']);
|
|
@@ -9459,7 +9523,7 @@ __factories["./src/extractors/typescript"] = function(module, exports) {
|
|
|
9459
9523
|
const retStr = retType ? ` → ${retType}` : '';
|
|
9460
9524
|
members.push({ text: `${isStatic}${isAsync}${m[1]}(${normalizeParams(params)})${retStr}`, start, end });
|
|
9461
9525
|
}
|
|
9462
|
-
return capMembersWithNotice(members,
|
|
9526
|
+
return capMembersWithNotice(members, 120, 'methods');
|
|
9463
9527
|
}
|
|
9464
9528
|
|
|
9465
9529
|
function normalizeParams(params) {
|
|
@@ -9534,7 +9598,7 @@ __factories["./src/extractors/typescript_react"] = function(module, exports) {
|
|
|
9534
9598
|
const { capWithNotice } = __require('./src/util/truncate');
|
|
9535
9599
|
|
|
9536
9600
|
// Ceiling discloses what it drops rather than truncating silently (#583).
|
|
9537
|
-
const PER_FILE_LIMIT =
|
|
9601
|
+
const PER_FILE_LIMIT = 200;
|
|
9538
9602
|
|
|
9539
9603
|
/**
|
|
9540
9604
|
* Extract React component signatures from .tsx files.
|
|
@@ -9600,6 +9664,8 @@ __factories["./src/extractors/typescript_react"] = function(module, exports) {
|
|
|
9600
9664
|
// ── ./src/extractors/vue_sfc ──
|
|
9601
9665
|
__factories["./src/extractors/vue_sfc"] = function(module, exports) {
|
|
9602
9666
|
|
|
9667
|
+
const { capWithNotice } = __require('./src/util/truncate');
|
|
9668
|
+
|
|
9603
9669
|
/**
|
|
9604
9670
|
* Extract Vue Single-File Component (SFC) signatures from .vue files.
|
|
9605
9671
|
* Captures component metadata: name, props, emits, slots, composables, lifecycle.
|
|
@@ -9693,7 +9759,7 @@ __factories["./src/extractors/vue_sfc"] = function(module, exports) {
|
|
|
9693
9759
|
sigs.push(`slot ${s}`);
|
|
9694
9760
|
}
|
|
9695
9761
|
|
|
9696
|
-
return Array.from(new Set(sigs))
|
|
9762
|
+
return capWithNotice(Array.from(new Set(sigs)), 200, 'signatures');
|
|
9697
9763
|
}
|
|
9698
9764
|
|
|
9699
9765
|
module.exports = { extract };
|
|
@@ -9703,6 +9769,8 @@ __factories["./src/extractors/vue_sfc"] = function(module, exports) {
|
|
|
9703
9769
|
// ── ./src/extractors/xml ──
|
|
9704
9770
|
__factories["./src/extractors/xml"] = function(module, exports) {
|
|
9705
9771
|
|
|
9772
|
+
const { capWithNotice } = __require('./src/util/truncate');
|
|
9773
|
+
|
|
9706
9774
|
/**
|
|
9707
9775
|
* Lightweight XML config extractor.
|
|
9708
9776
|
* Captures root tags, key config tags, and id/name/class attributes.
|
|
@@ -9743,7 +9811,7 @@ __factories["./src/extractors/xml"] = function(module, exports) {
|
|
|
9743
9811
|
if (cls) sigs.push(`${tag} -> ${cls[1]}`);
|
|
9744
9812
|
}
|
|
9745
9813
|
|
|
9746
|
-
return Array.from(new Set(sigs))
|
|
9814
|
+
return capWithNotice(Array.from(new Set(sigs)), 200, 'signatures');
|
|
9747
9815
|
}
|
|
9748
9816
|
|
|
9749
9817
|
module.exports = { extract };
|
|
@@ -9757,7 +9825,7 @@ __factories["./src/extractors/yaml"] = function(module, exports) {
|
|
|
9757
9825
|
|
|
9758
9826
|
// Ceiling sits above the default `maxSigsPerFile` so the configured budget
|
|
9759
9827
|
// governs output rather than a literal buried here, and omissions are disclosed (#576).
|
|
9760
|
-
const PER_FILE_LIMIT =
|
|
9828
|
+
const PER_FILE_LIMIT = 200;
|
|
9761
9829
|
|
|
9762
9830
|
/**
|
|
9763
9831
|
* Extract signatures from YAML configuration files.
|
|
@@ -16065,8 +16133,8 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
16065
16133
|
* One JSON object per line on both stdin and stdout.
|
|
16066
16134
|
*
|
|
16067
16135
|
* Supported methods:
|
|
16068
|
-
* initialize → serverInfo + capabilities
|
|
16069
|
-
* tools/list →
|
|
16136
|
+
* initialize → serverInfo + capabilities + negotiated protocolVersion
|
|
16137
|
+
* tools/list → 21 tool definitions
|
|
16070
16138
|
* tools/call → dispatch to handler, return result
|
|
16071
16139
|
*/
|
|
16072
16140
|
|
|
@@ -16076,10 +16144,22 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
16076
16144
|
|
|
16077
16145
|
const SERVER_INFO = {
|
|
16078
16146
|
name: 'sigmap',
|
|
16079
|
-
version: '8.
|
|
16147
|
+
version: '8.35.0',
|
|
16080
16148
|
description: 'SigMap MCP server — code signatures on demand',
|
|
16081
16149
|
};
|
|
16082
16150
|
|
|
16151
|
+
// Protocol revisions this server actually speaks. The tools-only surface —
|
|
16152
|
+
// initialize / tools/list / tools/call plus the initialized/cancelled
|
|
16153
|
+
// notifications — is identical across these revisions, and the
|
|
16154
|
+
// @hasmcp/mcp-spec-test suite passes every applicable 2025-11-25 case against
|
|
16155
|
+
// it. 2026-07-28 is deliberately absent: that revision requires
|
|
16156
|
+
// server/discover, which is not implemented. Newest first: a client offering
|
|
16157
|
+
// a version outside this list is downgraded to [0], never echoed back —
|
|
16158
|
+
// echoing an unspeakable version is itself a spec violation (#544), and it
|
|
16159
|
+
// made the conformance suite believe 2026-07-28 was supported, producing six
|
|
16160
|
+
// phantom server/discover failures on a revision never really offered (#545).
|
|
16161
|
+
const SUPPORTED_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
16162
|
+
|
|
16083
16163
|
// ---------------------------------------------------------------------------
|
|
16084
16164
|
// JSON-RPC helpers
|
|
16085
16165
|
// ---------------------------------------------------------------------------
|
|
@@ -16104,9 +16184,32 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
16104
16184
|
return;
|
|
16105
16185
|
}
|
|
16106
16186
|
|
|
16187
|
+
// server/discover (spec 2026-07-28) — session-less discovery, answerable
|
|
16188
|
+
// before any handshake, so a client can learn the honest version list
|
|
16189
|
+
// instead of offering versions and hoping. The response is a
|
|
16190
|
+
// CacheableResult: deterministic, so the TTL promise of stability holds.
|
|
16191
|
+
// Note supportedVersions does NOT include 2026-07-28 — answering discover
|
|
16192
|
+
// is forward-compatible plumbing, not a claim to serve that revision's
|
|
16193
|
+
// whole surface (per-result envelopes, inline _meta negotiation).
|
|
16194
|
+
if (method === 'server/discover') {
|
|
16195
|
+
respond(id, {
|
|
16196
|
+
resultType: 'complete',
|
|
16197
|
+
cacheScope: 'public',
|
|
16198
|
+
ttlMs: 3600000,
|
|
16199
|
+
supportedVersions: SUPPORTED_PROTOCOL_VERSIONS,
|
|
16200
|
+
capabilities: { tools: {} },
|
|
16201
|
+
serverInfo: SERVER_INFO,
|
|
16202
|
+
instructions: 'SigMap serves code signatures for the working directory. Call query_context or search_signatures to rank and fetch signature blocks instead of reading whole files.',
|
|
16203
|
+
});
|
|
16204
|
+
return;
|
|
16205
|
+
}
|
|
16206
|
+
|
|
16107
16207
|
if (method === 'initialize') {
|
|
16208
|
+
const offered = params && params.protocolVersion;
|
|
16108
16209
|
respond(id, {
|
|
16109
|
-
protocolVersion: (
|
|
16210
|
+
protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(offered)
|
|
16211
|
+
? offered
|
|
16212
|
+
: SUPPORTED_PROTOCOL_VERSIONS[0],
|
|
16110
16213
|
serverInfo: SERVER_INFO,
|
|
16111
16214
|
capabilities: { tools: {} },
|
|
16112
16215
|
});
|
|
@@ -16114,6 +16217,13 @@ __factories["./src/mcp/server"] = function(module, exports) {
|
|
|
16114
16217
|
}
|
|
16115
16218
|
|
|
16116
16219
|
if (method === 'tools/list') {
|
|
16220
|
+
// No pagination: the full list fits one page, so any cursor a client
|
|
16221
|
+
// presents is one this server never issued — reject it (-32602, per the
|
|
16222
|
+
// spec's SHOULD) rather than silently restarting from page one.
|
|
16223
|
+
if (params && params.cursor !== undefined) {
|
|
16224
|
+
respondError(id, -32602, `Invalid cursor: ${String(params.cursor)}`);
|
|
16225
|
+
return;
|
|
16226
|
+
}
|
|
16117
16227
|
respond(id, { tools: TOOLS });
|
|
16118
16228
|
return;
|
|
16119
16229
|
}
|
|
@@ -17743,9 +17853,15 @@ __factories["./src/retrieval/ranker"] = function(module, exports) {
|
|
|
17743
17853
|
const hop1Files = new Set(); // normalised keys that received a hop1 boost
|
|
17744
17854
|
const hop1Seeds = []; // original (un-normalised) paths, for hop-2 lookup
|
|
17745
17855
|
|
|
17746
|
-
// Hop 1: direct neighbors of scored files
|
|
17747
|
-
|
|
17748
|
-
|
|
17856
|
+
// Hop 1: direct neighbors of scored files. Seeds snapshotted BEFORE the
|
|
17857
|
+
// loop (as the call-graph block below already does) so boosts never
|
|
17858
|
+
// cascade: a file whose only score is a hop-1 boost must not become a seed
|
|
17859
|
+
// itself mid-loop, or the effective seed set — and every boost total —
|
|
17860
|
+
// depends on index insertion order, which git history changes via the
|
|
17861
|
+
// recent-commits hoist. That made gate scores differ between a shallow CI
|
|
17862
|
+
// checkout and a developer clone of the same commit (#596).
|
|
17863
|
+
const hop1SeedEntries = scored.filter((e) => e.score > 0);
|
|
17864
|
+
for (const entry of hop1SeedEntries) {
|
|
17749
17865
|
const neighbors = _graphGet(graph.forward, path.resolve(cwd, entry.file)) || [];
|
|
17750
17866
|
for (const neighborAbs of neighbors) {
|
|
17751
17867
|
const nk = path.normalize(neighborAbs);
|
|
@@ -17760,7 +17876,10 @@ __factories["./src/retrieval/ranker"] = function(module, exports) {
|
|
|
17760
17876
|
}
|
|
17761
17877
|
}
|
|
17762
17878
|
|
|
17763
|
-
// Hop 2: neighbors of hop1 files (only if they didn't get a direct score)
|
|
17879
|
+
// Hop 2: neighbors of hop1 files (only if they didn't get a direct score).
|
|
17880
|
+
// Eligibility frozen after hop-1 for the same reason: a file whose first
|
|
17881
|
+
// score is a hop-2 boost must not become hop-2-eligible mid-loop (#596).
|
|
17882
|
+
const hop2Eligible = scored.map((e) => e.score > 0);
|
|
17764
17883
|
for (const hop1Key of hop1Seeds) {
|
|
17765
17884
|
if (_graphGet(keyToIdx, hop1Key) === undefined) continue; // skip files not in index
|
|
17766
17885
|
const neighbors = _graphGet(graph.forward, hop1Key) || [];
|
|
@@ -17769,7 +17888,7 @@ __factories["./src/retrieval/ranker"] = function(module, exports) {
|
|
|
17769
17888
|
if (_isHub(nk) || hubs.has(nk) || hubs.has(nk.toLowerCase())) continue;
|
|
17770
17889
|
if (hop1Files.has(nk)) continue; // skip already hop1-boosted
|
|
17771
17890
|
const idx = _graphGet(keyToIdx, nk);
|
|
17772
|
-
if (idx !== undefined &&
|
|
17891
|
+
if (idx !== undefined && hop2Eligible[idx]) {
|
|
17773
17892
|
// Only boost files that have some baseline score (not noise)
|
|
17774
17893
|
scored[idx].score += GRAPH_BOOST_AMOUNTS.hop2;
|
|
17775
17894
|
scored[idx].signals.graphBoost = (scored[idx].signals.graphBoost || 0) + GRAPH_BOOST_AMOUNTS.hop2;
|
|
@@ -22370,7 +22489,7 @@ function __tryGit(args, opts = {}) {
|
|
|
22370
22489
|
catch (_) { return ''; }
|
|
22371
22490
|
}
|
|
22372
22491
|
|
|
22373
|
-
const VERSION = '8.
|
|
22492
|
+
const VERSION = '8.35.0';
|
|
22374
22493
|
const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
|
|
22375
22494
|
|
|
22376
22495
|
function requireSourceOrBundled(key) {
|
|
@@ -22665,7 +22784,20 @@ function estimateTokens(str) {
|
|
|
22665
22784
|
}
|
|
22666
22785
|
|
|
22667
22786
|
function isTestFile(filePath) {
|
|
22668
|
-
|
|
22787
|
+
const p = filePath.replace(/\\/g, '/');
|
|
22788
|
+
// Filename conventions: foo.test.ts / foo.spec.js / foo_test.go / test_foo.py,
|
|
22789
|
+
// plus the PascalCase JVM/C#/Swift family (FooTest.java, FooTests.kt,
|
|
22790
|
+
// FooSpec.scala). The [a-z0-9] guard keeps `contest.java` and `Latest.java`
|
|
22791
|
+
// out; the suffix must be a real case boundary.
|
|
22792
|
+
if (/\.(test|spec)\.[a-z]+$/.test(p) || /_test\.[a-z]+$/.test(p)) return true;
|
|
22793
|
+
if (/(^|\/)test_[^/]+\.[a-z]+$/.test(p)) return true;
|
|
22794
|
+
if (/[a-z0-9](Test|Spec)s?\.(java|kt|kts|scala|groovy|cs|swift)$/.test(p)) return true;
|
|
22795
|
+
// Path-segment conventions (src/test/java/**, tests/, spec/, __tests__/, e2e/)
|
|
22796
|
+
// — the form the entire JVM world uses. Without this, "drop test files first"
|
|
22797
|
+
// ran INVERTED on JVM repos: spring-petclinic's budget kept all 17 src/test/
|
|
22798
|
+
// files while dropping the application entry point, the owner entities and
|
|
22799
|
+
// every owner template (#592).
|
|
22800
|
+
return /(^|\/)(test|tests|spec|specs|__tests__|e2e)(\/|$)/i.test(p);
|
|
22669
22801
|
}
|
|
22670
22802
|
|
|
22671
22803
|
function isConfigFile(filePath) {
|
|
@@ -22684,6 +22816,21 @@ function isMockFile(filePath) {
|
|
|
22684
22816
|
/mock\.(ts|js|tsx|jsx)$/.test(p);
|
|
22685
22817
|
}
|
|
22686
22818
|
|
|
22819
|
+
// The application entry point is the single most orientation-valuable file in
|
|
22820
|
+
// a repo, yet it is often tiny (a main class with 2-3 signatures), so the
|
|
22821
|
+
// fewest-sigs tie-break dropped it while keeping bulkier files: petclinic's
|
|
22822
|
+
// budget dropped PetClinicApplication.java and an agent asking for the startup
|
|
22823
|
+
// entry point could not reach it at all (#592). Deliberately narrow — bare
|
|
22824
|
+
// main/app/application names plus the Spring `*Application.java` and C#
|
|
22825
|
+
// `Program.cs` conventions. `index.*` is excluded: JS barrel files are hubs,
|
|
22826
|
+
// not entry points, and protecting every one would crowd out real code.
|
|
22827
|
+
function isEntryPointFile(filePath) {
|
|
22828
|
+
const base = path.basename(filePath.replace(/\\/g, '/'));
|
|
22829
|
+
return /^(main|app|application|__main__)\.[a-z]+$/i.test(base)
|
|
22830
|
+
|| /Application\.(java|kt|kts)$/.test(base)
|
|
22831
|
+
|| /^Program\.cs$/.test(base);
|
|
22832
|
+
}
|
|
22833
|
+
|
|
22687
22834
|
/**
|
|
22688
22835
|
* Compute the effective token budget based on repo size and config.
|
|
22689
22836
|
*
|
|
@@ -22803,6 +22950,7 @@ function applyTokenBudget(fileEntries, maxTokens) {
|
|
|
22803
22950
|
else if (isMockFile(e.filePath)) { priority = 9; dropReason = 'budget: mock file'; }
|
|
22804
22951
|
else if (isTestFile(e.filePath)) { priority = 8; dropReason = 'budget: test file'; }
|
|
22805
22952
|
else if (isConfigFile(e.filePath)) { priority = 6; dropReason = 'budget: config file'; }
|
|
22953
|
+
else if (isEntryPointFile(e.filePath)) { priority = 3; dropReason = 'budget: entry point'; }
|
|
22806
22954
|
else priority = 4;
|
|
22807
22955
|
const loc = e.content ? e.content.split('\n').length : 1;
|
|
22808
22956
|
const signalQuality = loc > 0 ? (e.sigs ? e.sigs.length : 0) / loc : 0;
|