dravix-agent 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/.claude/settings.example.json +30 -0
- package/ARCHITECTURE.md +410 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/ROADMAP.md +117 -0
- package/data/vulnkb.json +666 -0
- package/dist/bin/aegis.d.ts +3 -0
- package/dist/bin/aegis.d.ts.map +1 -0
- package/dist/bin/aegis.js +489 -0
- package/dist/bin/aegis.js.map +1 -0
- package/dist/cache.d.ts +9 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +146 -0
- package/dist/cache.js.map +1 -0
- package/dist/engines/ai-sinks.d.ts +52 -0
- package/dist/engines/ai-sinks.d.ts.map +1 -0
- package/dist/engines/ai-sinks.js +204 -0
- package/dist/engines/ai-sinks.js.map +1 -0
- package/dist/engines/eslint.d.ts +9 -0
- package/dist/engines/eslint.d.ts.map +1 -0
- package/dist/engines/eslint.js +245 -0
- package/dist/engines/eslint.js.map +1 -0
- package/dist/engines/joern.d.ts +3 -0
- package/dist/engines/joern.d.ts.map +1 -0
- package/dist/engines/joern.js +98 -0
- package/dist/engines/joern.js.map +1 -0
- package/dist/engines/js-sinks.d.ts +70 -0
- package/dist/engines/js-sinks.d.ts.map +1 -0
- package/dist/engines/js-sinks.js +370 -0
- package/dist/engines/js-sinks.js.map +1 -0
- package/dist/engines/llm-critic.d.ts +130 -0
- package/dist/engines/llm-critic.d.ts.map +1 -0
- package/dist/engines/llm-critic.js +551 -0
- package/dist/engines/llm-critic.js.map +1 -0
- package/dist/engines/pragma.d.ts +20 -0
- package/dist/engines/pragma.d.ts.map +1 -0
- package/dist/engines/pragma.js +83 -0
- package/dist/engines/pragma.js.map +1 -0
- package/dist/engines/property-test.d.ts +3 -0
- package/dist/engines/property-test.d.ts.map +1 -0
- package/dist/engines/property-test.js +134 -0
- package/dist/engines/property-test.js.map +1 -0
- package/dist/engines/pyright.d.ts +10 -0
- package/dist/engines/pyright.d.ts.map +1 -0
- package/dist/engines/pyright.js +143 -0
- package/dist/engines/pyright.js.map +1 -0
- package/dist/engines/pysa.d.ts +3 -0
- package/dist/engines/pysa.d.ts.map +1 -0
- package/dist/engines/pysa.js +83 -0
- package/dist/engines/pysa.js.map +1 -0
- package/dist/engines/python-sinks.d.ts +82 -0
- package/dist/engines/python-sinks.d.ts.map +1 -0
- package/dist/engines/python-sinks.js +459 -0
- package/dist/engines/python-sinks.js.map +1 -0
- package/dist/engines/registry.d.ts +26 -0
- package/dist/engines/registry.d.ts.map +1 -0
- package/dist/engines/registry.js +70 -0
- package/dist/engines/registry.js.map +1 -0
- package/dist/engines/secret-scan.d.ts +22 -0
- package/dist/engines/secret-scan.d.ts.map +1 -0
- package/dist/engines/secret-scan.js +179 -0
- package/dist/engines/secret-scan.js.map +1 -0
- package/dist/engines/semgrep.d.ts +10 -0
- package/dist/engines/semgrep.d.ts.map +1 -0
- package/dist/engines/semgrep.js +200 -0
- package/dist/engines/semgrep.js.map +1 -0
- package/dist/engines/treesitter.d.ts +18 -0
- package/dist/engines/treesitter.d.ts.map +1 -0
- package/dist/engines/treesitter.js +135 -0
- package/dist/engines/treesitter.js.map +1 -0
- package/dist/engines/tsc.d.ts +10 -0
- package/dist/engines/tsc.d.ts.map +1 -0
- package/dist/engines/tsc.js +142 -0
- package/dist/engines/tsc.js.map +1 -0
- package/dist/engines/types.d.ts +47 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +27 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/findings.d.ts +121 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +98 -0
- package/dist/findings.js.map +1 -0
- package/dist/hooks/claude-code.d.ts +3 -0
- package/dist/hooks/claude-code.d.ts.map +1 -0
- package/dist/hooks/claude-code.js +187 -0
- package/dist/hooks/claude-code.js.map +1 -0
- package/dist/index/context.d.ts +127 -0
- package/dist/index/context.d.ts.map +1 -0
- package/dist/index/context.js +267 -0
- package/dist/index/context.js.map +1 -0
- package/dist/index/embeddings.d.ts +68 -0
- package/dist/index/embeddings.d.ts.map +1 -0
- package/dist/index/embeddings.js +570 -0
- package/dist/index/embeddings.js.map +1 -0
- package/dist/index/graph_routing.d.ts +36 -0
- package/dist/index/graph_routing.d.ts.map +1 -0
- package/dist/index/graph_routing.js +170 -0
- package/dist/index/graph_routing.js.map +1 -0
- package/dist/index/joern.d.ts +76 -0
- package/dist/index/joern.d.ts.map +1 -0
- package/dist/index/joern.js +782 -0
- package/dist/index/joern.js.map +1 -0
- package/dist/index/property-test.d.ts +88 -0
- package/dist/index/property-test.d.ts.map +1 -0
- package/dist/index/property-test.js +466 -0
- package/dist/index/property-test.js.map +1 -0
- package/dist/index/proto/scip.proto +897 -0
- package/dist/index/pysa.d.ts +91 -0
- package/dist/index/pysa.d.ts.map +1 -0
- package/dist/index/pysa.js +617 -0
- package/dist/index/pysa.js.map +1 -0
- package/dist/index/scip.d.ts +76 -0
- package/dist/index/scip.d.ts.map +1 -0
- package/dist/index/scip.js +541 -0
- package/dist/index/scip.js.map +1 -0
- package/dist/index/vulrag.d.ts +86 -0
- package/dist/index/vulrag.d.ts.map +1 -0
- package/dist/index/vulrag.js +242 -0
- package/dist/index/vulrag.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/install/claude-code.d.ts +31 -0
- package/dist/install/claude-code.d.ts.map +1 -0
- package/dist/install/claude-code.js +447 -0
- package/dist/install/claude-code.js.map +1 -0
- package/dist/lang.d.ts +5 -0
- package/dist/lang.d.ts.map +1 -0
- package/dist/lang.js +52 -0
- package/dist/lang.js.map +1 -0
- package/dist/learning/suppressions.d.ts +70 -0
- package/dist/learning/suppressions.d.ts.map +1 -0
- package/dist/learning/suppressions.js +179 -0
- package/dist/learning/suppressions.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +187 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/explain.d.ts +58 -0
- package/dist/mcp/tools/explain.d.ts.map +1 -0
- package/dist/mcp/tools/explain.js +60 -0
- package/dist/mcp/tools/explain.js.map +1 -0
- package/dist/mcp/tools/precheck.d.ts +29 -0
- package/dist/mcp/tools/precheck.d.ts.map +1 -0
- package/dist/mcp/tools/precheck.js +42 -0
- package/dist/mcp/tools/precheck.js.map +1 -0
- package/dist/mcp/tools/validate.d.ts +73 -0
- package/dist/mcp/tools/validate.d.ts.map +1 -0
- package/dist/mcp/tools/validate.js +66 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/dist/mcp/warm.d.ts +88 -0
- package/dist/mcp/warm.d.ts.map +1 -0
- package/dist/mcp/warm.js +331 -0
- package/dist/mcp/warm.js.map +1 -0
- package/dist/orchestrator.d.ts +46 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +596 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/policy.d.ts +51 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +201 -0
- package/dist/policy.js.map +1 -0
- package/dist/risk.d.ts +31 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +92 -0
- package/dist/risk.js.map +1 -0
- package/dist/stats.d.ts +72 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +217 -0
- package/dist/stats.js.map +1 -0
- package/dist/telemetry/collector.d.ts +10 -0
- package/dist/telemetry/collector.d.ts.map +1 -0
- package/dist/telemetry/collector.js +75 -0
- package/dist/telemetry/collector.js.map +1 -0
- package/dist/telemetry/consent.d.ts +9 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +42 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/installation.d.ts +2 -0
- package/dist/telemetry/installation.d.ts.map +1 -0
- package/dist/telemetry/installation.js +32 -0
- package/dist/telemetry/installation.js.map +1 -0
- package/dist/telemetry/sanitizer.d.ts +5 -0
- package/dist/telemetry/sanitizer.d.ts.map +1 -0
- package/dist/telemetry/sanitizer.js +60 -0
- package/dist/telemetry/sanitizer.js.map +1 -0
- package/dist/telemetry/types.d.ts +39 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +4 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/telemetry/uploader.d.ts +12 -0
- package/dist/telemetry/uploader.d.ts.map +1 -0
- package/dist/telemetry/uploader.js +92 -0
- package/dist/telemetry/uploader.js.map +1 -0
- package/dist/util/logger.d.ts +19 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +58 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/safe-paths.d.ts +8 -0
- package/dist/util/safe-paths.d.ts.map +1 -0
- package/dist/util/safe-paths.js +102 -0
- package/dist/util/safe-paths.js.map +1 -0
- package/dist/util/subprocess.d.ts +32 -0
- package/dist/util/subprocess.d.ts.map +1 -0
- package/dist/util/subprocess.js +137 -0
- package/dist/util/subprocess.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-aware routing — surfaces "this file is the CALLER of a module that
|
|
3
|
+
* already has security/logic findings in cache".
|
|
4
|
+
*
|
|
5
|
+
* Without this, the orchestrator's ``decideStage2`` can miss real cross-file
|
|
6
|
+
* bugs (V2-14 eval found 2/7): the route file looks clean in isolation
|
|
7
|
+
* (no SQL, no obvious patterns) but it imports a function from db.py that
|
|
8
|
+
* Joern already flagged with CWE-89. The critic on the route file alone
|
|
9
|
+
* never gets invoked.
|
|
10
|
+
*
|
|
11
|
+
* **What this module does (v1, Python-only):**
|
|
12
|
+
* 1. Parse top-level imports from the source: ``from X import …`` and
|
|
13
|
+
* ``import X``.
|
|
14
|
+
* 2. Resolve each module name to a file inside the project root.
|
|
15
|
+
* 3. Cross-reference against the Joern + Pysa findings.jsonl caches.
|
|
16
|
+
* 4. Return one ``CallerSideRiskHit`` per (import, finding) pair so the
|
|
17
|
+
* critic can be both ROUTED to AND informed about which import is
|
|
18
|
+
* the risky one ("you're calling db.get_user_by_name which Joern
|
|
19
|
+
* flagged as CWE-89 — review THIS file's usage carefully").
|
|
20
|
+
*
|
|
21
|
+
* **What this module is NOT:**
|
|
22
|
+
* - It is not full call-graph analysis (no SCIP traversal yet — that's
|
|
23
|
+
* Phase 4). We only look at imports at the import statement, not at
|
|
24
|
+
* transitive calls.
|
|
25
|
+
* - It is not JS/TS-aware in v1. The ``jsImports`` parser is here as a
|
|
26
|
+
* stub for the next iteration but ``resolveImportToFile`` returns
|
|
27
|
+
* null for non-Python.
|
|
28
|
+
* - It is heuristic over import strings — does NOT understand aliasing
|
|
29
|
+
* (``from db import foo as bar`` is fine, ``import db as x; x.foo()``
|
|
30
|
+
* also handled because we key on the IMPORT not the call site).
|
|
31
|
+
*
|
|
32
|
+
* **Performance:**
|
|
33
|
+
* - Regex pass over ``content`` (≤ MB-scale typical): sub-ms.
|
|
34
|
+
* - readJoernFindings/readPysaFindings hit disk once per scan; both
|
|
35
|
+
* parse JSONL line-by-line (~10K findings = ~5 ms cold; both
|
|
36
|
+
* functions are call-site cached at the index module level).
|
|
37
|
+
* - ``findCallerSideRiskSignals`` is therefore ~10 ms p95 on a typical
|
|
38
|
+
* project — cheap enough for every gate call.
|
|
39
|
+
*/
|
|
40
|
+
import { existsSync } from "node:fs";
|
|
41
|
+
import { join, resolve as resolvePath } from "node:path";
|
|
42
|
+
import { readJoernFindings } from "./joern.js";
|
|
43
|
+
import { readPysaFindings } from "./pysa.js";
|
|
44
|
+
// ── Import parsers ───────────────────────────────────────────────────────-
|
|
45
|
+
/** Top-level Python imports — both ``from X import Y`` and ``import X``
|
|
46
|
+
* (and dotted forms like ``import services.pricing``). Aliases via ``as``
|
|
47
|
+
* are intentionally ignored — we care about the SOURCE module, not the
|
|
48
|
+
* local binding. */
|
|
49
|
+
export function parsePythonImports(content) {
|
|
50
|
+
const out = new Set();
|
|
51
|
+
// from <module> import …
|
|
52
|
+
for (const m of content.matchAll(/^\s*from\s+([a-zA-Z_][\w.]*)\s+import\s+/gm)) {
|
|
53
|
+
out.add(m[1]);
|
|
54
|
+
}
|
|
55
|
+
// import <module>[, <module>, …]
|
|
56
|
+
for (const m of content.matchAll(/^\s*import\s+([a-zA-Z_][\w.]*(?:\s*,\s*[a-zA-Z_][\w.]*)*)/gm)) {
|
|
57
|
+
for (const mod of m[1].split(",")) {
|
|
58
|
+
out.add(mod.trim());
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Drop stdlib-ish prefixes that obviously aren't project files (cheap
|
|
62
|
+
// pruning so we don't probe the filesystem for them). We DON'T do an
|
|
63
|
+
// exhaustive stdlib list — false positives here just waste a filesystem
|
|
64
|
+
// probe, never produce a wrong routing decision.
|
|
65
|
+
const STDLIB_PREFIX_BLOCKLIST = new Set([
|
|
66
|
+
"os", "sys", "json", "re", "math", "typing", "pathlib", "subprocess",
|
|
67
|
+
"asyncio", "datetime", "time", "collections", "itertools", "functools",
|
|
68
|
+
"dataclasses", "abc", "enum", "logging", "io", "string", "hashlib",
|
|
69
|
+
"base64", "uuid", "random", "warnings", "weakref", "copy", "pickle",
|
|
70
|
+
"sqlite3", "urllib", "http", "socket", "ssl", "secrets",
|
|
71
|
+
]);
|
|
72
|
+
return [...out].filter((m) => {
|
|
73
|
+
const head = m.split(".")[0];
|
|
74
|
+
return !STDLIB_PREFIX_BLOCKLIST.has(head);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** Top-level JS/TS imports — `import … from "…"` and `require("…")`.
|
|
78
|
+
* Currently parsed for future use; ``resolveImportToFile`` returns null
|
|
79
|
+
* for JS so these don't yet contribute to routing. */
|
|
80
|
+
export function parseJsImports(content) {
|
|
81
|
+
const out = new Set();
|
|
82
|
+
for (const m of content.matchAll(/(?:from|require\s*\()\s*['"]([^'"]+)['"]/g)) {
|
|
83
|
+
out.add(m[1]);
|
|
84
|
+
}
|
|
85
|
+
return [...out];
|
|
86
|
+
}
|
|
87
|
+
// ── Resolution ────────────────────────────────────────────────────────────
|
|
88
|
+
/** Resolve a Python module name to a file inside ``projectRoot``. Returns
|
|
89
|
+
* the absolute path or null when not found. */
|
|
90
|
+
export function resolveImportToFile(importStr, projectRoot, lang) {
|
|
91
|
+
if (lang === "python") {
|
|
92
|
+
// Dotted module → path-with-slashes; either <path>.py or <path>/__init__.py.
|
|
93
|
+
const path = importStr.replace(/\./g, "/");
|
|
94
|
+
const candidates = [
|
|
95
|
+
join(projectRoot, path + ".py"),
|
|
96
|
+
join(projectRoot, path, "__init__.py"),
|
|
97
|
+
];
|
|
98
|
+
for (const c of candidates) {
|
|
99
|
+
if (existsSync(c))
|
|
100
|
+
return c;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
// JS/TS resolution would need to honor moduleResolution, "./db" relative
|
|
105
|
+
// paths, package.json "exports", etc. Out of scope for v1 — the routing
|
|
106
|
+
// skips JS files cleanly (returning [] from findCallerSideRiskSignals).
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
// ── Public entry ─────────────────────────────────────────────────────────-
|
|
110
|
+
/** Inspect ``content``'s imports + the project's cached findings; return
|
|
111
|
+
* one hit per (import, finding) pair when the imported module already has
|
|
112
|
+
* a cached finding. */
|
|
113
|
+
export function findCallerSideRiskSignals(content, projectRoot, lang) {
|
|
114
|
+
if (lang !== "python")
|
|
115
|
+
return []; // v1: Python only
|
|
116
|
+
const imports = parsePythonImports(content);
|
|
117
|
+
if (imports.length === 0)
|
|
118
|
+
return [];
|
|
119
|
+
// Load caches once per call. Both readers are tolerant of a missing
|
|
120
|
+
// file (return []) so a project that hasn't been indexed yet just
|
|
121
|
+
// produces zero hits.
|
|
122
|
+
const root = resolvePath(projectRoot);
|
|
123
|
+
const joernFindings = readJoernFindings(root);
|
|
124
|
+
const pysaFindings = readPysaFindings(root);
|
|
125
|
+
if (joernFindings.length === 0 && pysaFindings.length === 0)
|
|
126
|
+
return [];
|
|
127
|
+
// Pre-build a per-file index so each import lookup is O(1).
|
|
128
|
+
const byFile = new Map();
|
|
129
|
+
for (const f of joernFindings) {
|
|
130
|
+
const arr = byFile.get(f.file) ?? [];
|
|
131
|
+
arr.push({ f, engine: "joern" });
|
|
132
|
+
byFile.set(f.file, arr);
|
|
133
|
+
}
|
|
134
|
+
for (const f of pysaFindings) {
|
|
135
|
+
const arr = byFile.get(f.file) ?? [];
|
|
136
|
+
arr.push({ f, engine: "pysa" });
|
|
137
|
+
byFile.set(f.file, arr);
|
|
138
|
+
}
|
|
139
|
+
const hits = [];
|
|
140
|
+
for (const imp of imports) {
|
|
141
|
+
const resolved = resolveImportToFile(imp, root, lang);
|
|
142
|
+
if (!resolved)
|
|
143
|
+
continue;
|
|
144
|
+
// Convert absolute → project-relative POSIX (Joern/Pysa store paths
|
|
145
|
+
// that way). The compare is case-insensitive on Windows since
|
|
146
|
+
// joern/pysa may produce mixed-case relative paths through the WSL
|
|
147
|
+
// bridge.
|
|
148
|
+
const rel = (resolved.startsWith(root)
|
|
149
|
+
? resolved.slice(root.length + 1)
|
|
150
|
+
: resolved).replace(/\\/g, "/");
|
|
151
|
+
const matches = byFile.get(rel) ?? [];
|
|
152
|
+
for (const m of matches) {
|
|
153
|
+
hits.push({
|
|
154
|
+
importedModule: imp,
|
|
155
|
+
resolvedFile: rel,
|
|
156
|
+
finding: m.f,
|
|
157
|
+
sourceEngine: m.engine,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return hits;
|
|
162
|
+
}
|
|
163
|
+
// Test-friendly exports
|
|
164
|
+
export const _testing = {
|
|
165
|
+
parsePythonImports,
|
|
166
|
+
parseJsImports,
|
|
167
|
+
resolveImportToFile,
|
|
168
|
+
findCallerSideRiskSignals,
|
|
169
|
+
};
|
|
170
|
+
//# sourceMappingURL=graph_routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_routing.js","sourceRoot":"","sources":["../../src/index/graph_routing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Finding } from "../findings.js";
|
|
2
|
+
export interface JoernBuildReport {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
/** Per-project cache directory the build wrote into. */
|
|
5
|
+
cacheDir: string;
|
|
6
|
+
/** Absolute path to the findings.jsonl produced by the query. */
|
|
7
|
+
findingsPath: string;
|
|
8
|
+
/** Number of findings written. */
|
|
9
|
+
findingsCount: number;
|
|
10
|
+
/** Wall-clock total. */
|
|
11
|
+
durationMs: number;
|
|
12
|
+
/** Reason if !ok (e.g. "joern not installed", "JDK 11-21 missing"). */
|
|
13
|
+
reason?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface JoernInfo {
|
|
16
|
+
built_at: number;
|
|
17
|
+
query_version: string;
|
|
18
|
+
joern_path: string;
|
|
19
|
+
jdk_path: string;
|
|
20
|
+
n_findings: number;
|
|
21
|
+
files_indexed: number;
|
|
22
|
+
}
|
|
23
|
+
/** Locate the joern-cli directory containing ``joern-parse`` + ``joern``. */
|
|
24
|
+
export declare function findJoernDir(): string | null;
|
|
25
|
+
/** Locate a JDK in the 11..21 range. ``AEGIS_JOERN_JDK`` env wins. */
|
|
26
|
+
export declare function findJoernJdk(): string | null;
|
|
27
|
+
export declare function joernFindingsPath(projectRoot: string): string;
|
|
28
|
+
export declare function joernInfoPath(projectRoot: string): string;
|
|
29
|
+
/** Read the Joern info.json — returns null if missing / unreadable. */
|
|
30
|
+
export declare function readJoernInfo(projectRoot: string): JoernInfo | null;
|
|
31
|
+
/** Read cached findings as Finding[]. Returns [] on missing / unreadable. */
|
|
32
|
+
export declare function readJoernFindings(projectRoot: string): Finding[];
|
|
33
|
+
/** sink-call → (CWE, severity, title) used by the parsed-line converter.
|
|
34
|
+
* Mirrors the table in argus/engines/joern.py. */
|
|
35
|
+
type SinkSeverity = "low" | "medium" | "high" | "critical";
|
|
36
|
+
interface SinkMeta {
|
|
37
|
+
cwe: string;
|
|
38
|
+
severity: SinkSeverity;
|
|
39
|
+
title: string;
|
|
40
|
+
}
|
|
41
|
+
interface LogicMeta {
|
|
42
|
+
cwe: string;
|
|
43
|
+
severity: SinkSeverity;
|
|
44
|
+
title: string;
|
|
45
|
+
}
|
|
46
|
+
/** RacerD-inspired race / concurrency detectors. Each kind maps to a CWE
|
|
47
|
+
* + human label that mirrors the LOGIC table's shape. They're tracked
|
|
48
|
+
* separately so the AEGIS_RACE prefix in CPGQL output is parse-time
|
|
49
|
+
* obvious and we never accidentally classify a sink as a race. */
|
|
50
|
+
interface RaceMeta {
|
|
51
|
+
cwe: string;
|
|
52
|
+
severity: SinkSeverity;
|
|
53
|
+
title: string;
|
|
54
|
+
}
|
|
55
|
+
declare function buildCpgqlScript(cpgPath: string): string;
|
|
56
|
+
/** Convert a Joern stdout dump to deduped Finding[]. */
|
|
57
|
+
declare function parseJoernOutput(stdout: string, projectRoot: string): Finding[];
|
|
58
|
+
declare function toRelPosix(absPath: string, projectRoot: string): string;
|
|
59
|
+
/** Build the CPG for a project, run the security+logic query, write the
|
|
60
|
+
* findings cache. Returns a structured report. Never throws — failures
|
|
61
|
+
* produce ``{ok:false, reason}``. */
|
|
62
|
+
export declare function buildJoernCpg(projectRoot: string, opts?: {
|
|
63
|
+
force?: boolean;
|
|
64
|
+
timeoutMs?: number;
|
|
65
|
+
}): Promise<JoernBuildReport>;
|
|
66
|
+
export declare const _testing: {
|
|
67
|
+
buildCpgqlScript: typeof buildCpgqlScript;
|
|
68
|
+
parseJoernOutput: typeof parseJoernOutput;
|
|
69
|
+
toRelPosix: typeof toRelPosix;
|
|
70
|
+
SINKS: Record<string, SinkMeta>;
|
|
71
|
+
LOGIC: Record<string, LogicMeta>;
|
|
72
|
+
RACES: Record<string, RaceMeta>;
|
|
73
|
+
QUERY_VERSION: string;
|
|
74
|
+
};
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=joern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joern.d.ts","sourceRoot":"","sources":["../../src/index/joern.ts"],"names":[],"mappings":"AA+CA,OAAO,EAAE,OAAO,EAAgC,MAAM,gBAAgB,CAAC;AA0CvE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IAGnB,aAAa,EAAE,MAAM,CAAC;CACvB;AASD,6EAA6E;AAC7E,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAe5C;AA4BD,sEAAsE;AACtE,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAe5C;AAaD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQnE;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,EAAE,CAiBhE;AAID;kDACkD;AAClD,KAAK,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAC3D,UAAU,QAAQ;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAUD;;;kEAGkE;AAClE,UAAU,QAAQ;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAuBD,iBAAS,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAyEjD;AAID,wDAAwD;AACxD,iBAAS,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,EAAE,CAiBxE;AAED,iBAAS,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAahE;AAoLD;;qCAEqC;AACrC,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,gBAAgB,CAAC,CA8O3B;AAGD,eAAO,MAAM,QAAQ;;;;;;;;CAQpB,CAAC"}
|