@securecode-ai/mcp 0.5.5 → 0.5.6

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 (185) hide show
  1. package/dist/api/types.d.ts +7 -0
  2. package/dist/approval/auditLog.d.ts +1 -1
  3. package/dist/approval/auditLog.js +11 -3
  4. package/dist/approval/auditLog.js.map +1 -1
  5. package/dist/approval/broker.d.ts +7 -2
  6. package/dist/approval/broker.js +239 -110
  7. package/dist/approval/broker.js.map +1 -1
  8. package/dist/approval/policy.d.ts +10 -0
  9. package/dist/approval/policy.js +104 -0
  10. package/dist/approval/policy.js.map +1 -0
  11. package/dist/approval/types.d.ts +11 -2
  12. package/dist/approval/types.js +10 -1
  13. package/dist/approval/types.js.map +1 -1
  14. package/dist/attack/agentScanExecutor.d.ts +35 -1
  15. package/dist/attack/agentScanExecutor.js +405 -76
  16. package/dist/attack/agentScanExecutor.js.map +1 -1
  17. package/dist/attack/agentScanLoop.d.ts +20 -0
  18. package/dist/attack/agentScanLoop.js +1264 -60
  19. package/dist/attack/agentScanLoop.js.map +1 -1
  20. package/dist/attack/agentScanProtocol.d.ts +382 -6
  21. package/dist/attack/agentScanProtocol.js +110 -4
  22. package/dist/attack/agentScanProtocol.js.map +1 -1
  23. package/dist/attack/agentTrace.d.ts +73 -0
  24. package/dist/attack/agentTrace.js +228 -0
  25. package/dist/attack/agentTrace.js.map +1 -0
  26. package/dist/attack/architectureScoutExecutor.d.ts +18 -0
  27. package/dist/attack/architectureScoutExecutor.js +211 -0
  28. package/dist/attack/architectureScoutExecutor.js.map +1 -0
  29. package/dist/attack/architectureScoutLoop.d.ts +36 -0
  30. package/dist/attack/architectureScoutLoop.js +403 -0
  31. package/dist/attack/architectureScoutLoop.js.map +1 -0
  32. package/dist/attack/architectureScoutProtocol.d.ts +209 -0
  33. package/dist/attack/architectureScoutProtocol.js +47 -0
  34. package/dist/attack/architectureScoutProtocol.js.map +1 -0
  35. package/dist/attack/candidateStore.d.ts +95 -0
  36. package/dist/attack/candidateStore.js +231 -0
  37. package/dist/attack/candidateStore.js.map +1 -0
  38. package/dist/attack/evidenceLedger.d.ts +67 -0
  39. package/dist/attack/evidenceLedger.js +192 -0
  40. package/dist/attack/evidenceLedger.js.map +1 -0
  41. package/dist/attack/finishGate.d.ts +62 -0
  42. package/dist/attack/finishGate.js +209 -0
  43. package/dist/attack/finishGate.js.map +1 -0
  44. package/dist/attack/fixCodeMerge.d.ts +27 -0
  45. package/dist/attack/fixCodeMerge.js +42 -0
  46. package/dist/attack/fixCodeMerge.js.map +1 -0
  47. package/dist/attack/fixVerifyLoop.d.ts +55 -0
  48. package/dist/attack/fixVerifyLoop.js +187 -0
  49. package/dist/attack/fixVerifyLoop.js.map +1 -0
  50. package/dist/attack/investigationProfiles.d.ts +36 -0
  51. package/dist/attack/investigationProfiles.js +144 -0
  52. package/dist/attack/investigationProfiles.js.map +1 -0
  53. package/dist/attack/investigationState.d.ts +227 -0
  54. package/dist/attack/investigationState.js +666 -0
  55. package/dist/attack/investigationState.js.map +1 -0
  56. package/dist/attack/mutationOperators.d.ts +22 -0
  57. package/dist/attack/mutationOperators.js +170 -0
  58. package/dist/attack/mutationOperators.js.map +1 -0
  59. package/dist/attack/mutationTest.d.ts +33 -0
  60. package/dist/attack/mutationTest.js +110 -0
  61. package/dist/attack/mutationTest.js.map +1 -0
  62. package/dist/attack/proofGate.d.ts +20 -0
  63. package/dist/attack/proofGate.js +104 -0
  64. package/dist/attack/proofGate.js.map +1 -0
  65. package/dist/attack/proofTypes.d.ts +57 -0
  66. package/dist/attack/proofTypes.js +32 -0
  67. package/dist/attack/proofTypes.js.map +1 -0
  68. package/dist/attack/protocolValidator.d.ts +50 -0
  69. package/dist/attack/protocolValidator.js +427 -0
  70. package/dist/attack/protocolValidator.js.map +1 -0
  71. package/dist/attack/qualityMetrics.d.ts +133 -0
  72. package/dist/attack/qualityMetrics.js +226 -0
  73. package/dist/attack/qualityMetrics.js.map +1 -0
  74. package/dist/attack/scanScheduler.d.ts +52 -0
  75. package/dist/attack/scanScheduler.js +265 -0
  76. package/dist/attack/scanScheduler.js.map +1 -0
  77. package/dist/attack/scanState.d.ts +58 -0
  78. package/dist/attack/scanState.js +102 -0
  79. package/dist/attack/scanState.js.map +1 -0
  80. package/dist/attack/searchIntent.d.ts +16 -0
  81. package/dist/attack/searchIntent.js +57 -0
  82. package/dist/attack/searchIntent.js.map +1 -0
  83. package/dist/attack/verifyLoop.d.ts +43 -0
  84. package/dist/attack/verifyLoop.js +314 -14
  85. package/dist/attack/verifyLoop.js.map +1 -1
  86. package/dist/attack/workItem.d.ts +57 -0
  87. package/dist/attack/workItem.js +225 -0
  88. package/dist/attack/workItem.js.map +1 -0
  89. package/dist/audit/findingReviewQueue.d.ts +109 -0
  90. package/dist/audit/findingReviewQueue.js +335 -0
  91. package/dist/audit/findingReviewQueue.js.map +1 -0
  92. package/dist/audit/scanAuditLog.d.ts +160 -0
  93. package/dist/audit/scanAuditLog.js +404 -0
  94. package/dist/audit/scanAuditLog.js.map +1 -0
  95. package/dist/dependency/dependencyChecker.js +35 -9
  96. package/dist/dependency/dependencyChecker.js.map +1 -1
  97. package/dist/dependency/exploitPriority.d.ts +33 -0
  98. package/dist/dependency/exploitPriority.js +78 -0
  99. package/dist/dependency/exploitPriority.js.map +1 -0
  100. package/dist/dependency/finding.d.ts +16 -0
  101. package/dist/dependency/osvClient.js +2 -0
  102. package/dist/dependency/osvClient.js.map +1 -1
  103. package/dist/dependency/types.d.ts +12 -1
  104. package/dist/mcp/server.js +13 -2
  105. package/dist/mcp/server.js.map +1 -1
  106. package/dist/mcp/tools.d.ts +1 -0
  107. package/dist/mcp/tools.js +127 -6
  108. package/dist/mcp/tools.js.map +1 -1
  109. package/dist/project-map/agentMemory.d.ts +83 -1
  110. package/dist/project-map/agentMemory.js +197 -7
  111. package/dist/project-map/agentMemory.js.map +1 -1
  112. package/dist/project-map/architectureContext.d.ts +202 -0
  113. package/dist/project-map/architectureContext.js +421 -0
  114. package/dist/project-map/architectureContext.js.map +1 -0
  115. package/dist/project-map/blastRadius.d.ts +54 -0
  116. package/dist/project-map/blastRadius.js +196 -0
  117. package/dist/project-map/blastRadius.js.map +1 -0
  118. package/dist/project-map/callGraphExtractor.d.ts +13 -0
  119. package/dist/project-map/callGraphExtractor.js +222 -0
  120. package/dist/project-map/callGraphExtractor.js.map +1 -0
  121. package/dist/project-map/capabilityRegistry.d.ts +46 -0
  122. package/dist/project-map/capabilityRegistry.js +91 -0
  123. package/dist/project-map/capabilityRegistry.js.map +1 -0
  124. package/dist/project-map/findTests.d.ts +29 -0
  125. package/dist/project-map/findTests.js +236 -0
  126. package/dist/project-map/findTests.js.map +1 -0
  127. package/dist/project-map/handlerInventory.d.ts +112 -0
  128. package/dist/project-map/handlerInventory.js +184 -0
  129. package/dist/project-map/handlerInventory.js.map +1 -0
  130. package/dist/project-map/implementationResolver.d.ts +43 -0
  131. package/dist/project-map/implementationResolver.js +217 -0
  132. package/dist/project-map/implementationResolver.js.map +1 -0
  133. package/dist/project-map/mapContext.d.ts +6 -1
  134. package/dist/project-map/mapContext.js +1 -0
  135. package/dist/project-map/mapContext.js.map +1 -1
  136. package/dist/project-map/scanCache.d.ts +57 -3
  137. package/dist/project-map/scanCache.js +61 -2
  138. package/dist/project-map/scanCache.js.map +1 -1
  139. package/dist/project-map/symbolIndex.d.ts +39 -0
  140. package/dist/project-map/symbolIndex.js +385 -0
  141. package/dist/project-map/symbolIndex.js.map +1 -0
  142. package/dist/tooling/agentEvalScoring.d.ts +77 -0
  143. package/dist/tooling/agentEvalScoring.js +140 -0
  144. package/dist/tooling/agentEvalScoring.js.map +1 -0
  145. package/dist/tooling/agentRegression.d.ts +53 -0
  146. package/dist/tooling/agentRegression.js +99 -0
  147. package/dist/tooling/agentRegression.js.map +1 -0
  148. package/dist/tools/agentScan.d.ts +69 -0
  149. package/dist/tools/agentScan.js +702 -43
  150. package/dist/tools/agentScan.js.map +1 -1
  151. package/dist/tools/findingReviewTools.d.ts +22 -0
  152. package/dist/tools/findingReviewTools.js +121 -0
  153. package/dist/tools/findingReviewTools.js.map +1 -0
  154. package/dist/tools/fix.js +1 -1
  155. package/dist/tools/fix.js.map +1 -1
  156. package/dist/tools/map.js +191 -1
  157. package/dist/tools/map.js.map +1 -1
  158. package/dist/tools/runTests.d.ts +2 -0
  159. package/dist/tools/runTests.js +29 -0
  160. package/dist/tools/runTests.js.map +1 -0
  161. package/dist/utils/effectMock.d.ts +1 -0
  162. package/dist/utils/effectMock.js +162 -0
  163. package/dist/utils/effectMock.js.map +1 -0
  164. package/dist/utils/gitContext.d.ts +26 -0
  165. package/dist/utils/gitContext.js +317 -0
  166. package/dist/utils/gitContext.js.map +1 -0
  167. package/dist/utils/localTestRunner.d.ts +57 -2
  168. package/dist/utils/localTestRunner.js +122 -115
  169. package/dist/utils/localTestRunner.js.map +1 -1
  170. package/dist/utils/securityConfig.d.ts +17 -0
  171. package/dist/utils/securityConfig.js +192 -0
  172. package/dist/utils/securityConfig.js.map +1 -0
  173. package/dist/utils/testCommandPolicy.d.ts +36 -0
  174. package/dist/utils/testCommandPolicy.js +252 -0
  175. package/dist/utils/testCommandPolicy.js.map +1 -0
  176. package/dist/utils/testRunner.d.ts +56 -0
  177. package/dist/utils/testRunner.js +246 -0
  178. package/dist/utils/testRunner.js.map +1 -0
  179. package/dist/utils/testSafety.d.ts +40 -2
  180. package/dist/utils/testSafety.js +205 -26
  181. package/dist/utils/testSafety.js.map +1 -1
  182. package/dist/utils/verificationSandbox.d.ts +113 -0
  183. package/dist/utils/verificationSandbox.js +656 -0
  184. package/dist/utils/verificationSandbox.js.map +1 -0
  185. package/package.json +1 -1
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ /**
3
+ * Blast radius computation — given a set of changed files, compute which
4
+ * other files in the workspace are affected by those changes.
5
+ *
6
+ * Uses the Project Map's import graph (forward: what this file imports;
7
+ * reverse: who imports this file) to traverse the dependency graph to a
8
+ * depth cap. The result is a set of files that the agent scan should focus
9
+ * on, plus the changed files themselves.
10
+ *
11
+ * Algorithm:
12
+ * 1. Invert the Project Map's `imports` records once into a reverse map:
13
+ * for each file F that imports module M, record F as an importer of M.
14
+ * 2. BFS from each changed file:
15
+ * - Forward edges: files that THIS file imports (if F changes, the
16
+ * files F depends on might behave differently — but they're
17
+ * dependencies, not dependents. We skip forward edges for blast
18
+ * radius because changing a file doesn't affect its dependencies.)
19
+ * - Reverse edges: files that import THIS file (if F changes, files
20
+ * that depend on F are affected — these are the blast radius.)
21
+ * 3. Cap depth at `maxDepth` (default 3) to avoid traversing the entire
22
+ * workspace for a large change.
23
+ * 4. Cap total files at `maxFiles` (default 100) to keep the scope
24
+ * manageable.
25
+ *
26
+ * Security:
27
+ * - All file paths come from the Project Map (already workspace-confined)
28
+ * - No filesystem access — pure graph computation
29
+ * - Output is a list of workspace-relative paths
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.computeBlastRadius = computeBlastRadius;
33
+ exports.formatBlastRadius = formatBlastRadius;
34
+ const DEFAULT_MAX_DEPTH = 3;
35
+ const DEFAULT_MAX_FILES = 100;
36
+ function normalizePath(p) {
37
+ return p.replace(/\\/g, '/');
38
+ }
39
+ function buildReverseImportMap(map) {
40
+ const reverse = new Map();
41
+ for (const [fileRel, extraction] of Object.entries(map.files)) {
42
+ const importer = normalizePath(fileRel);
43
+ if (!extraction.imports)
44
+ continue;
45
+ for (const [, sourceFile] of Object.entries(extraction.imports)) {
46
+ if (!sourceFile)
47
+ continue;
48
+ const imported = normalizePath(sourceFile);
49
+ if (imported === importer)
50
+ continue;
51
+ let importers = reverse.get(imported);
52
+ if (!importers) {
53
+ importers = [];
54
+ reverse.set(imported, importers);
55
+ }
56
+ if (!importers.includes(importer)) {
57
+ importers.push(importer);
58
+ }
59
+ }
60
+ }
61
+ return reverse;
62
+ }
63
+ function buildReverseCallGraph(map) {
64
+ const reverse = new Map();
65
+ for (const [fileRel, extraction] of Object.entries(map.files)) {
66
+ const caller = normalizePath(fileRel);
67
+ for (const endpoint of extraction.endpoints) {
68
+ if (!endpoint.callGraph)
69
+ continue;
70
+ for (const node of endpoint.callGraph) {
71
+ if (!node.calleeFile)
72
+ continue;
73
+ const callee = normalizePath(node.calleeFile);
74
+ if (callee === caller)
75
+ continue;
76
+ let callers = reverse.get(callee);
77
+ if (!callers) {
78
+ callers = [];
79
+ reverse.set(callee, callers);
80
+ }
81
+ if (!callers.includes(caller)) {
82
+ callers.push(caller);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ return reverse;
88
+ }
89
+ function buildReverseMiddlewareMap(map) {
90
+ const reverse = new Map();
91
+ for (const [fileRel, extraction] of Object.entries(map.files)) {
92
+ const handler = normalizePath(fileRel);
93
+ for (const endpoint of extraction.endpoints) {
94
+ if (!endpoint.middleware)
95
+ continue;
96
+ for (const mw of endpoint.middleware) {
97
+ if (!mw.sourceFile)
98
+ continue;
99
+ const mwFile = normalizePath(mw.sourceFile);
100
+ if (mwFile === handler)
101
+ continue;
102
+ let handlers = reverse.get(mwFile);
103
+ if (!handlers) {
104
+ handlers = [];
105
+ reverse.set(mwFile, handlers);
106
+ }
107
+ if (!handlers.includes(handler)) {
108
+ handlers.push(handler);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ return reverse;
114
+ }
115
+ function computeBlastRadius(options) {
116
+ const { changedFiles, map, maxDepth = DEFAULT_MAX_DEPTH, maxFiles = DEFAULT_MAX_FILES, } = options;
117
+ const normalizedChanged = changedFiles
118
+ .map(normalizePath)
119
+ .filter(f => f.length > 0);
120
+ if (normalizedChanged.length === 0) {
121
+ return { files: [], changedFiles: [], affectedFiles: [], depthReached: 0, truncated: false };
122
+ }
123
+ const reverseImports = buildReverseImportMap(map);
124
+ const reverseCallGraph = buildReverseCallGraph(map);
125
+ const reverseMiddleware = buildReverseMiddlewareMap(map);
126
+ function getReverseDeps(file) {
127
+ const deps = new Set();
128
+ for (const dep of reverseImports.get(file) || [])
129
+ deps.add(dep);
130
+ for (const dep of reverseCallGraph.get(file) || [])
131
+ deps.add(dep);
132
+ for (const dep of reverseMiddleware.get(file) || [])
133
+ deps.add(dep);
134
+ return [...deps];
135
+ }
136
+ const visited = new Set();
137
+ const queue = [];
138
+ for (const f of normalizedChanged) {
139
+ if (!visited.has(f)) {
140
+ visited.add(f);
141
+ queue.push({ file: f, depth: 0 });
142
+ }
143
+ }
144
+ let depthReached = 0;
145
+ while (queue.length > 0 && visited.size < maxFiles) {
146
+ const { file, depth } = queue.shift();
147
+ if (depth >= maxDepth)
148
+ continue;
149
+ if (depth + 1 > depthReached)
150
+ depthReached = depth + 1;
151
+ const dependents = getReverseDeps(file);
152
+ for (const dep of dependents) {
153
+ if (visited.has(dep))
154
+ continue;
155
+ if (visited.size >= maxFiles)
156
+ break;
157
+ visited.add(dep);
158
+ queue.push({ file: dep, depth: depth + 1 });
159
+ }
160
+ }
161
+ const truncated = visited.size >= maxFiles && queue.length > 0;
162
+ const allFiles = [...visited];
163
+ const changedSet = new Set(normalizedChanged);
164
+ const affectedFiles = allFiles.filter(f => !changedSet.has(f));
165
+ const changedInMap = normalizedChanged.filter(f => map.files[f] !== undefined || visited.has(f));
166
+ return {
167
+ files: allFiles,
168
+ changedFiles: changedInMap,
169
+ affectedFiles,
170
+ depthReached,
171
+ truncated,
172
+ };
173
+ }
174
+ function formatBlastRadius(result) {
175
+ if (result.files.length === 0) {
176
+ return 'No blast radius — no changed files provided.';
177
+ }
178
+ const lines = [
179
+ `Blast radius: ${result.files.length} file(s) (changed: ${result.changedFiles.length}, affected: ${result.affectedFiles.length}, depth: ${result.depthReached})${result.truncated ? ' [truncated]' : ''}:`,
180
+ '',
181
+ ];
182
+ lines.push('Changed files:');
183
+ for (const f of result.changedFiles.slice(0, 50)) {
184
+ lines.push(` [changed] ${f}`);
185
+ }
186
+ lines.push('');
187
+ lines.push('Affected files (importers/callers):');
188
+ for (const f of result.affectedFiles.slice(0, 50)) {
189
+ lines.push(` [affected] ${f}`);
190
+ }
191
+ if (result.files.length > 100) {
192
+ lines.push(` ... and ${result.files.length - 100} more`);
193
+ }
194
+ return lines.join('\n');
195
+ }
196
+ //# sourceMappingURL=blastRadius.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blastRadius.js","sourceRoot":"","sources":["../../src/project-map/blastRadius.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Call graph extractor — builds a forward + reverse call graph for a file
3
+ * or a specific function, using tree-sitter AST.
4
+ *
5
+ * Used by the agent scan's call_graph tool. Unlike layer1.ts's extractCallGraph
6
+ * (which is endpoint-handler-specific), this is a general-purpose extractor
7
+ * that works on any function in any parseable file.
8
+ *
9
+ * Forward graph: what does function X call? (callees)
10
+ * Reverse graph: who calls function X? (callers)
11
+ * File-level: what functions exist, and what do they call?
12
+ */
13
+ export declare function getCallGraph(workspaceRoot: string, filePath: string, functionName?: string): Promise<string>;
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /**
3
+ * Call graph extractor — builds a forward + reverse call graph for a file
4
+ * or a specific function, using tree-sitter AST.
5
+ *
6
+ * Used by the agent scan's call_graph tool. Unlike layer1.ts's extractCallGraph
7
+ * (which is endpoint-handler-specific), this is a general-purpose extractor
8
+ * that works on any function in any parseable file.
9
+ *
10
+ * Forward graph: what does function X call? (callees)
11
+ * Reverse graph: who calls function X? (callers)
12
+ * File-level: what functions exist, and what do they call?
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.getCallGraph = getCallGraph;
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const parserLoader_1 = require("./parserLoader");
52
+ const astHelpers_1 = require("./astHelpers");
53
+ const files_1 = require("../utils/files");
54
+ const FUNCTION_TYPES = new Set([
55
+ 'function_declaration', 'function_definition', 'method_definition',
56
+ 'async_function_declaration', 'async_function_definition',
57
+ 'generator_function_declaration', 'generator_declaration',
58
+ ]);
59
+ function extractFunctionList(root, source) {
60
+ const out = [];
61
+ const seen = new Set();
62
+ for (const n of (0, astHelpers_1.walk)(root)) {
63
+ if (!FUNCTION_TYPES.has(n.type))
64
+ continue;
65
+ let name = '';
66
+ for (const child of n.namedChildren) {
67
+ if ((0, astHelpers_1.isIdentifier)(child)) {
68
+ name = source.slice(child.startIndex, child.endIndex);
69
+ break;
70
+ }
71
+ }
72
+ if (!name && n.parent) {
73
+ const parent = n.parent;
74
+ if (parent.type === 'lexical_declaration' || parent.type === 'variable_declaration') {
75
+ const decl = parent.namedChildren.find(c => c.type === 'variable_declarator');
76
+ if (decl) {
77
+ const id = decl.child(0);
78
+ if (id && (0, astHelpers_1.isIdentifier)(id))
79
+ name = source.slice(id.startIndex, id.endIndex);
80
+ }
81
+ }
82
+ }
83
+ if (!name)
84
+ continue;
85
+ if (seen.has(n.startIndex))
86
+ continue;
87
+ seen.add(n.startIndex);
88
+ out.push({
89
+ name,
90
+ startLine: n.startPosition.row + 1,
91
+ endLine: n.endPosition.row + 1,
92
+ node: n,
93
+ });
94
+ }
95
+ return out;
96
+ }
97
+ function extractCallees(funcNode, source, imports, fromFile, workspaceRoot) {
98
+ const out = [];
99
+ const seen = new Set();
100
+ for (const n of (0, astHelpers_1.walk)(funcNode)) {
101
+ if (n.type !== 'call_expression' && n.type !== 'call')
102
+ continue;
103
+ const p = (0, astHelpers_1.callParts)(n, source);
104
+ if (!p)
105
+ continue;
106
+ const name = p.receiver ? `${p.receiver}.${p.method}` : p.method;
107
+ if (seen.has(name))
108
+ continue;
109
+ seen.add(name);
110
+ const calleeSpec = imports.get(p.receiver || '') || imports.get(p.method) || null;
111
+ const resolved = calleeSpec ? (0, astHelpers_1.resolveModulePath)(calleeSpec, fromFile, workspaceRoot) : null;
112
+ out.push({ name, calleeFile: resolved, line: p.line + 1 });
113
+ }
114
+ return out;
115
+ }
116
+ function findCallers(root, source, targetName) {
117
+ const out = [];
118
+ const seen = new Set();
119
+ for (const n of (0, astHelpers_1.walk)(root)) {
120
+ if (n.type !== 'call_expression' && n.type !== 'call')
121
+ continue;
122
+ const p = (0, astHelpers_1.callParts)(n, source);
123
+ if (!p)
124
+ continue;
125
+ if (p.method !== targetName)
126
+ continue;
127
+ let callerName = '<anonymous>';
128
+ let callerStart = 0;
129
+ let cur = n.parent;
130
+ while (cur) {
131
+ if (FUNCTION_TYPES.has(cur.type)) {
132
+ const id = cur.namedChildren.find(c => (0, astHelpers_1.isIdentifier)(c));
133
+ if (id)
134
+ callerName = source.slice(id.startIndex, id.endIndex);
135
+ callerStart = cur.startPosition.row + 1;
136
+ break;
137
+ }
138
+ cur = cur.parent;
139
+ }
140
+ const key = `${callerName}:${p.line}`;
141
+ if (seen.has(key))
142
+ continue;
143
+ seen.add(key);
144
+ out.push({ caller: callerName, line: p.line + 1, callerStart });
145
+ }
146
+ return out;
147
+ }
148
+ async function getCallGraph(workspaceRoot, filePath, functionName) {
149
+ const grammar = (0, parserLoader_1.grammarForFile)(filePath);
150
+ if (grammar === 'unknown') {
151
+ return `Cannot extract call graph: unsupported file type (${filePath}). Only JS/TS/TSX/Python can be parsed.`;
152
+ }
153
+ let content;
154
+ let relPath;
155
+ let absPath;
156
+ try {
157
+ absPath = (0, files_1.resolveWorkspacePath)(workspaceRoot, filePath);
158
+ content = fs.readFileSync(absPath, 'utf8');
159
+ relPath = path.relative(workspaceRoot, absPath).replace(/\\/g, '/');
160
+ }
161
+ catch (e) {
162
+ return `Error reading file "${filePath}": ${e.message || e}`;
163
+ }
164
+ const parsed = await (0, parserLoader_1.parseSource)(content, grammar);
165
+ if (!parsed) {
166
+ return `Cannot parse ${relPath}: tree-sitter parsing failed.`;
167
+ }
168
+ const { root } = parsed;
169
+ const imports = (0, astHelpers_1.collectImports)(root, content);
170
+ const functions = extractFunctionList(root, content);
171
+ if (functions.length === 0) {
172
+ return `No functions found in ${relPath}.`;
173
+ }
174
+ const lines = [`Call graph for ${relPath} (${functions.length} function(s)):`];
175
+ if (functionName) {
176
+ const target = functions.find(f => f.name === functionName);
177
+ if (!target) {
178
+ lines.push(`\nFunction "${functionName}" not found in this file.`);
179
+ lines.push(`\nAvailable functions:`);
180
+ for (const f of functions) {
181
+ lines.push(` L${f.startLine}-${f.endLine} ${f.name}`);
182
+ }
183
+ return lines.join('\n');
184
+ }
185
+ lines.push(`\nFunction: ${target.name} (L${target.startLine}-${target.endLine})`);
186
+ const callees = extractCallees(target.node, content, imports, absPath, workspaceRoot);
187
+ lines.push(`\n Callees (${callees.length} — what ${target.name} calls):`);
188
+ if (callees.length === 0) {
189
+ lines.push(' (none)');
190
+ }
191
+ else {
192
+ for (const c of callees) {
193
+ const file = c.calleeFile ? ` → ${c.calleeFile}` : '';
194
+ lines.push(` L${c.line} ${c.name}${file}`);
195
+ }
196
+ }
197
+ const callers = findCallers(root, content, target.name);
198
+ lines.push(`\n Callers (${callers.length} — who calls ${target.name}):`);
199
+ if (callers.length === 0) {
200
+ lines.push(' (none — this may be an entry point)');
201
+ }
202
+ else {
203
+ for (const c of callers) {
204
+ lines.push(` L${c.line} ${c.caller}`);
205
+ }
206
+ }
207
+ }
208
+ else {
209
+ lines.push('');
210
+ for (const f of functions) {
211
+ const callees = extractCallees(f.node, content, imports, absPath, workspaceRoot);
212
+ const calleeNames = callees.length > 0
213
+ ? callees.map(c => c.name).join(', ')
214
+ : '(no calls)';
215
+ lines.push(` L${f.startLine}-${f.endLine} ${f.name} → ${calleeNames}`);
216
+ }
217
+ lines.push('');
218
+ lines.push('Use call_graph with functionName to get forward + reverse edges for a specific function.');
219
+ }
220
+ return lines.join('\n');
221
+ }
222
+ //# sourceMappingURL=callGraphExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callGraphExtractor.js","sourceRoot":"","sources":["../../src/project-map/callGraphExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Capability registry — the dispatch point for tiered language support.
3
+ *
4
+ * Determines what analysis capabilities are available for each language:
5
+ * - Tier 1 ('deep'): taint, AST, call graph, guards, policy, verify
6
+ * - Tier 2 ('standard'): AST, call graph, semgrep (no taint, no guard eval)
7
+ * - Tier 3 ('fallback'): LLM exploration only (read_file, search_code)
8
+ *
9
+ * The confidence clamper (agentScan.ts) consults this to decide whether a
10
+ * finding's confidence should be penalized for not using structural tools.
11
+ * If a capability is unavailable for the language, the agent can't be blamed
12
+ * for not using it — but the confidence ceiling is lower overall.
13
+ *
14
+ * To promote a language to a higher tier, add its sinks/sources/sanitizers
15
+ * and move it to the appropriate set below. The rest of the system adapts
16
+ * automatically.
17
+ */
18
+ export type CapabilityTier = 'deep' | 'standard' | 'fallback';
19
+ export interface LanguageCapability {
20
+ language: string;
21
+ tier: CapabilityTier;
22
+ /** Taint tracking: trace_flow / trace_flow_cross_file */
23
+ taint: boolean;
24
+ /** Tree-sitter AST parsing available */
25
+ ast: boolean;
26
+ /** Call graph extraction available */
27
+ callGraph: boolean;
28
+ /** Guard function evaluation: check_guard */
29
+ guardCheck: boolean;
30
+ /** Endpoint policy checking: check_policy */
31
+ policyCheck: boolean;
32
+ /** Semgrep integration (Tier 2, not wired yet) */
33
+ semgrep: boolean;
34
+ /** Exploit verification via test execution: verify subagent */
35
+ verify: boolean;
36
+ /** Human-readable label for the UI */
37
+ tierLabel: string;
38
+ }
39
+ export declare function normalizeLanguage(language: string): string;
40
+ export declare function getCapability(language: string): LanguageCapability;
41
+ /**
42
+ * Evidence level tag for a finding, based on what structural tools were
43
+ * actually used during the investigation. The confidence clamper attaches
44
+ * this to each finding so the UI can show how the confidence was derived.
45
+ */
46
+ export declare function evidenceLevelTag(usedTaint: boolean, usedGuard: boolean, usedPolicy: boolean, verifyVerdict: string | undefined): string;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Capability registry — the dispatch point for tiered language support.
4
+ *
5
+ * Determines what analysis capabilities are available for each language:
6
+ * - Tier 1 ('deep'): taint, AST, call graph, guards, policy, verify
7
+ * - Tier 2 ('standard'): AST, call graph, semgrep (no taint, no guard eval)
8
+ * - Tier 3 ('fallback'): LLM exploration only (read_file, search_code)
9
+ *
10
+ * The confidence clamper (agentScan.ts) consults this to decide whether a
11
+ * finding's confidence should be penalized for not using structural tools.
12
+ * If a capability is unavailable for the language, the agent can't be blamed
13
+ * for not using it — but the confidence ceiling is lower overall.
14
+ *
15
+ * To promote a language to a higher tier, add its sinks/sources/sanitizers
16
+ * and move it to the appropriate set below. The rest of the system adapts
17
+ * automatically.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.normalizeLanguage = normalizeLanguage;
21
+ exports.getCapability = getCapability;
22
+ exports.evidenceLevelTag = evidenceLevelTag;
23
+ const DEEP_LANGUAGES = new Set([
24
+ 'javascript', 'typescript', 'tsx', 'python',
25
+ ]);
26
+ const STANDARD_LANGUAGES = new Set([]);
27
+ const TIER_LABELS = {
28
+ deep: 'Deep Analysis',
29
+ standard: 'Advanced Analysis',
30
+ fallback: 'Agent Analysis',
31
+ };
32
+ function normalizeLanguage(language) {
33
+ const l = (language || '').toLowerCase();
34
+ if (l === 'typescriptreact' || l === 'jsx')
35
+ return 'tsx' in DEEP_LANGUAGES || 'tsx' in STANDARD_LANGUAGES ? 'tsx' : l;
36
+ if (l === 'javascriptreact')
37
+ return 'javascript';
38
+ if (l === 'ts')
39
+ return 'typescript';
40
+ if (l === 'js')
41
+ return 'javascript';
42
+ if (l === 'py')
43
+ return 'python';
44
+ return l;
45
+ }
46
+ function getCapability(language) {
47
+ const lang = normalizeLanguage(language);
48
+ const tier = DEEP_LANGUAGES.has(lang)
49
+ ? 'deep'
50
+ : STANDARD_LANGUAGES.has(lang)
51
+ ? 'standard'
52
+ : 'fallback';
53
+ return {
54
+ language: lang,
55
+ tier,
56
+ taint: tier === 'deep',
57
+ ast: tier === 'deep' || tier === 'standard',
58
+ callGraph: tier === 'deep' || tier === 'standard',
59
+ guardCheck: tier === 'deep',
60
+ policyCheck: tier === 'deep',
61
+ semgrep: tier === 'standard',
62
+ verify: tier === 'deep',
63
+ tierLabel: TIER_LABELS[tier],
64
+ };
65
+ }
66
+ /**
67
+ * Evidence level tag for a finding, based on what structural tools were
68
+ * actually used during the investigation. The confidence clamper attaches
69
+ * this to each finding so the UI can show how the confidence was derived.
70
+ */
71
+ function evidenceLevelTag(usedTaint, usedGuard, usedPolicy, verifyVerdict) {
72
+ const parts = [];
73
+ if (usedTaint)
74
+ parts.push('taint-traced');
75
+ if (usedGuard)
76
+ parts.push('guard-checked');
77
+ if (usedPolicy)
78
+ parts.push('policy-checked');
79
+ if (verifyVerdict === 'PROVEN')
80
+ parts.push('verified');
81
+ else if (verifyVerdict === 'UNPROVEN')
82
+ parts.push('verify-failed');
83
+ else if (verifyVerdict === 'INCONCLUSIVE')
84
+ parts.push('verify-inconclusive');
85
+ else if (verifyVerdict === 'SKIPPED')
86
+ parts.push('verify-skipped');
87
+ if (parts.length === 0)
88
+ return 'llm-only';
89
+ return parts.join('+');
90
+ }
91
+ //# sourceMappingURL=capabilityRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilityRegistry.js","sourceRoot":"","sources":["../../src/project-map/capabilityRegistry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;AAqCH,8CAQC;AAED,sCAoBC;AAOD,4CAgBC;AAjED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC3B,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ;CAC9C,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS,EAAE,CAAC,CAAC;AAE/C,MAAM,WAAW,GAAmC;IAChD,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,mBAAmB;IAC7B,QAAQ,EAAE,gBAAgB;CAC7B,CAAC;AAEF,SAAgB,iBAAiB,CAAC,QAAgB;IAC9C,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,KAAK,iBAAiB,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,KAAK,IAAI,cAAc,IAAI,KAAK,IAAI,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtH,IAAI,CAAC,KAAK,iBAAiB;QAAE,OAAO,YAAY,CAAC;IACjD,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,IAAI,GAAmB,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QACjD,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,UAAU,CAAC;IAErB,OAAO;QACH,QAAQ,EAAE,IAAI;QACd,IAAI;QACJ,KAAK,EAAE,IAAI,KAAK,MAAM;QACtB,GAAG,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU;QAC3C,SAAS,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU;QACjD,UAAU,EAAE,IAAI,KAAK,MAAM;QAC3B,WAAW,EAAE,IAAI,KAAK,MAAM;QAC5B,OAAO,EAAE,IAAI,KAAK,UAAU;QAC5B,MAAM,EAAE,IAAI,KAAK,MAAM;QACvB,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC;KAC/B,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAC5B,SAAkB,EAClB,SAAkB,EAClB,UAAmB,EACnB,aAAiC;IAEjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3C,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,aAAa,KAAK,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SAClD,IAAI,aAAa,KAAK,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;SAC9D,IAAI,aAAa,KAAK,cAAc;QAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;SACxE,IAAI,aAAa,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACnE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Test discovery — finds test files that exercise a source file or symbol.
3
+ *
4
+ * Two strategies:
5
+ * 1. Naming convention: derive candidate test file paths from the source
6
+ * file (src/foo.ts → tests/foo.test.ts, src/foo.test.ts, etc.)
7
+ * 2. Symbol reference: if a symbol name is provided, search all test files
8
+ * in the workspace for references to that symbol.
9
+ *
10
+ * Returns ranked results with match type and confidence.
11
+ *
12
+ * Security:
13
+ * - All paths workspace-confined via resolveWorkspacePath
14
+ * - Output truncated to 16KB
15
+ * - No file contents returned — only paths and matched lines
16
+ */
17
+ export interface TestFinding {
18
+ /** Workspace-relative test file path. */
19
+ filePath: string;
20
+ /** How this test was found. */
21
+ matchType: 'naming' | 'symbol';
22
+ /** Confidence 0-1. */
23
+ confidence: number;
24
+ /** Matched line numbers (for symbol matches). */
25
+ matchedLines?: number[];
26
+ /** Preview of matched lines (for symbol matches). */
27
+ matchedPreviews?: string[];
28
+ }
29
+ export declare function findTests(workspaceRoot: string, filePath: string, symbol?: string): Promise<string>;