nexus-agents 2.169.0 → 2.171.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.
Files changed (129) hide show
  1. package/dist/{child-mcp-config-FJRGAMUU.js → child-mcp-config-NW4JZFWC.js} +2 -2
  2. package/dist/{chunk-CHF63T3L.js → chunk-25CWEJ2M.js} +4 -4
  3. package/dist/{chunk-MCT7JJF6.js → chunk-4KVAHGMB.js} +2 -2
  4. package/dist/{chunk-NT3KCLT6.js → chunk-5UDKUPZB.js} +7 -7
  5. package/dist/{chunk-DSMSYENI.js → chunk-76Q63KJM.js} +2 -2
  6. package/dist/{chunk-TB26XNJH.js → chunk-7AJWIOMT.js} +2 -2
  7. package/dist/{chunk-ZXFIBDT3.js → chunk-AJIDYCQG.js} +3 -3
  8. package/dist/{chunk-HNNSCTOI.js → chunk-B4XT3B2E.js} +2 -2
  9. package/dist/{chunk-BWG54OJS.js → chunk-BTH745HU.js} +2 -2
  10. package/dist/{chunk-SX4E2W3Z.js → chunk-CEDSYAAI.js} +2 -2
  11. package/dist/{chunk-3ON2P4WL.js → chunk-DLVDFJXU.js} +4 -4
  12. package/dist/{chunk-7S43YASS.js → chunk-DYFF72HX.js} +3 -3
  13. package/dist/{chunk-ROCNXZBC.js → chunk-E53VLN73.js} +8 -8
  14. package/dist/{chunk-5O4JRXNQ.js → chunk-FU2FRL46.js} +2 -2
  15. package/dist/{chunk-4G5W5EPU.js → chunk-GJRLIANS.js} +7 -7
  16. package/dist/{chunk-OOFPDA3B.js → chunk-IC3NZHPT.js} +2 -2
  17. package/dist/{chunk-PZF67XDY.js → chunk-IK7POCXO.js} +3 -3
  18. package/dist/{chunk-IQC2K3KY.js → chunk-KP4ZXW3B.js} +3 -3
  19. package/dist/{chunk-Q3UMNYV2.js → chunk-LFKCJQ7G.js} +4 -4
  20. package/dist/{chunk-W76DOL27.js → chunk-O4J34GZT.js} +2 -2
  21. package/dist/{chunk-WB33EPTV.js → chunk-PP5QL4EJ.js} +5 -5
  22. package/dist/{chunk-QXSR5KPG.js → chunk-QBCWORAK.js} +3 -3
  23. package/dist/{chunk-XGNB7LQB.js → chunk-QBOTSJ7S.js} +235 -20
  24. package/dist/chunk-QBOTSJ7S.js.map +1 -0
  25. package/dist/{chunk-JCJHQSAY.js → chunk-QFS5VOB6.js} +2 -2
  26. package/dist/{chunk-RO23OT47.js → chunk-RAK6PTNM.js} +2 -2
  27. package/dist/{chunk-R46SBPLH.js → chunk-RQGORCFM.js} +5 -5
  28. package/dist/{chunk-CD2NZFAI.js → chunk-S66XOAMZ.js} +2 -2
  29. package/dist/{chunk-EQRN5FRZ.js → chunk-SCHMBRK4.js} +3 -3
  30. package/dist/{chunk-T3VD32JY.js → chunk-SUWN54CK.js} +2 -2
  31. package/dist/{chunk-F6HJJG3E.js → chunk-SZ3CRNPI.js} +8 -8
  32. package/dist/{chunk-3JH3FMEJ.js → chunk-Y7JDXVJA.js} +2 -2
  33. package/dist/{chunk-N7FIUFQL.js → chunk-YIQ5Z7LV.js} +44 -118
  34. package/dist/chunk-YIQ5Z7LV.js.map +1 -0
  35. package/dist/{chunk-P7MYTCE6.js → chunk-Z5GJ4FXW.js} +4 -4
  36. package/dist/{chunk-HAVBBSYN.js → chunk-ZSWXEDI6.js} +2 -2
  37. package/dist/{cli-circuit-breaker-FJQXDC5M.js → cli-circuit-breaker-UWJNXHLC.js} +4 -4
  38. package/dist/cli.js +40 -40
  39. package/dist/{composite-router-UQTCPADM.js → composite-router-ULDZRQGO.js} +2 -2
  40. package/dist/{consensus-vote-FEDF24T5.js → consensus-vote-KF6M7NZJ.js} +15 -15
  41. package/dist/{context-retriever-TIJGFLGO.js → context-retriever-73PNAWES.js} +8 -8
  42. package/dist/{doctor-deep-EULAHWTK.js → doctor-deep-LURSTTF7.js} +3 -3
  43. package/dist/{expert-bridge-7HQ54XYU.js → expert-bridge-VWS3NBL3.js} +4 -4
  44. package/dist/{factory-RW2ROEDS.js → factory-KPJ2EG63.js} +5 -5
  45. package/dist/{factory-QZZQVDGQ.js → factory-MYJYONBQ.js} +8 -8
  46. package/dist/{improvement-review-DGQPADKS.js → improvement-review-APOK4U3Z.js} +5 -5
  47. package/dist/index.d.ts +151 -1
  48. package/dist/index.js +389 -155
  49. package/dist/index.js.map +1 -1
  50. package/dist/{init-opencode-MK2NUEWH.js → init-opencode-Y7WPFCY7.js} +5 -5
  51. package/dist/{issue-triage-RVDZEM53.js → issue-triage-4P3TDIJQ.js} +6 -6
  52. package/dist/{pr-reviewer-helpers-TKXJBDT6.js → pr-reviewer-helpers-4JX2LEVZ.js} +4 -4
  53. package/dist/{registry-command-VXXKVZ3H.js → registry-command-CTYTYRXF.js} +2 -2
  54. package/dist/{repo-security-plan-YCTKRAGA.js → repo-security-plan-4CXBXLAY.js} +3 -3
  55. package/dist/{research-helpers-synthesize-4L6SXYQU.js → research-helpers-synthesize-23OXMV47.js} +4 -4
  56. package/dist/{routing-memory-INY5DC2P.js → routing-memory-AWCOIW27.js} +2 -2
  57. package/dist/security/ast-rules/command-exec-go.yml +15 -0
  58. package/dist/security/ast-rules/dangerous-eval-python.yml +8 -0
  59. package/dist/security/ast-rules/shell-injection-python.yml +13 -0
  60. package/dist/{session-memory-TQMLN67N.js → session-memory-P53QXKGV.js} +3 -3
  61. package/dist/{setup-command-FT5LBTSR.js → setup-command-IRW76CNQ.js} +13 -13
  62. package/dist/{setup-config-U3WLC5OO.js → setup-config-B7WLUMUU.js} +3 -3
  63. package/dist/{setup-custom-api-2E4MZ5MF.js → setup-custom-api-B6QGKSEY.js} +3 -3
  64. package/dist/{tool-memory-IV5BVIV4.js → tool-memory-QUFVINHN.js} +5 -5
  65. package/dist/{unified-registry-6LFTI4MG.js → unified-registry-4NOWT2MU.js} +9 -9
  66. package/dist/{weather-report-7NZ6D4C7.js → weather-report-MCLS5MFZ.js} +2 -2
  67. package/package.json +4 -1
  68. package/src/security/ast-rules/command-exec-go.yml +15 -0
  69. package/src/security/ast-rules/dangerous-eval-python.yml +8 -0
  70. package/src/security/ast-rules/fixtures/sample.go +33 -0
  71. package/src/security/ast-rules/fixtures/sample.py +41 -0
  72. package/src/security/ast-rules/shell-injection-python.yml +13 -0
  73. package/dist/chunk-N7FIUFQL.js.map +0 -1
  74. package/dist/chunk-XGNB7LQB.js.map +0 -1
  75. /package/dist/{child-mcp-config-FJRGAMUU.js.map → child-mcp-config-NW4JZFWC.js.map} +0 -0
  76. /package/dist/{chunk-CHF63T3L.js.map → chunk-25CWEJ2M.js.map} +0 -0
  77. /package/dist/{chunk-MCT7JJF6.js.map → chunk-4KVAHGMB.js.map} +0 -0
  78. /package/dist/{chunk-NT3KCLT6.js.map → chunk-5UDKUPZB.js.map} +0 -0
  79. /package/dist/{chunk-DSMSYENI.js.map → chunk-76Q63KJM.js.map} +0 -0
  80. /package/dist/{chunk-TB26XNJH.js.map → chunk-7AJWIOMT.js.map} +0 -0
  81. /package/dist/{chunk-ZXFIBDT3.js.map → chunk-AJIDYCQG.js.map} +0 -0
  82. /package/dist/{chunk-HNNSCTOI.js.map → chunk-B4XT3B2E.js.map} +0 -0
  83. /package/dist/{chunk-BWG54OJS.js.map → chunk-BTH745HU.js.map} +0 -0
  84. /package/dist/{chunk-SX4E2W3Z.js.map → chunk-CEDSYAAI.js.map} +0 -0
  85. /package/dist/{chunk-3ON2P4WL.js.map → chunk-DLVDFJXU.js.map} +0 -0
  86. /package/dist/{chunk-7S43YASS.js.map → chunk-DYFF72HX.js.map} +0 -0
  87. /package/dist/{chunk-ROCNXZBC.js.map → chunk-E53VLN73.js.map} +0 -0
  88. /package/dist/{chunk-5O4JRXNQ.js.map → chunk-FU2FRL46.js.map} +0 -0
  89. /package/dist/{chunk-4G5W5EPU.js.map → chunk-GJRLIANS.js.map} +0 -0
  90. /package/dist/{chunk-OOFPDA3B.js.map → chunk-IC3NZHPT.js.map} +0 -0
  91. /package/dist/{chunk-PZF67XDY.js.map → chunk-IK7POCXO.js.map} +0 -0
  92. /package/dist/{chunk-IQC2K3KY.js.map → chunk-KP4ZXW3B.js.map} +0 -0
  93. /package/dist/{chunk-Q3UMNYV2.js.map → chunk-LFKCJQ7G.js.map} +0 -0
  94. /package/dist/{chunk-W76DOL27.js.map → chunk-O4J34GZT.js.map} +0 -0
  95. /package/dist/{chunk-WB33EPTV.js.map → chunk-PP5QL4EJ.js.map} +0 -0
  96. /package/dist/{chunk-QXSR5KPG.js.map → chunk-QBCWORAK.js.map} +0 -0
  97. /package/dist/{chunk-JCJHQSAY.js.map → chunk-QFS5VOB6.js.map} +0 -0
  98. /package/dist/{chunk-RO23OT47.js.map → chunk-RAK6PTNM.js.map} +0 -0
  99. /package/dist/{chunk-R46SBPLH.js.map → chunk-RQGORCFM.js.map} +0 -0
  100. /package/dist/{chunk-CD2NZFAI.js.map → chunk-S66XOAMZ.js.map} +0 -0
  101. /package/dist/{chunk-EQRN5FRZ.js.map → chunk-SCHMBRK4.js.map} +0 -0
  102. /package/dist/{chunk-T3VD32JY.js.map → chunk-SUWN54CK.js.map} +0 -0
  103. /package/dist/{chunk-F6HJJG3E.js.map → chunk-SZ3CRNPI.js.map} +0 -0
  104. /package/dist/{chunk-3JH3FMEJ.js.map → chunk-Y7JDXVJA.js.map} +0 -0
  105. /package/dist/{chunk-P7MYTCE6.js.map → chunk-Z5GJ4FXW.js.map} +0 -0
  106. /package/dist/{chunk-HAVBBSYN.js.map → chunk-ZSWXEDI6.js.map} +0 -0
  107. /package/dist/{cli-circuit-breaker-FJQXDC5M.js.map → cli-circuit-breaker-UWJNXHLC.js.map} +0 -0
  108. /package/dist/{composite-router-UQTCPADM.js.map → composite-router-ULDZRQGO.js.map} +0 -0
  109. /package/dist/{consensus-vote-FEDF24T5.js.map → consensus-vote-KF6M7NZJ.js.map} +0 -0
  110. /package/dist/{context-retriever-TIJGFLGO.js.map → context-retriever-73PNAWES.js.map} +0 -0
  111. /package/dist/{doctor-deep-EULAHWTK.js.map → doctor-deep-LURSTTF7.js.map} +0 -0
  112. /package/dist/{expert-bridge-7HQ54XYU.js.map → expert-bridge-VWS3NBL3.js.map} +0 -0
  113. /package/dist/{factory-QZZQVDGQ.js.map → factory-KPJ2EG63.js.map} +0 -0
  114. /package/dist/{factory-RW2ROEDS.js.map → factory-MYJYONBQ.js.map} +0 -0
  115. /package/dist/{improvement-review-DGQPADKS.js.map → improvement-review-APOK4U3Z.js.map} +0 -0
  116. /package/dist/{init-opencode-MK2NUEWH.js.map → init-opencode-Y7WPFCY7.js.map} +0 -0
  117. /package/dist/{issue-triage-RVDZEM53.js.map → issue-triage-4P3TDIJQ.js.map} +0 -0
  118. /package/dist/{pr-reviewer-helpers-TKXJBDT6.js.map → pr-reviewer-helpers-4JX2LEVZ.js.map} +0 -0
  119. /package/dist/{registry-command-VXXKVZ3H.js.map → registry-command-CTYTYRXF.js.map} +0 -0
  120. /package/dist/{repo-security-plan-YCTKRAGA.js.map → repo-security-plan-4CXBXLAY.js.map} +0 -0
  121. /package/dist/{research-helpers-synthesize-4L6SXYQU.js.map → research-helpers-synthesize-23OXMV47.js.map} +0 -0
  122. /package/dist/{routing-memory-INY5DC2P.js.map → routing-memory-AWCOIW27.js.map} +0 -0
  123. /package/dist/{session-memory-TQMLN67N.js.map → session-memory-P53QXKGV.js.map} +0 -0
  124. /package/dist/{setup-command-FT5LBTSR.js.map → setup-command-IRW76CNQ.js.map} +0 -0
  125. /package/dist/{setup-config-U3WLC5OO.js.map → setup-config-B7WLUMUU.js.map} +0 -0
  126. /package/dist/{setup-custom-api-2E4MZ5MF.js.map → setup-custom-api-B6QGKSEY.js.map} +0 -0
  127. /package/dist/{tool-memory-IV5BVIV4.js.map → tool-memory-QUFVINHN.js.map} +0 -0
  128. /package/dist/{unified-registry-6LFTI4MG.js.map → unified-registry-4NOWT2MU.js.map} +0 -0
  129. /package/dist/{weather-report-7NZ6D4C7.js.map → weather-report-MCLS5MFZ.js.map} +0 -0
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  resolveToken
3
- } from "./chunk-3JH3FMEJ.js";
3
+ } from "./chunk-Y7JDXVJA.js";
4
4
  import {
5
5
  REGISTRY_PATH,
6
6
  getProjectRoot,
7
7
  loadPapersRegistry,
8
8
  loadTechniquesRegistry,
9
9
  savePapersRegistry
10
- } from "./chunk-HAVBBSYN.js";
10
+ } from "./chunk-ZSWXEDI6.js";
11
11
  import {
12
12
  resolveInsideRoot
13
13
  } from "./chunk-NUBSJGQZ.js";
14
14
  import {
15
15
  getToolMemory
16
- } from "./chunk-Q3UMNYV2.js";
16
+ } from "./chunk-LFKCJQ7G.js";
17
17
  import {
18
18
  capitalizeWords,
19
19
  truncateSentence
@@ -38,7 +38,7 @@ import {
38
38
  getTimeProvider,
39
39
  ok,
40
40
  registerPersistentDistillerFactory
41
- } from "./chunk-QXSR5KPG.js";
41
+ } from "./chunk-QBCWORAK.js";
42
42
  import {
43
43
  ensureLearningDir,
44
44
  getRulesFile
@@ -3337,11 +3337,195 @@ function buildIndex(files) {
3337
3337
  };
3338
3338
  }
3339
3339
 
3340
+ // src/context/repo-map-callsites.ts
3341
+ import { readFileSync as readFileSync3 } from "fs";
3342
+ import { resolve as resolve4 } from "path";
3343
+
3344
+ // src/indexer/usage-ast.ts
3345
+ import { extname } from "path";
3346
+ import { Lang, parse as parse2 } from "@ast-grep/napi";
3347
+ var LANG_VALUES = ["typescript", "tsx", "javascript"];
3348
+ var MAX_SNIPPET_CHARS = 200;
3349
+ var IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
3350
+ var CALL_USAGE_KINDS = /* @__PURE__ */ new Set(["call", "method-call", "new"]);
3351
+ var DECLARATION_PARENT_KINDS = /* @__PURE__ */ new Set([
3352
+ "function_declaration",
3353
+ "generator_function_declaration",
3354
+ "class_declaration",
3355
+ "interface_declaration",
3356
+ "type_alias_declaration",
3357
+ "enum_declaration",
3358
+ "function_signature",
3359
+ "method_definition",
3360
+ "abstract_method_signature"
3361
+ ]);
3362
+ var IMPORT_PARENT_KINDS = /* @__PURE__ */ new Set([
3363
+ "import_specifier",
3364
+ "namespace_import",
3365
+ "import_clause"
3366
+ ]);
3367
+ function langToNapi(lang) {
3368
+ if (lang === "tsx") return Lang.Tsx;
3369
+ if (lang === "javascript") return Lang.JavaScript;
3370
+ return Lang.TypeScript;
3371
+ }
3372
+ function inferLang(file) {
3373
+ const ext = extname(file).toLowerCase();
3374
+ if (ext === ".tsx" || ext === ".jsx") return "tsx";
3375
+ if (ext === ".js" || ext === ".mjs" || ext === ".cjs") return "javascript";
3376
+ return "typescript";
3377
+ }
3378
+ function escapeRegex(value) {
3379
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3380
+ }
3381
+ function isDeclaredName(declarator, node) {
3382
+ const name = declarator.field("name");
3383
+ return name !== null && name.id() === node.id();
3384
+ }
3385
+ function classifyIdentifier(node) {
3386
+ const parent = node.parent();
3387
+ if (parent === null) return "reference";
3388
+ const pk = String(parent.kind());
3389
+ if (DECLARATION_PARENT_KINDS.has(pk)) return null;
3390
+ if (pk === "variable_declarator") return isDeclaredName(parent, node) ? null : "reference";
3391
+ if (IMPORT_PARENT_KINDS.has(pk)) return "import";
3392
+ if (pk === "call_expression") return "call";
3393
+ if (pk === "new_expression") return "new";
3394
+ return "reference";
3395
+ }
3396
+ function classifyProperty(node) {
3397
+ const member = node.parent();
3398
+ const grandparent = member === null ? null : member.parent();
3399
+ if (grandparent !== null && String(grandparent.kind()) === "call_expression")
3400
+ return "method-call";
3401
+ return "reference";
3402
+ }
3403
+ function toMatch(node, kind, lines) {
3404
+ const { start } = node.range();
3405
+ const rawLine = lines[start.line] ?? node.text();
3406
+ return {
3407
+ line: start.line + 1,
3408
+ column: start.column + 1,
3409
+ kind,
3410
+ snippet: rawLine.trim().slice(0, MAX_SNIPPET_CHARS)
3411
+ };
3412
+ }
3413
+ function findUsagesInSource(symbol, src, lang) {
3414
+ if (!IDENTIFIER_RE.test(symbol)) return [];
3415
+ const root = parse2(langToNapi(lang), src).root();
3416
+ const lines = src.split("\n");
3417
+ const out = [];
3418
+ for (const node of root.findAll(symbol)) {
3419
+ const kind = classifyIdentifier(node);
3420
+ if (kind !== null) out.push(toMatch(node, kind, lines));
3421
+ }
3422
+ const propRule = {
3423
+ rule: { kind: "property_identifier", regex: `^${escapeRegex(symbol)}$` }
3424
+ };
3425
+ for (const node of root.findAll(propRule)) {
3426
+ out.push(toMatch(node, classifyProperty(node), lines));
3427
+ }
3428
+ return out.sort((a, b) => a.line - b.line || a.column - b.column);
3429
+ }
3430
+ function bump(counts, symbols, name) {
3431
+ if (symbols.has(name)) counts.set(name, (counts.get(name) ?? 0) + 1);
3432
+ }
3433
+ function tallyIdentifierCalls(root, symbols, counts) {
3434
+ for (const node of root.findAll({ rule: { kind: "identifier" } })) {
3435
+ const kind = classifyIdentifier(node);
3436
+ if (kind !== null && CALL_USAGE_KINDS.has(kind)) bump(counts, symbols, node.text());
3437
+ }
3438
+ }
3439
+ function tallyPropertyCalls(root, symbols, counts) {
3440
+ for (const node of root.findAll({ rule: { kind: "property_identifier" } })) {
3441
+ if (CALL_USAGE_KINDS.has(classifyProperty(node))) bump(counts, symbols, node.text());
3442
+ }
3443
+ }
3444
+ function countCallSitesInSource(symbols, src, lang) {
3445
+ const counts = /* @__PURE__ */ new Map();
3446
+ if (symbols.size === 0) return counts;
3447
+ const root = parse2(langToNapi(lang), src).root();
3448
+ tallyIdentifierCalls(root, symbols, counts);
3449
+ tallyPropertyCalls(root, symbols, counts);
3450
+ return counts;
3451
+ }
3452
+
3453
+ // src/context/repo-map-callsites.ts
3454
+ var CALLSITE_TOP_N_MODULES = 25;
3455
+ var MAX_PROBE_SYMBOLS = 60;
3456
+ var MAX_CALLSITE_FILES = 4e3;
3457
+ function defaultSourceRoot() {
3458
+ return resolve4(process.cwd(), "src");
3459
+ }
3460
+ function addModuleExports(mod, name, owner) {
3461
+ for (const file of mod.files) {
3462
+ for (const exp of file.exports) {
3463
+ if (exp.isReExport) continue;
3464
+ if (!owner.has(exp.name)) owner.set(exp.name, name);
3465
+ if (owner.size >= MAX_PROBE_SYMBOLS) return;
3466
+ }
3467
+ }
3468
+ }
3469
+ function buildProbeSet(index, topModuleNames) {
3470
+ const owner = /* @__PURE__ */ new Map();
3471
+ for (const name of topModuleNames) {
3472
+ const mod = index.modules[name];
3473
+ if (mod === void 0) continue;
3474
+ addModuleExports(mod, name, owner);
3475
+ if (owner.size >= MAX_PROBE_SYMBOLS) break;
3476
+ }
3477
+ return { symbols: new Set(owner.keys()), owner };
3478
+ }
3479
+ function collectFiles(index, sourceRoot, maxFiles) {
3480
+ const refs = [];
3481
+ const seen = /* @__PURE__ */ new Set();
3482
+ for (const mod of Object.values(index.modules)) {
3483
+ for (const file of mod.files) {
3484
+ if (seen.has(file.path)) continue;
3485
+ seen.add(file.path);
3486
+ refs.push({ abs: resolve4(sourceRoot, file.path), rel: file.path });
3487
+ if (refs.length >= maxFiles) return refs;
3488
+ }
3489
+ }
3490
+ return refs;
3491
+ }
3492
+ function tallyFile(probe, ref, counts, log) {
3493
+ let src;
3494
+ try {
3495
+ src = readFileSync3(ref.abs, "utf8");
3496
+ } catch {
3497
+ log.debug("repo-map call-site: unreadable file", { file: ref.rel });
3498
+ return;
3499
+ }
3500
+ for (const [sym, n] of countCallSitesInSource(probe.symbols, src, inferLang(ref.rel))) {
3501
+ const owner = probe.owner.get(sym);
3502
+ if (owner !== void 0) counts.set(owner, (counts.get(owner) ?? 0) + n);
3503
+ }
3504
+ }
3505
+ function computeCallSiteCounts(index, topModuleNames, options = {}) {
3506
+ const log = options.logger ?? createLogger({ component: "RepoMapCallSites" });
3507
+ const counts = /* @__PURE__ */ new Map();
3508
+ try {
3509
+ const probe = buildProbeSet(index, topModuleNames);
3510
+ if (probe.symbols.size === 0) return counts;
3511
+ const sourceRoot = options.sourceRoot ?? defaultSourceRoot();
3512
+ const maxFiles = options.maxFiles ?? MAX_CALLSITE_FILES;
3513
+ for (const ref of collectFiles(index, sourceRoot, maxFiles)) {
3514
+ tallyFile(probe, ref, counts, log);
3515
+ }
3516
+ } catch (error) {
3517
+ log.debug("repo-map call-site counting failed", {
3518
+ error: error instanceof Error ? error.message : String(error)
3519
+ });
3520
+ }
3521
+ return counts;
3522
+ }
3523
+
3340
3524
  // src/context/repo-map.ts
3341
3525
  var REPO_MAP_FLAG = "NEXUS_REPO_MAP";
3342
3526
  var DEFAULT_REPO_MAP_TOKEN_BUDGET = 400;
3343
- var REPO_MAP_CAVEAT = "Import-graph only: edges are module import dependencies + declaration names, NOT call-site/usage data. Centrality reflects import structure, not runtime call frequency \u2014 do not treat this as a call graph (call-site edges tracked in #4249-A).";
3344
- var REPO_MAP_HEADER = "## Repo Map (module import graph \u2014 PageRank-ranked)";
3527
+ var REPO_MAP_CAVEAT = "Ranking blends import-graph PageRank with structural call-site frequency (ast-grep, sampled over the top import-ranked modules). Call-site matching is syntactic, not type-aware: dynamic dispatch, computed/string-keyed calls, and same-named members on unrelated objects are not resolved \u2014 treat centrality as an approximate structural+usage signal, not an exact call graph.";
3528
+ var REPO_MAP_HEADER = "## Repo Map (module import graph + call-site usage \u2014 ranked)";
3345
3529
  var PAGERANK_DAMPING = 0.85;
3346
3530
  var PAGERANK_MAX_ITERATIONS = 100;
3347
3531
  var PAGERANK_EPSILON = 1e-6;
@@ -3396,24 +3580,43 @@ function l1Delta(a, b) {
3396
3580
  for (const [k, v] of a) d += Math.abs(v - (b.get(k) ?? 0));
3397
3581
  return d;
3398
3582
  }
3399
- function rankRepoMapEntries(index) {
3583
+ var CALL_SITE_WEIGHT = 2;
3584
+ function blendRankScore(centrality, callSites, maxCallSites) {
3585
+ if (maxCallSites <= 0) return centrality;
3586
+ return centrality * (1 + CALL_SITE_WEIGHT * (callSites / maxCallSites));
3587
+ }
3588
+ function maxCount(counts) {
3589
+ let max = 0;
3590
+ for (const v of counts.values()) if (v > max) max = v;
3591
+ return max;
3592
+ }
3593
+ function rankRepoMapEntries(index, callSiteCounts) {
3400
3594
  const ranks = computeModulePageRank(index.modules);
3401
- const entries = Object.entries(index.modules).map(([name, mod]) => ({
3402
- module: name,
3403
- centrality: ranks.get(name) ?? 0,
3404
- purpose: mod.purpose,
3405
- dependsOn: mod.dependsOn,
3406
- fileCount: mod.stats.fileCount
3407
- }));
3408
- return entries.sort(
3409
- (a, b) => b.centrality !== a.centrality ? b.centrality - a.centrality : a.module.localeCompare(b.module)
3595
+ const counts = callSiteCounts ?? /* @__PURE__ */ new Map();
3596
+ const max = maxCount(counts);
3597
+ const scored = Object.entries(index.modules).map(([name, mod]) => {
3598
+ const centrality = ranks.get(name) ?? 0;
3599
+ const callSites = counts.get(name) ?? 0;
3600
+ const entry = {
3601
+ module: name,
3602
+ centrality,
3603
+ callSites,
3604
+ purpose: mod.purpose,
3605
+ dependsOn: mod.dependsOn,
3606
+ fileCount: mod.stats.fileCount
3607
+ };
3608
+ return { entry, score: blendRankScore(centrality, callSites, max) };
3609
+ });
3610
+ scored.sort(
3611
+ (a, b) => b.score !== a.score ? b.score - a.score : a.entry.module.localeCompare(b.entry.module)
3410
3612
  );
3613
+ return scored.map((s) => s.entry);
3411
3614
  }
3412
3615
  var CHARS_PER_TOKEN3 = 4;
3413
3616
  var MAX_DEPS_PER_LINE = 6;
3414
3617
  var MAX_LINE_CHARS = 200;
3415
3618
  function buildRepoMap(index, options = {}) {
3416
- const entries = rankRepoMapEntries(index);
3619
+ const entries = rankRepoMapEntries(index, options.callSiteCounts);
3417
3620
  if (entries.length === 0) return "";
3418
3621
  const budget = options.budgetTokens ?? DEFAULT_REPO_MAP_TOKEN_BUDGET;
3419
3622
  return renderRepoMap(entries, budget);
@@ -3434,7 +3637,8 @@ function formatEntryLine(e) {
3434
3637
  const shownDeps = e.dependsOn.slice(0, MAX_DEPS_PER_LINE);
3435
3638
  const more = e.dependsOn.length > MAX_DEPS_PER_LINE ? ", \u2026" : "";
3436
3639
  const deps = shownDeps.length > 0 ? ` \u2192 ${shownDeps.join(", ")}${more}` : "";
3437
- const line = `- ${e.module} (centrality ${e.centrality.toFixed(3)}, ${String(e.fileCount)} files): ${oneLine2(e.purpose)}${deps}`;
3640
+ const calls = e.callSites > 0 ? `, ${String(e.callSites)} call-sites` : "";
3641
+ const line = `- ${e.module} (centrality ${e.centrality.toFixed(3)}${calls}, ${String(e.fileCount)} files): ${oneLine2(e.purpose)}${deps}`;
3438
3642
  return line.slice(0, MAX_LINE_CHARS);
3439
3643
  }
3440
3644
  function fitLinesWithinBudget(lines, budgetTokens) {
@@ -3472,8 +3676,10 @@ function getRepoMapForTask(options) {
3472
3676
  const log = options.logger ?? createLogger({ component: "RepoMap" });
3473
3677
  try {
3474
3678
  const index = (options.indexProvider ?? buildLiveIndex)();
3679
+ const callSiteCounts = options.callSiteCounts ?? liveCallSiteCounts(index, log);
3475
3680
  const map = buildRepoMap(index, {
3476
- budgetTokens: options.budgetTokens ?? DEFAULT_REPO_MAP_TOKEN_BUDGET
3681
+ budgetTokens: options.budgetTokens ?? DEFAULT_REPO_MAP_TOKEN_BUDGET,
3682
+ callSiteCounts
3477
3683
  });
3478
3684
  return map === "" ? void 0 : map;
3479
3685
  } catch (error) {
@@ -3483,6 +3689,10 @@ function getRepoMapForTask(options) {
3483
3689
  return void 0;
3484
3690
  }
3485
3691
  }
3692
+ function liveCallSiteCounts(index, log) {
3693
+ const topModules = rankRepoMapEntries(index).slice(0, CALLSITE_TOP_N_MODULES).map((e) => e.module);
3694
+ return computeCallSiteCounts(index, topModules, { logger: log });
3695
+ }
3486
3696
  function buildLiveIndex() {
3487
3697
  const extraction = extractProject({ extractDescriptions: false });
3488
3698
  return buildIndex(extraction.files);
@@ -3811,6 +4021,11 @@ export {
3811
4021
  CodebaseIndexSchema,
3812
4022
  extractProject,
3813
4023
  buildIndex,
4024
+ LANG_VALUES,
4025
+ IDENTIFIER_RE,
4026
+ langToNapi,
4027
+ inferLang,
4028
+ findUsagesInSource,
3814
4029
  getContextForTask,
3815
4030
  selectRelevantResearch,
3816
4031
  getResearchInsightsForTask,
@@ -3819,4 +4034,4 @@ export {
3819
4034
  DEFAULT_CONTEXT_BUDGET_TOKENS,
3820
4035
  getContextPromptPrefix
3821
4036
  };
3822
- //# sourceMappingURL=chunk-XGNB7LQB.js.map
4037
+ //# sourceMappingURL=chunk-QBOTSJ7S.js.map