@securecode-ai/mcp 0.3.9 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -13
- package/dist/api/client.d.ts +1 -1
- package/dist/api/client.js +2 -1
- package/dist/api/client.js.map +1 -1
- package/dist/api/types.d.ts +18 -0
- package/dist/attack/agentScanExecutor.js +159 -5
- package/dist/attack/agentScanExecutor.js.map +1 -1
- package/dist/attack/agentScanLoop.js +157 -3
- package/dist/attack/agentScanLoop.js.map +1 -1
- package/dist/attack/agentScanProtocol.d.ts +47 -5
- package/dist/attack/agentScanProtocol.js +3 -3
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +5 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.js +80 -3
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-map/agentMemory.d.ts +75 -0
- package/dist/project-map/agentMemory.js +230 -0
- package/dist/project-map/agentMemory.js.map +1 -0
- package/dist/project-map/crossFileTaintTracker.d.ts +51 -0
- package/dist/project-map/crossFileTaintTracker.js +429 -0
- package/dist/project-map/crossFileTaintTracker.js.map +1 -0
- package/dist/project-map/endpointDiscovery.d.ts +24 -0
- package/dist/project-map/endpointDiscovery.js +101 -0
- package/dist/project-map/endpointDiscovery.js.map +1 -0
- package/dist/project-map/guardEvaluator.js +37 -0
- package/dist/project-map/guardEvaluator.js.map +1 -1
- package/dist/project-map/guardPatterns.js +16 -5
- package/dist/project-map/guardPatterns.js.map +1 -1
- package/dist/project-map/sanitizers.js +10 -0
- package/dist/project-map/sanitizers.js.map +1 -1
- package/dist/project-map/scanCache.d.ts +67 -0
- package/dist/project-map/scanCache.js +169 -0
- package/dist/project-map/scanCache.js.map +1 -0
- package/dist/project-map/sinkRegistry.js +165 -0
- package/dist/project-map/sinkRegistry.js.map +1 -1
- package/dist/project-map/taintSources.d.ts +19 -1
- package/dist/project-map/taintSources.js +69 -2
- package/dist/project-map/taintSources.js.map +1 -1
- package/dist/project-map/taintTracker.d.ts +4 -1
- package/dist/project-map/taintTracker.js +188 -5
- package/dist/project-map/taintTracker.js.map +1 -1
- package/dist/tools/agentMemoryTools.d.ts +18 -0
- package/dist/tools/agentMemoryTools.js +107 -0
- package/dist/tools/agentMemoryTools.js.map +1 -0
- package/dist/tools/agentScan.d.ts +8 -7
- package/dist/tools/agentScan.js +245 -23
- package/dist/tools/agentScan.js.map +1 -1
- package/dist/utils/files.js +19 -2
- package/dist/utils/files.js.map +1 -1
- package/dist/utils/listFiles.d.ts +17 -0
- package/dist/utils/listFiles.js +126 -0
- package/dist/utils/listFiles.js.map +1 -0
- package/dist/utils/listImports.d.ts +15 -0
- package/dist/utils/listImports.js +164 -0
- package/dist/utils/listImports.js.map +1 -0
- package/package.json +1 -1
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -18,7 +18,7 @@ exports.TOOLS = [
|
|
|
18
18
|
},
|
|
19
19
|
language: {
|
|
20
20
|
type: 'string',
|
|
21
|
-
description: 'Language id (javascript, typescript, python
|
|
21
|
+
description: 'Language id (javascript, typescript, python). Inferred from filePath if omitted.',
|
|
22
22
|
},
|
|
23
23
|
scanDepth: {
|
|
24
24
|
type: 'string',
|
|
@@ -58,7 +58,7 @@ exports.TOOLS = [
|
|
|
58
58
|
},
|
|
59
59
|
language: {
|
|
60
60
|
type: 'string',
|
|
61
|
-
description: 'Language id (javascript, typescript, python
|
|
61
|
+
description: 'Language id (javascript, typescript, python).',
|
|
62
62
|
},
|
|
63
63
|
vulnerabilityType: {
|
|
64
64
|
type: 'string',
|
|
@@ -193,10 +193,87 @@ exports.TOOLS = [
|
|
|
193
193
|
},
|
|
194
194
|
language: {
|
|
195
195
|
type: 'string',
|
|
196
|
-
description: 'Language id (javascript, typescript, python
|
|
196
|
+
description: 'Language id (javascript, typescript, python). Inferred from filePath if omitted.',
|
|
197
197
|
},
|
|
198
198
|
},
|
|
199
199
|
},
|
|
200
200
|
},
|
|
201
|
+
{
|
|
202
|
+
name: 'securecode.record-false-positive',
|
|
203
|
+
description: 'Dismiss a vulnerability finding as a false positive. The agent learns from this and will not report similar patterns in future scans of this workspace. Stored per-workspace in .securecode/agent-memory.json. Use when the user marks a finding as "not a vulnerability".',
|
|
204
|
+
inputSchema: {
|
|
205
|
+
type: 'object',
|
|
206
|
+
properties: {
|
|
207
|
+
filePath: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
description: 'Workspace-relative path to the file where the finding was reported.',
|
|
210
|
+
},
|
|
211
|
+
findingType: {
|
|
212
|
+
type: 'string',
|
|
213
|
+
description: 'The vulnerability type of the finding (e.g. sql_injection, broken_access_control, missing_rate_limiting, information_disclosure, user_enumeration).',
|
|
214
|
+
},
|
|
215
|
+
line: {
|
|
216
|
+
type: 'number',
|
|
217
|
+
description: 'Line number of the finding.',
|
|
218
|
+
},
|
|
219
|
+
evidence: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
description: 'The evidence string from the finding (code snippet or description).',
|
|
222
|
+
},
|
|
223
|
+
reason: {
|
|
224
|
+
type: 'string',
|
|
225
|
+
description: 'Why this is a false positive (user\'s explanation).',
|
|
226
|
+
},
|
|
227
|
+
pattern: {
|
|
228
|
+
type: 'string',
|
|
229
|
+
description: 'Optional short pattern description. If omitted, derived from evidence.',
|
|
230
|
+
},
|
|
231
|
+
codeSnippet: {
|
|
232
|
+
type: 'string',
|
|
233
|
+
description: 'Optional code snippet for context.',
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
required: ['filePath', 'findingType', 'line', 'evidence', 'reason'],
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: 'securecode.get-agent-memory',
|
|
241
|
+
description: 'View the agent\'s learned memory for this workspace — false positives and known facts. Read-only. Use to review what the agent has learned before running a scan.',
|
|
242
|
+
inputSchema: {
|
|
243
|
+
type: 'object',
|
|
244
|
+
properties: {},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'securecode.clear-agent-memory',
|
|
249
|
+
description: 'Clear the agent\'s learned memory for this workspace. If "id" is provided, removes only that false positive. Otherwise clears all memory (false positives + known facts). Stored in .securecode/agent-memory.json.',
|
|
250
|
+
inputSchema: {
|
|
251
|
+
type: 'object',
|
|
252
|
+
properties: {
|
|
253
|
+
id: {
|
|
254
|
+
type: 'string',
|
|
255
|
+
description: 'Optional: ID of a specific false positive to remove. If omitted, clears ALL memory.',
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'securecode.add-known-fact',
|
|
262
|
+
description: 'Add a fact about the project the agent should know in future scans (e.g. "Project uses requireMembership for auth"). Helps the agent investigate faster by not re-discovering known structural facts.',
|
|
263
|
+
inputSchema: {
|
|
264
|
+
type: 'object',
|
|
265
|
+
properties: {
|
|
266
|
+
fact: {
|
|
267
|
+
type: 'string',
|
|
268
|
+
description: 'The fact to store (e.g. "Project uses requireMembership for membership auth, isProjectOwner for ownership").',
|
|
269
|
+
},
|
|
270
|
+
source: {
|
|
271
|
+
type: 'string',
|
|
272
|
+
description: 'Where this fact was discovered (e.g. "src/lib/authz.ts:12").',
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
required: ['fact', 'source'],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
201
278
|
];
|
|
202
279
|
//# sourceMappingURL=tools.js.map
|
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":";;;AAEa,QAAA,KAAK,GAAc;IAC5B;QACI,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACP,qPAAqP;QACzP,WAAW,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,IAAI,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+CAA+C;iBAC/D;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0FAA0F;iBAC1G;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent memory — per-workspace store of false positives and known facts.
|
|
3
|
+
*
|
|
4
|
+
* The agent reads this at the start of each scan so it doesn't repeat
|
|
5
|
+
* mistakes from prior scans. False positives are patterns the user has
|
|
6
|
+
* explicitly dismissed; known facts are structural facts about the project
|
|
7
|
+
* (e.g. "uses requireMembership for auth") that speed up investigation.
|
|
8
|
+
*
|
|
9
|
+
* Storage: <workspaceRoot>/.securecode/agent-memory.json
|
|
10
|
+
* Pattern: same as scanCache.ts — lazy mkdir, atomic write (.tmp + rename).
|
|
11
|
+
*
|
|
12
|
+
* Privacy: per-workspace only. No cross-tenant leakage. User-owned, deletable.
|
|
13
|
+
*/
|
|
14
|
+
export interface FalsePositiveEntry {
|
|
15
|
+
id: string;
|
|
16
|
+
findingType: string;
|
|
17
|
+
file: string;
|
|
18
|
+
line: number;
|
|
19
|
+
/** SHA-256 of the evidence string — for dedup. */
|
|
20
|
+
evidenceHash: string;
|
|
21
|
+
/** Short pattern description for the prompt. */
|
|
22
|
+
pattern: string;
|
|
23
|
+
/** User's reason for dismissing. */
|
|
24
|
+
reason: string;
|
|
25
|
+
/** Code snippet (truncated) for context. */
|
|
26
|
+
codeSnippet?: string;
|
|
27
|
+
addedAt: string;
|
|
28
|
+
}
|
|
29
|
+
export interface KnownFactEntry {
|
|
30
|
+
id: string;
|
|
31
|
+
fact: string;
|
|
32
|
+
source: string;
|
|
33
|
+
addedAt: string;
|
|
34
|
+
}
|
|
35
|
+
export interface AgentMemory {
|
|
36
|
+
version: number;
|
|
37
|
+
falsePositives: FalsePositiveEntry[];
|
|
38
|
+
knownFacts: KnownFactEntry[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load agent memory for a workspace. Returns an empty memory object
|
|
42
|
+
* (version + empty arrays) if the file doesn't exist or is corrupt.
|
|
43
|
+
*/
|
|
44
|
+
export declare function loadAgentMemory(workspaceRoot: string): AgentMemory;
|
|
45
|
+
export interface RecordFalsePositiveInput {
|
|
46
|
+
filePath: string;
|
|
47
|
+
findingType: string;
|
|
48
|
+
line: number;
|
|
49
|
+
evidence: string;
|
|
50
|
+
reason: string;
|
|
51
|
+
pattern?: string;
|
|
52
|
+
codeSnippet?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record a false positive. Dedupes by (findingType + evidenceHash).
|
|
56
|
+
* Returns the entry (existing or new). Returns null if input is invalid.
|
|
57
|
+
*/
|
|
58
|
+
export declare function recordFalsePositive(workspaceRoot: string, input: RecordFalsePositiveInput): FalsePositiveEntry | null;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a false positive by ID. Returns true if removed.
|
|
61
|
+
*/
|
|
62
|
+
export declare function removeFalsePositive(workspaceRoot: string, id: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Add a known fact. Dedupes by fact text (case-insensitive).
|
|
65
|
+
*/
|
|
66
|
+
export declare function addKnownFact(workspaceRoot: string, fact: string, source: string): KnownFactEntry | null;
|
|
67
|
+
/**
|
|
68
|
+
* Clear all agent memory (false positives + known facts) for a workspace.
|
|
69
|
+
*/
|
|
70
|
+
export declare function clearAgentMemory(workspaceRoot: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Format agent memory into a string block for injection into the agent's
|
|
73
|
+
* target context. Returns empty string if no memory.
|
|
74
|
+
*/
|
|
75
|
+
export declare function formatMemoryForPrompt(memory: AgentMemory): string;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Agent memory — per-workspace store of false positives and known facts.
|
|
4
|
+
*
|
|
5
|
+
* The agent reads this at the start of each scan so it doesn't repeat
|
|
6
|
+
* mistakes from prior scans. False positives are patterns the user has
|
|
7
|
+
* explicitly dismissed; known facts are structural facts about the project
|
|
8
|
+
* (e.g. "uses requireMembership for auth") that speed up investigation.
|
|
9
|
+
*
|
|
10
|
+
* Storage: <workspaceRoot>/.securecode/agent-memory.json
|
|
11
|
+
* Pattern: same as scanCache.ts — lazy mkdir, atomic write (.tmp + rename).
|
|
12
|
+
*
|
|
13
|
+
* Privacy: per-workspace only. No cross-tenant leakage. User-owned, deletable.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.loadAgentMemory = loadAgentMemory;
|
|
50
|
+
exports.recordFalsePositive = recordFalsePositive;
|
|
51
|
+
exports.removeFalsePositive = removeFalsePositive;
|
|
52
|
+
exports.addKnownFact = addKnownFact;
|
|
53
|
+
exports.clearAgentMemory = clearAgentMemory;
|
|
54
|
+
exports.formatMemoryForPrompt = formatMemoryForPrompt;
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const crypto = __importStar(require("crypto"));
|
|
58
|
+
const MEMORY_DIR = '.securecode';
|
|
59
|
+
const MEMORY_FILE = 'agent-memory.json';
|
|
60
|
+
const MEMORY_VERSION = 1;
|
|
61
|
+
const MAX_FALSE_POSITIVES = 100; // cap to prevent unbounded growth
|
|
62
|
+
const MAX_KNOWN_FACTS = 50;
|
|
63
|
+
// ── Path helpers ────────────────────────────────────────────────────────────
|
|
64
|
+
function memoryPath(workspaceRoot) {
|
|
65
|
+
return path.join(workspaceRoot, MEMORY_DIR, MEMORY_FILE);
|
|
66
|
+
}
|
|
67
|
+
function hashEvidence(evidence) {
|
|
68
|
+
return crypto.createHash('sha256').update(evidence).digest('hex').slice(0, 16);
|
|
69
|
+
}
|
|
70
|
+
function genId() {
|
|
71
|
+
return 'fp_' + crypto.randomBytes(4).toString('hex');
|
|
72
|
+
}
|
|
73
|
+
// ── Read / Write ────────────────────────────────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Load agent memory for a workspace. Returns an empty memory object
|
|
76
|
+
* (version + empty arrays) if the file doesn't exist or is corrupt.
|
|
77
|
+
*/
|
|
78
|
+
function loadAgentMemory(workspaceRoot) {
|
|
79
|
+
const p = memoryPath(workspaceRoot);
|
|
80
|
+
try {
|
|
81
|
+
if (!fs.existsSync(p)) {
|
|
82
|
+
return { version: MEMORY_VERSION, falsePositives: [], knownFacts: [] };
|
|
83
|
+
}
|
|
84
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
85
|
+
const data = JSON.parse(raw);
|
|
86
|
+
if (!data.version || data.version > MEMORY_VERSION) {
|
|
87
|
+
// Forward-incompatible — start fresh
|
|
88
|
+
return { version: MEMORY_VERSION, falsePositives: [], knownFacts: [] };
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
version: MEMORY_VERSION,
|
|
92
|
+
falsePositives: data.falsePositives || [],
|
|
93
|
+
knownFacts: data.knownFacts || [],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return { version: MEMORY_VERSION, falsePositives: [], knownFacts: [] };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Save agent memory (atomic write). */
|
|
101
|
+
function saveAgentMemory(workspaceRoot, memory) {
|
|
102
|
+
const dir = path.join(workspaceRoot, MEMORY_DIR);
|
|
103
|
+
if (!fs.existsSync(dir)) {
|
|
104
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
105
|
+
}
|
|
106
|
+
const p = memoryPath(workspaceRoot);
|
|
107
|
+
const tmp = p + '.tmp';
|
|
108
|
+
fs.writeFileSync(tmp, JSON.stringify(memory, null, 2), 'utf8');
|
|
109
|
+
fs.renameSync(tmp, p);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Record a false positive. Dedupes by (findingType + evidenceHash).
|
|
113
|
+
* Returns the entry (existing or new). Returns null if input is invalid.
|
|
114
|
+
*/
|
|
115
|
+
function recordFalsePositive(workspaceRoot, input) {
|
|
116
|
+
if (!input.filePath || !input.findingType || !input.evidence || !input.reason) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const memory = loadAgentMemory(workspaceRoot);
|
|
120
|
+
const evidenceHash = hashEvidence(input.evidence);
|
|
121
|
+
// Dedup: if the same finding type + evidence hash exists, update the reason
|
|
122
|
+
const existingIdx = memory.falsePositives.findIndex(fp => fp.findingType === input.findingType && fp.evidenceHash === evidenceHash);
|
|
123
|
+
if (existingIdx >= 0) {
|
|
124
|
+
memory.falsePositives[existingIdx].reason = input.reason;
|
|
125
|
+
memory.falsePositives[existingIdx].pattern = input.pattern || memory.falsePositives[existingIdx].pattern;
|
|
126
|
+
saveAgentMemory(workspaceRoot, memory);
|
|
127
|
+
return memory.falsePositives[existingIdx];
|
|
128
|
+
}
|
|
129
|
+
const entry = {
|
|
130
|
+
id: genId(),
|
|
131
|
+
findingType: input.findingType,
|
|
132
|
+
file: input.filePath,
|
|
133
|
+
line: input.line,
|
|
134
|
+
evidenceHash,
|
|
135
|
+
pattern: input.pattern || input.evidence.slice(0, 200),
|
|
136
|
+
reason: input.reason,
|
|
137
|
+
codeSnippet: input.codeSnippet ? input.codeSnippet.slice(0, 500) : undefined,
|
|
138
|
+
addedAt: new Date().toISOString(),
|
|
139
|
+
};
|
|
140
|
+
memory.falsePositives.push(entry);
|
|
141
|
+
// Cap growth — drop oldest
|
|
142
|
+
if (memory.falsePositives.length > MAX_FALSE_POSITIVES) {
|
|
143
|
+
memory.falsePositives = memory.falsePositives.slice(-MAX_FALSE_POSITIVES);
|
|
144
|
+
}
|
|
145
|
+
saveAgentMemory(workspaceRoot, memory);
|
|
146
|
+
return entry;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Remove a false positive by ID. Returns true if removed.
|
|
150
|
+
*/
|
|
151
|
+
function removeFalsePositive(workspaceRoot, id) {
|
|
152
|
+
const memory = loadAgentMemory(workspaceRoot);
|
|
153
|
+
const before = memory.falsePositives.length;
|
|
154
|
+
memory.falsePositives = memory.falsePositives.filter(fp => fp.id !== id);
|
|
155
|
+
if (memory.falsePositives.length === before)
|
|
156
|
+
return false;
|
|
157
|
+
saveAgentMemory(workspaceRoot, memory);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Add a known fact. Dedupes by fact text (case-insensitive).
|
|
162
|
+
*/
|
|
163
|
+
function addKnownFact(workspaceRoot, fact, source) {
|
|
164
|
+
if (!fact || !source)
|
|
165
|
+
return null;
|
|
166
|
+
const memory = loadAgentMemory(workspaceRoot);
|
|
167
|
+
const lower = fact.toLowerCase().trim();
|
|
168
|
+
if (memory.knownFacts.some(kf => kf.fact.toLowerCase().trim() === lower)) {
|
|
169
|
+
return null; // already exists
|
|
170
|
+
}
|
|
171
|
+
const entry = {
|
|
172
|
+
id: 'fact_' + crypto.randomBytes(4).toString('hex'),
|
|
173
|
+
fact,
|
|
174
|
+
source,
|
|
175
|
+
addedAt: new Date().toISOString(),
|
|
176
|
+
};
|
|
177
|
+
memory.knownFacts.push(entry);
|
|
178
|
+
if (memory.knownFacts.length > MAX_KNOWN_FACTS) {
|
|
179
|
+
memory.knownFacts = memory.knownFacts.slice(-MAX_KNOWN_FACTS);
|
|
180
|
+
}
|
|
181
|
+
saveAgentMemory(workspaceRoot, memory);
|
|
182
|
+
return entry;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Clear all agent memory (false positives + known facts) for a workspace.
|
|
186
|
+
*/
|
|
187
|
+
function clearAgentMemory(workspaceRoot) {
|
|
188
|
+
const p = memoryPath(workspaceRoot);
|
|
189
|
+
try {
|
|
190
|
+
if (fs.existsSync(p)) {
|
|
191
|
+
fs.unlinkSync(p);
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// ── Prompt formatting ───────────────────────────────────────────────────────
|
|
201
|
+
/**
|
|
202
|
+
* Format agent memory into a string block for injection into the agent's
|
|
203
|
+
* target context. Returns empty string if no memory.
|
|
204
|
+
*/
|
|
205
|
+
function formatMemoryForPrompt(memory) {
|
|
206
|
+
const hasFps = memory.falsePositives.length > 0;
|
|
207
|
+
const hasFacts = memory.knownFacts.length > 0;
|
|
208
|
+
if (!hasFps && !hasFacts)
|
|
209
|
+
return '';
|
|
210
|
+
const lines = ['Workspace memory (from previous scans in this workspace):'];
|
|
211
|
+
if (hasFps) {
|
|
212
|
+
lines.push('', `False positives — DO NOT report similar patterns (${memory.falsePositives.length}):`);
|
|
213
|
+
memory.falsePositives.forEach((fp, i) => {
|
|
214
|
+
lines.push(` ${i + 1}. [${fp.findingType}] "${fp.pattern}"`);
|
|
215
|
+
lines.push(` Reason: ${fp.reason}`);
|
|
216
|
+
if (fp.file)
|
|
217
|
+
lines.push(` Was at: ${fp.file}:${fp.line}`);
|
|
218
|
+
});
|
|
219
|
+
lines.push('', 'Before reporting a finding, check if it matches any false positive above.');
|
|
220
|
+
lines.push('If the finding type AND code pattern match a known FP, do NOT report it.');
|
|
221
|
+
}
|
|
222
|
+
if (hasFacts) {
|
|
223
|
+
lines.push('', `Known facts about this project (${memory.knownFacts.length}):`);
|
|
224
|
+
memory.knownFacts.forEach((f, i) => {
|
|
225
|
+
lines.push(` ${i + 1}. ${f.fact} (source: ${f.source})`);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return lines.join('\n');
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=agentMemory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentMemory.js","sourceRoot":"","sources":["../../src/project-map/agentMemory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-file taint tracker — follows taint across file boundaries.
|
|
3
|
+
*
|
|
4
|
+
* The single-file `trackTaint` engine finds source→sink flows within one
|
|
5
|
+
* file. This module extends that to multi-file flows by:
|
|
6
|
+
*
|
|
7
|
+
* 1. Parsing the entry file's imports (collectImports)
|
|
8
|
+
* 2. Resolving each import to a file on disk (resolveModulePath)
|
|
9
|
+
* 3. Indexing each imported function: does it return tainted data?
|
|
10
|
+
* Does it propagate taint through a specific parameter?
|
|
11
|
+
* 4. Running taint tracking on the entry file with the cross-file
|
|
12
|
+
* function index, so calls to imported functions that propagate
|
|
13
|
+
* taint are recognised.
|
|
14
|
+
*
|
|
15
|
+
* Limits prevent runaway analysis on large codebases:
|
|
16
|
+
* maxDepth (3) — how many import hops to follow
|
|
17
|
+
* maxFiles (10) — total files parsed per trace
|
|
18
|
+
* maxFunctionBodySize (5000 chars) — skip oversized functions
|
|
19
|
+
*/
|
|
20
|
+
export interface CrossFileStep {
|
|
21
|
+
file: string;
|
|
22
|
+
line: number;
|
|
23
|
+
variable: string;
|
|
24
|
+
operation: 'source' | 'call-cross-file' | 'return-tainted' | 'sink-arg';
|
|
25
|
+
description: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CrossFileTaintResult {
|
|
28
|
+
source: string;
|
|
29
|
+
sourceLine: number;
|
|
30
|
+
sourceFile: string;
|
|
31
|
+
sink: string;
|
|
32
|
+
sinkLine: number;
|
|
33
|
+
sinkFile: string;
|
|
34
|
+
canonicalType: string;
|
|
35
|
+
crossFileSteps: CrossFileStep[];
|
|
36
|
+
}
|
|
37
|
+
export interface CrossFileTaintOptions {
|
|
38
|
+
workspaceRoot: string;
|
|
39
|
+
filePath: string;
|
|
40
|
+
maxDepth?: number;
|
|
41
|
+
maxFiles?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Track taint propagation across file boundaries.
|
|
45
|
+
*
|
|
46
|
+
* Parses the entry file, resolves its imports, indexes imported functions
|
|
47
|
+
* for taint behavior, then runs taint tracking with cross-file knowledge.
|
|
48
|
+
*
|
|
49
|
+
* Returns CrossFileTaintResult[] with full file:line paths.
|
|
50
|
+
*/
|
|
51
|
+
export declare function trackTaintCrossFile(opts: CrossFileTaintOptions): Promise<CrossFileTaintResult[]>;
|