fivosense 0.1.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/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/.github/workflows/ci.yml +52 -0
- package/BLUEPRINT.md +215 -0
- package/BUILD_PLAN.md +175 -0
- package/CONTRIBUTING.md +80 -0
- package/DOCS_VERIFICATION.md +232 -0
- package/FINAL_CHECKLIST.md +263 -0
- package/FINAL_SUMMARY.md +238 -0
- package/GITHUB_PUSH.md +64 -0
- package/LICENSE +21 -0
- package/PROGRESS.md +153 -0
- package/README.md +443 -0
- package/RELEASE_READY.md +201 -0
- package/SECURITY.md +211 -0
- package/SECURITY_DEEP_AUDIT.md +331 -0
- package/TODO.md +52 -0
- package/dist/ai/judge.d.ts +36 -0
- package/dist/ai/judge.d.ts.map +1 -0
- package/dist/ai/judge.js +75 -0
- package/dist/ai/judge.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +39 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/editors/vscode.d.ts +30 -0
- package/dist/editors/vscode.d.ts.map +1 -0
- package/dist/editors/vscode.js +103 -0
- package/dist/editors/vscode.js.map +1 -0
- package/dist/engine/adversary.d.ts +24 -0
- package/dist/engine/adversary.d.ts.map +1 -0
- package/dist/engine/adversary.js +83 -0
- package/dist/engine/adversary.js.map +1 -0
- package/dist/engine/graph.d.ts +38 -0
- package/dist/engine/graph.d.ts.map +1 -0
- package/dist/engine/graph.js +131 -0
- package/dist/engine/graph.js.map +1 -0
- package/dist/engine/reach.d.ts +22 -0
- package/dist/engine/reach.d.ts.map +1 -0
- package/dist/engine/reach.js +107 -0
- package/dist/engine/reach.js.map +1 -0
- package/dist/engine/sinks.d.ts +52 -0
- package/dist/engine/sinks.d.ts.map +1 -0
- package/dist/engine/sinks.js +96 -0
- package/dist/engine/sinks.js.map +1 -0
- package/dist/engine/sources.d.ts +35 -0
- package/dist/engine/sources.d.ts.map +1 -0
- package/dist/engine/sources.js +59 -0
- package/dist/engine/sources.js.map +1 -0
- package/dist/engine/taint.d.ts +37 -0
- package/dist/engine/taint.d.ts.map +1 -0
- package/dist/engine/taint.js +83 -0
- package/dist/engine/taint.js.map +1 -0
- package/dist/engine/verify.d.ts +20 -0
- package/dist/engine/verify.d.ts.map +1 -0
- package/dist/engine/verify.js +65 -0
- package/dist/engine/verify.js.map +1 -0
- package/dist/features/badge.d.ts +20 -0
- package/dist/features/badge.d.ts.map +1 -0
- package/dist/features/badge.js +86 -0
- package/dist/features/badge.js.map +1 -0
- package/dist/features/fix.d.ts +20 -0
- package/dist/features/fix.d.ts.map +1 -0
- package/dist/features/fix.js +115 -0
- package/dist/features/fix.js.map +1 -0
- package/dist/features/roast.d.ts +23 -0
- package/dist/features/roast.d.ts.map +1 -0
- package/dist/features/roast.js +96 -0
- package/dist/features/roast.js.map +1 -0
- package/dist/hooks/agent.d.ts +19 -0
- package/dist/hooks/agent.d.ts.map +1 -0
- package/dist/hooks/agent.js +69 -0
- package/dist/hooks/agent.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/destructive.d.ts +35 -0
- package/dist/rules/destructive.d.ts.map +1 -0
- package/dist/rules/destructive.js +117 -0
- package/dist/rules/destructive.js.map +1 -0
- package/dist/rules/secrets.d.ts +29 -0
- package/dist/rules/secrets.d.ts.map +1 -0
- package/dist/rules/secrets.js +100 -0
- package/dist/rules/secrets.js.map +1 -0
- package/package.json +56 -0
- package/skill/SKILL.md +86 -0
- package/skill/prompts/path-judge.md +22 -0
- package/src/ai/judge.ts +100 -0
- package/src/cli/index.ts +46 -0
- package/src/editors/vscode.ts +125 -0
- package/src/engine/adversary.ts +100 -0
- package/src/engine/graph.ts +167 -0
- package/src/engine/reach.ts +141 -0
- package/src/engine/sinks.ts +113 -0
- package/src/engine/sources.ts +71 -0
- package/src/engine/taint.ts +117 -0
- package/src/engine/verify.ts +94 -0
- package/src/features/badge.ts +102 -0
- package/src/features/fix.ts +138 -0
- package/src/features/roast.ts +110 -0
- package/src/hooks/agent.ts +84 -0
- package/src/index.ts +147 -0
- package/src/rules/destructive.ts +131 -0
- package/src/rules/secrets.ts +120 -0
- package/test/engine.test.ts +110 -0
- package/test/features.test.ts +131 -0
- package/test/phase3.test.ts +129 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;GAEG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* FivoSense CLI
|
|
4
|
+
*/
|
|
5
|
+
import { auditFile, formatAuditResult } from '../index.js';
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
if (args.length === 0) {
|
|
8
|
+
console.log(`
|
|
9
|
+
🛡️ FivoSense - Neuro-symbolic AI Security Scanner
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
npx fivosense <file>
|
|
13
|
+
npx fivosense audit <file>
|
|
14
|
+
|
|
15
|
+
Example:
|
|
16
|
+
npx fivosense src/server.js
|
|
17
|
+
`);
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
const command = args[0];
|
|
21
|
+
const filepath = args[1] || args[0];
|
|
22
|
+
async function main() {
|
|
23
|
+
try {
|
|
24
|
+
console.log(`\n🔍 Auditing ${filepath}...\n`);
|
|
25
|
+
const result = await auditFile(filepath);
|
|
26
|
+
const output = formatAuditResult(result);
|
|
27
|
+
console.log(output);
|
|
28
|
+
// Exit with error code if critical/high findings
|
|
29
|
+
if (result.summary.critical > 0 || result.summary.high > 0) {
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error(`\n❌ Error: ${error.message}\n`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
main();
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;GASX,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpC,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,OAAO,CAAC,CAAC;QAE9C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEzC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpB,iDAAiD;QACjD,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code Extension Adapter
|
|
3
|
+
* Integrates FivoSense with VS Code
|
|
4
|
+
*/
|
|
5
|
+
export interface VSCodeDiagnostic {
|
|
6
|
+
file: string;
|
|
7
|
+
line: number;
|
|
8
|
+
column: number;
|
|
9
|
+
severity: 'error' | 'warning' | 'info';
|
|
10
|
+
message: string;
|
|
11
|
+
source: string;
|
|
12
|
+
code?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert FivoSense results to VS Code diagnostics
|
|
16
|
+
*/
|
|
17
|
+
export declare function analyzeWorkspace(files: string[]): Promise<VSCodeDiagnostic[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Quick fix provider for VS Code
|
|
20
|
+
*/
|
|
21
|
+
export declare function provideCodeActions(diagnostic: VSCodeDiagnostic): any[];
|
|
22
|
+
/**
|
|
23
|
+
* VS Code command handlers
|
|
24
|
+
*/
|
|
25
|
+
export declare const commands: {
|
|
26
|
+
'fivosense.scan': (uri: string) => Promise<string>;
|
|
27
|
+
'fivosense.fix': (file: string, line: number) => Promise<string>;
|
|
28
|
+
'fivosense.explain': (diagnostic: VSCodeDiagnostic) => Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=vscode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.d.ts","sourceRoot":"","sources":["../../src/editors/vscode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoDnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,GAAG,GAAG,EAAE,CA4BtE;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;4BACW,MAAM;4BAKN,MAAM,QAAQ,MAAM;sCAKV,gBAAgB;CAGzD,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code Extension Adapter
|
|
3
|
+
* Integrates FivoSense with VS Code
|
|
4
|
+
*/
|
|
5
|
+
import { auditFile, formatAuditResult } from '../index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Convert FivoSense results to VS Code diagnostics
|
|
8
|
+
*/
|
|
9
|
+
export async function analyzeWorkspace(files) {
|
|
10
|
+
const diagnostics = [];
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
try {
|
|
13
|
+
const result = await auditFile(file);
|
|
14
|
+
// Convert vulnerabilities to diagnostics
|
|
15
|
+
result.vulnerabilities.forEach(vuln => {
|
|
16
|
+
diagnostics.push({
|
|
17
|
+
file,
|
|
18
|
+
line: vuln.location.line,
|
|
19
|
+
column: vuln.location.column,
|
|
20
|
+
severity: vuln.severity === 'critical' ? 'error' : 'warning',
|
|
21
|
+
message: `${vuln.finding}: ${vuln.path}`,
|
|
22
|
+
source: 'FivoSense',
|
|
23
|
+
code: vuln.cwe,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
// Convert secrets to diagnostics
|
|
27
|
+
result.secrets.forEach(secret => {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
file,
|
|
30
|
+
line: secret.line,
|
|
31
|
+
column: 0,
|
|
32
|
+
severity: 'error',
|
|
33
|
+
message: `${secret.description}: ${secret.match}`,
|
|
34
|
+
source: 'FivoSense',
|
|
35
|
+
code: 'SECRET',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
// Convert destructive commands to diagnostics
|
|
39
|
+
result.destructive.forEach(cmd => {
|
|
40
|
+
diagnostics.push({
|
|
41
|
+
file,
|
|
42
|
+
line: 0,
|
|
43
|
+
column: 0,
|
|
44
|
+
severity: 'error',
|
|
45
|
+
message: `${cmd.description} (${cmd.category})`,
|
|
46
|
+
source: 'FivoSense',
|
|
47
|
+
code: 'DESTRUCTIVE',
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// Skip files that can't be analyzed
|
|
53
|
+
console.error(`Error analyzing ${file}:`, error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return diagnostics;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Quick fix provider for VS Code
|
|
60
|
+
*/
|
|
61
|
+
export function provideCodeActions(diagnostic) {
|
|
62
|
+
const actions = [];
|
|
63
|
+
// Add quick fix action
|
|
64
|
+
actions.push({
|
|
65
|
+
title: 'Fix with FivoSense',
|
|
66
|
+
kind: 'quickfix',
|
|
67
|
+
diagnostics: [diagnostic],
|
|
68
|
+
command: {
|
|
69
|
+
command: 'fivosense.fix',
|
|
70
|
+
title: 'Apply Fix',
|
|
71
|
+
arguments: [diagnostic.file, diagnostic.line],
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
// Add explain action
|
|
75
|
+
actions.push({
|
|
76
|
+
title: 'Explain vulnerability',
|
|
77
|
+
kind: 'info',
|
|
78
|
+
diagnostics: [diagnostic],
|
|
79
|
+
command: {
|
|
80
|
+
command: 'fivosense.explain',
|
|
81
|
+
title: 'Show Details',
|
|
82
|
+
arguments: [diagnostic],
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return actions;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* VS Code command handlers
|
|
89
|
+
*/
|
|
90
|
+
export const commands = {
|
|
91
|
+
'fivosense.scan': async (uri) => {
|
|
92
|
+
const result = await auditFile(uri);
|
|
93
|
+
return formatAuditResult(result);
|
|
94
|
+
},
|
|
95
|
+
'fivosense.fix': async (file, line) => {
|
|
96
|
+
// TODO: Implement fix application
|
|
97
|
+
return 'Fix applied';
|
|
98
|
+
},
|
|
99
|
+
'fivosense.explain': async (diagnostic) => {
|
|
100
|
+
return `Security Issue: ${diagnostic.message}\n\nFile: ${diagnostic.file}:${diagnostic.line}`;
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.js","sourceRoot":"","sources":["../../src/editors/vscode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adversarial Verification - AI attacker proves exploitability
|
|
3
|
+
*/
|
|
4
|
+
import { TaintTrace } from './taint.js';
|
|
5
|
+
export interface AdversarialResult {
|
|
6
|
+
exploitable: boolean;
|
|
7
|
+
confidence: number;
|
|
8
|
+
attackVector: string;
|
|
9
|
+
payload: string;
|
|
10
|
+
reasoning: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generate adversarial attack prompt
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildAdversarialPrompt(trace: TaintTrace, code: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse adversarial response
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseAdversarialResult(response: string): AdversarialResult | null;
|
|
20
|
+
/**
|
|
21
|
+
* Placeholder for adversarial verification
|
|
22
|
+
*/
|
|
23
|
+
export declare function verifyWithAdversary(trace: TaintTrace, code: string): Promise<AdversarialResult>;
|
|
24
|
+
//# sourceMappingURL=adversary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adversary.d.ts","sourceRoot":"","sources":["../../src/engine/adversary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAuC9E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAiBjF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,CAa5B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adversarial Verification - AI attacker proves exploitability
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate adversarial attack prompt
|
|
6
|
+
*/
|
|
7
|
+
export function buildAdversarialPrompt(trace, code) {
|
|
8
|
+
return `You are a security researcher testing for vulnerabilities.
|
|
9
|
+
|
|
10
|
+
**Vulnerability:** ${trace.finding}
|
|
11
|
+
**Category:** ${trace.category}
|
|
12
|
+
**CWE:** ${trace.cwe || 'N/A'}
|
|
13
|
+
|
|
14
|
+
**Data Flow:**
|
|
15
|
+
${trace.path}
|
|
16
|
+
|
|
17
|
+
**Code:**
|
|
18
|
+
\`\`\`javascript
|
|
19
|
+
${code}
|
|
20
|
+
\`\`\`
|
|
21
|
+
|
|
22
|
+
**Your Task:**
|
|
23
|
+
Try to exploit this vulnerability. If you can create a working exploit, respond with:
|
|
24
|
+
|
|
25
|
+
\`\`\`json
|
|
26
|
+
{
|
|
27
|
+
"exploitable": true,
|
|
28
|
+
"confidence": 0.0-1.0,
|
|
29
|
+
"attackVector": "description of attack",
|
|
30
|
+
"payload": "actual exploit payload",
|
|
31
|
+
"reasoning": "why this works"
|
|
32
|
+
}
|
|
33
|
+
\`\`\`
|
|
34
|
+
|
|
35
|
+
If you CANNOT exploit it (properly sanitized), respond with:
|
|
36
|
+
|
|
37
|
+
\`\`\`json
|
|
38
|
+
{
|
|
39
|
+
"exploitable": false,
|
|
40
|
+
"confidence": 0.0-1.0,
|
|
41
|
+
"attackVector": "none",
|
|
42
|
+
"payload": "",
|
|
43
|
+
"reasoning": "why exploitation failed"
|
|
44
|
+
}
|
|
45
|
+
\`\`\``;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parse adversarial response
|
|
49
|
+
*/
|
|
50
|
+
export function parseAdversarialResult(response) {
|
|
51
|
+
try {
|
|
52
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
53
|
+
if (!jsonMatch)
|
|
54
|
+
return null;
|
|
55
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
56
|
+
return {
|
|
57
|
+
exploitable: Boolean(parsed.exploitable),
|
|
58
|
+
confidence: Number(parsed.confidence) || 0.5,
|
|
59
|
+
attackVector: String(parsed.attackVector || ''),
|
|
60
|
+
payload: String(parsed.payload || ''),
|
|
61
|
+
reasoning: String(parsed.reasoning || ''),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Placeholder for adversarial verification
|
|
70
|
+
*/
|
|
71
|
+
export async function verifyWithAdversary(trace, code) {
|
|
72
|
+
const prompt = buildAdversarialPrompt(trace, code);
|
|
73
|
+
// TODO: Phase 3 - integrate with host AI
|
|
74
|
+
console.warn('⚠️ Adversarial verification not yet integrated');
|
|
75
|
+
return {
|
|
76
|
+
exploitable: true,
|
|
77
|
+
confidence: 0.7,
|
|
78
|
+
attackVector: 'Adversarial verification not yet integrated',
|
|
79
|
+
payload: '',
|
|
80
|
+
reasoning: 'Marked as potentially exploitable until AI attacker confirms',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=adversary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adversary.js","sourceRoot":"","sources":["../../src/engine/adversary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAiB,EAAE,IAAY;IACpE,OAAO;;qBAEY,KAAK,CAAC,OAAO;gBAClB,KAAK,CAAC,QAAQ;WACnB,KAAK,CAAC,GAAG,IAAI,KAAK;;;EAG3B,KAAK,CAAC,IAAI;;;;EAIV,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BC,CAAC;AACR,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAExC,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;YACxC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG;YAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;YAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACrC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;SAC1C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAAiB,EACjB,IAAY;IAEZ,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEnD,yCAAyC;IACzC,OAAO,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAEhE,OAAO;QACL,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,GAAG;QACf,YAAY,EAAE,6CAA6C;QAC3D,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,8DAA8D;KAC1E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FivoCore Graph Builder
|
|
3
|
+
*/
|
|
4
|
+
import * as t from '@babel/types';
|
|
5
|
+
import { SourcePattern } from './sources.js';
|
|
6
|
+
import { SinkPattern } from './sinks.js';
|
|
7
|
+
export interface DataFlowNode {
|
|
8
|
+
id: string;
|
|
9
|
+
type: 'source' | 'sink' | 'variable' | 'function';
|
|
10
|
+
name: string;
|
|
11
|
+
value?: string;
|
|
12
|
+
loc?: t.SourceLocation | null;
|
|
13
|
+
sourcePattern?: SourcePattern;
|
|
14
|
+
sinkPattern?: SinkPattern;
|
|
15
|
+
}
|
|
16
|
+
export interface DataFlowEdge {
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
type: 'assignment' | 'call' | 'return' | 'parameter';
|
|
20
|
+
loc?: t.SourceLocation | null;
|
|
21
|
+
}
|
|
22
|
+
export interface TaintPath {
|
|
23
|
+
source: DataFlowNode;
|
|
24
|
+
sink: DataFlowNode;
|
|
25
|
+
path: DataFlowNode[];
|
|
26
|
+
sanitized: boolean;
|
|
27
|
+
confidence: number;
|
|
28
|
+
}
|
|
29
|
+
export interface DataFlowGraph {
|
|
30
|
+
nodes: Map<string, DataFlowNode>;
|
|
31
|
+
edges: DataFlowEdge[];
|
|
32
|
+
taintPaths: TaintPath[];
|
|
33
|
+
}
|
|
34
|
+
export declare function buildDataFlowGraph(code: string, filename?: string): DataFlowGraph;
|
|
35
|
+
export declare function getVulnerablePaths(graph: DataFlowGraph): TaintPath[];
|
|
36
|
+
export declare function getPathsBySeverity(graph: DataFlowGraph, severity: 'critical' | 'high' | 'medium'): TaintPath[];
|
|
37
|
+
export declare function formatTaintPath(path: TaintPath): string;
|
|
38
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/engine/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAY,aAAa,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAU,WAAW,EAAE,MAAM,YAAY,CAAC;AAKjD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;IACrD,GAAG,CAAC,EAAE,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAa,GAAG,aAAa,CAuGrF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,EAAE,CAEpE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,EAAE,CAE9G;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAIvD"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FivoCore Graph Builder
|
|
3
|
+
*/
|
|
4
|
+
import { parse } from '@babel/parser';
|
|
5
|
+
import * as traverseModule from '@babel/traverse';
|
|
6
|
+
import * as t from '@babel/types';
|
|
7
|
+
import { isSource } from './sources.js';
|
|
8
|
+
import { isSink } from './sinks.js';
|
|
9
|
+
// @ts-ignore - Handle CJS/ESM interop
|
|
10
|
+
const traverse = traverseModule.default ?? traverseModule;
|
|
11
|
+
const SANITIZERS = new Set([
|
|
12
|
+
'parseInt', 'parseFloat', 'Number', 'escape', 'escapeHtml', 'sanitize',
|
|
13
|
+
'validator.escape', 'validator.trim', 'encodeURIComponent', 'encodeURI',
|
|
14
|
+
]);
|
|
15
|
+
export function buildDataFlowGraph(code, filename = 'input.js') {
|
|
16
|
+
const ast = parse(code, {
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
plugins: ['jsx', 'typescript'],
|
|
19
|
+
errorRecovery: true,
|
|
20
|
+
});
|
|
21
|
+
const graph = { nodes: new Map(), edges: [], taintPaths: [] };
|
|
22
|
+
const taintedVars = new Map();
|
|
23
|
+
let nodeIdCounter = 0;
|
|
24
|
+
const getNodeId = () => `node_${nodeIdCounter++}`;
|
|
25
|
+
function addNode(node) {
|
|
26
|
+
graph.nodes.set(node.id, node);
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
function nodeToString(node) {
|
|
30
|
+
if (t.isMemberExpression(node)) {
|
|
31
|
+
const obj = nodeToString(node.object);
|
|
32
|
+
const prop = t.isIdentifier(node.property) ? node.property.name : '';
|
|
33
|
+
return `${obj}.${prop}`;
|
|
34
|
+
}
|
|
35
|
+
return t.isIdentifier(node) ? node.name : t.isStringLiteral(node) ? node.value : '';
|
|
36
|
+
}
|
|
37
|
+
function getCalleeName(node) {
|
|
38
|
+
if (t.isIdentifier(node))
|
|
39
|
+
return node.name;
|
|
40
|
+
if (t.isMemberExpression(node)) {
|
|
41
|
+
const obj = t.isIdentifier(node.object) ? node.object.name : '';
|
|
42
|
+
const prop = t.isIdentifier(node.property) ? node.property.name : '';
|
|
43
|
+
return `${obj}.${prop}`;
|
|
44
|
+
}
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
47
|
+
function findTaintedVars(node) {
|
|
48
|
+
const results = [];
|
|
49
|
+
if (t.isIdentifier(node)) {
|
|
50
|
+
const taint = taintedVars.get(node.name);
|
|
51
|
+
if (taint)
|
|
52
|
+
results.push({ varName: node.name, taint });
|
|
53
|
+
}
|
|
54
|
+
else if (t.isTemplateLiteral(node)) {
|
|
55
|
+
node.expressions.forEach(expr => results.push(...findTaintedVars(expr)));
|
|
56
|
+
}
|
|
57
|
+
else if (t.isBinaryExpression(node)) {
|
|
58
|
+
results.push(...findTaintedVars(node.left), ...findTaintedVars(node.right));
|
|
59
|
+
}
|
|
60
|
+
else if (t.isCallExpression(node)) {
|
|
61
|
+
node.arguments.forEach(arg => !t.isSpreadElement(arg) && results.push(...findTaintedVars(arg)));
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
traverse(ast, {
|
|
66
|
+
VariableDeclarator(path) {
|
|
67
|
+
const { id, init } = path.node;
|
|
68
|
+
if (t.isIdentifier(id) && init) {
|
|
69
|
+
const varName = id.name;
|
|
70
|
+
const sourcePattern = isSource(nodeToString(init));
|
|
71
|
+
if (sourcePattern) {
|
|
72
|
+
const node = addNode({
|
|
73
|
+
id: getNodeId(), type: 'source', name: varName, value: nodeToString(init),
|
|
74
|
+
loc: path.node.loc, sourcePattern,
|
|
75
|
+
});
|
|
76
|
+
taintedVars.set(varName, { source: sourcePattern, sanitized: false, node });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const taintedSources = findTaintedVars(init);
|
|
80
|
+
if (taintedSources.length > 0) {
|
|
81
|
+
const firstTaint = taintedSources[0].taint;
|
|
82
|
+
taintedVars.set(varName, { source: firstTaint.source, sanitized: firstTaint.sanitized, node: firstTaint.node });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
CallExpression(path) {
|
|
88
|
+
const { callee, arguments: args } = path.node;
|
|
89
|
+
if (SANITIZERS.has(getCalleeName(callee))) {
|
|
90
|
+
args.forEach((arg) => {
|
|
91
|
+
if (t.isIdentifier(arg)) {
|
|
92
|
+
const taint = taintedVars.get(arg.name);
|
|
93
|
+
if (taint)
|
|
94
|
+
taint.sanitized = true;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const sinkPattern = isSink(nodeToString(callee));
|
|
100
|
+
if (sinkPattern) {
|
|
101
|
+
const sinkNode = addNode({
|
|
102
|
+
id: getNodeId(), type: 'sink', name: getCalleeName(callee),
|
|
103
|
+
loc: path.node.loc, sinkPattern,
|
|
104
|
+
});
|
|
105
|
+
args.forEach((arg) => {
|
|
106
|
+
if (t.isSpreadElement(arg))
|
|
107
|
+
return;
|
|
108
|
+
findTaintedVars(arg).forEach(({ taint }) => {
|
|
109
|
+
graph.taintPaths.push({
|
|
110
|
+
source: taint.node, sink: sinkNode, path: [taint.node, sinkNode],
|
|
111
|
+
sanitized: taint.sanitized, confidence: taint.sanitized ? 0.3 : 0.9,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return graph;
|
|
119
|
+
}
|
|
120
|
+
export function getVulnerablePaths(graph) {
|
|
121
|
+
return graph.taintPaths.filter(p => !p.sanitized);
|
|
122
|
+
}
|
|
123
|
+
export function getPathsBySeverity(graph, severity) {
|
|
124
|
+
return graph.taintPaths.filter(p => p.sink.sinkPattern?.severity === severity);
|
|
125
|
+
}
|
|
126
|
+
export function formatTaintPath(path) {
|
|
127
|
+
const sourceStr = `${path.source.value} (${path.source.sourcePattern?.description})`;
|
|
128
|
+
const sinkStr = `${path.sink.name} (${path.sink.sinkPattern?.description})`;
|
|
129
|
+
return `${sourceStr} → ${sinkStr}`;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/engine/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reachability Analysis - Filters code to only entry-point reachable paths
|
|
3
|
+
* This reduces analysis surface by ~97% (OpenAnt research)
|
|
4
|
+
*/
|
|
5
|
+
export interface ReachabilityResult {
|
|
6
|
+
reachableFunctions: Set<string>;
|
|
7
|
+
reachableLines: Set<number>;
|
|
8
|
+
entryPoints: string[];
|
|
9
|
+
totalFunctions: number;
|
|
10
|
+
reachableFunctionCount: number;
|
|
11
|
+
reductionPercent: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Analyze reachability from entry points
|
|
15
|
+
*/
|
|
16
|
+
export declare function analyzeReachability(code: string): ReachabilityResult;
|
|
17
|
+
export declare function filterReachablePaths<T extends {
|
|
18
|
+
location: {
|
|
19
|
+
line: number;
|
|
20
|
+
};
|
|
21
|
+
}>(paths: T[], reachability: ReachabilityResult): T[];
|
|
22
|
+
//# sourceMappingURL=reach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../../src/engine/reach.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAeD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAiEpE;AA8BD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAC3E,KAAK,EAAE,CAAC,EAAE,EACV,YAAY,EAAE,kBAAkB,GAC/B,CAAC,EAAE,CAKL"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reachability Analysis - Filters code to only entry-point reachable paths
|
|
3
|
+
* This reduces analysis surface by ~97% (OpenAnt research)
|
|
4
|
+
*/
|
|
5
|
+
import { parse } from '@babel/parser';
|
|
6
|
+
import * as traverseModule from '@babel/traverse';
|
|
7
|
+
import * as t from '@babel/types';
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const traverse = traverseModule.default ?? traverseModule;
|
|
10
|
+
/**
|
|
11
|
+
* Common entry points in web applications
|
|
12
|
+
*/
|
|
13
|
+
const ENTRY_POINT_PATTERNS = [
|
|
14
|
+
/^app\.(get|post|put|delete|patch)/,
|
|
15
|
+
/^router\.(get|post|put|delete|patch)/,
|
|
16
|
+
/^exports\./,
|
|
17
|
+
/^module\.exports/,
|
|
18
|
+
/^export /,
|
|
19
|
+
/addEventListener/,
|
|
20
|
+
/^on[A-Z]/,
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Analyze reachability from entry points
|
|
24
|
+
*/
|
|
25
|
+
export function analyzeReachability(code) {
|
|
26
|
+
const ast = parse(code, {
|
|
27
|
+
sourceType: 'module',
|
|
28
|
+
plugins: ['jsx', 'typescript'],
|
|
29
|
+
errorRecovery: true,
|
|
30
|
+
});
|
|
31
|
+
const entryPoints = [];
|
|
32
|
+
const allFunctions = new Set();
|
|
33
|
+
const reachableFunctions = new Set();
|
|
34
|
+
const reachableLines = new Set();
|
|
35
|
+
const functionCalls = new Map();
|
|
36
|
+
traverse(ast, {
|
|
37
|
+
FunctionDeclaration(path) {
|
|
38
|
+
const name = path.node.id?.name;
|
|
39
|
+
if (name) {
|
|
40
|
+
allFunctions.add(name);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
CallExpression(path) {
|
|
44
|
+
const callee = getCalleeName(path.node.callee);
|
|
45
|
+
if (isEntryPoint(callee)) {
|
|
46
|
+
entryPoints.push(callee);
|
|
47
|
+
const callback = path.node.arguments[1] || path.node.arguments[0];
|
|
48
|
+
if (t.isFunctionExpression(callback) || t.isArrowFunctionExpression(callback)) {
|
|
49
|
+
markReachable(callback, reachableFunctions, reachableLines);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
const visited = new Set();
|
|
55
|
+
const queue = [...entryPoints];
|
|
56
|
+
while (queue.length > 0) {
|
|
57
|
+
const current = queue.shift();
|
|
58
|
+
if (visited.has(current))
|
|
59
|
+
continue;
|
|
60
|
+
visited.add(current);
|
|
61
|
+
reachableFunctions.add(current);
|
|
62
|
+
const callees = functionCalls.get(current) || new Set();
|
|
63
|
+
for (const callee of callees) {
|
|
64
|
+
if (!visited.has(callee)) {
|
|
65
|
+
queue.push(callee);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const totalFuncs = allFunctions.size || 1;
|
|
70
|
+
const reachableFuncs = reachableFunctions.size;
|
|
71
|
+
const reduction = ((totalFuncs - reachableFuncs) / totalFuncs) * 100;
|
|
72
|
+
return {
|
|
73
|
+
reachableFunctions,
|
|
74
|
+
reachableLines,
|
|
75
|
+
entryPoints,
|
|
76
|
+
totalFunctions: totalFuncs,
|
|
77
|
+
reachableFunctionCount: reachableFuncs,
|
|
78
|
+
reductionPercent: reduction,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function isEntryPoint(callee) {
|
|
82
|
+
return ENTRY_POINT_PATTERNS.some(pattern => pattern.test(callee));
|
|
83
|
+
}
|
|
84
|
+
function getCalleeName(node) {
|
|
85
|
+
if (t.isIdentifier(node))
|
|
86
|
+
return node.name;
|
|
87
|
+
if (t.isMemberExpression(node)) {
|
|
88
|
+
const obj = t.isIdentifier(node.object) ? node.object.name : '';
|
|
89
|
+
const prop = t.isIdentifier(node.property) ? node.property.name : '';
|
|
90
|
+
return `${obj}.${prop}`;
|
|
91
|
+
}
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
function markReachable(node, reachableFunctions, reachableLines) {
|
|
95
|
+
if (t.isFunctionExpression(node) || t.isArrowFunctionExpression(node)) {
|
|
96
|
+
if (node.loc) {
|
|
97
|
+
for (let i = node.loc.start.line; i <= node.loc.end.line; i++) {
|
|
98
|
+
reachableLines.add(i);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function filterReachablePaths(paths, reachability) {
|
|
104
|
+
return paths.filter(path => reachability.reachableLines.size === 0 ||
|
|
105
|
+
reachability.reachableLines.has(path.location.line));
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=reach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reach.js","sourceRoot":"","sources":["../../src/engine/reach.ts"],"names":[],"mappings":"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"}
|