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.
Files changed (208) hide show
  1. package/.claude/settings.example.json +30 -0
  2. package/ARCHITECTURE.md +410 -0
  3. package/LICENSE +21 -0
  4. package/README.md +153 -0
  5. package/ROADMAP.md +117 -0
  6. package/data/vulnkb.json +666 -0
  7. package/dist/bin/aegis.d.ts +3 -0
  8. package/dist/bin/aegis.d.ts.map +1 -0
  9. package/dist/bin/aegis.js +489 -0
  10. package/dist/bin/aegis.js.map +1 -0
  11. package/dist/cache.d.ts +9 -0
  12. package/dist/cache.d.ts.map +1 -0
  13. package/dist/cache.js +146 -0
  14. package/dist/cache.js.map +1 -0
  15. package/dist/engines/ai-sinks.d.ts +52 -0
  16. package/dist/engines/ai-sinks.d.ts.map +1 -0
  17. package/dist/engines/ai-sinks.js +204 -0
  18. package/dist/engines/ai-sinks.js.map +1 -0
  19. package/dist/engines/eslint.d.ts +9 -0
  20. package/dist/engines/eslint.d.ts.map +1 -0
  21. package/dist/engines/eslint.js +245 -0
  22. package/dist/engines/eslint.js.map +1 -0
  23. package/dist/engines/joern.d.ts +3 -0
  24. package/dist/engines/joern.d.ts.map +1 -0
  25. package/dist/engines/joern.js +98 -0
  26. package/dist/engines/joern.js.map +1 -0
  27. package/dist/engines/js-sinks.d.ts +70 -0
  28. package/dist/engines/js-sinks.d.ts.map +1 -0
  29. package/dist/engines/js-sinks.js +370 -0
  30. package/dist/engines/js-sinks.js.map +1 -0
  31. package/dist/engines/llm-critic.d.ts +130 -0
  32. package/dist/engines/llm-critic.d.ts.map +1 -0
  33. package/dist/engines/llm-critic.js +551 -0
  34. package/dist/engines/llm-critic.js.map +1 -0
  35. package/dist/engines/pragma.d.ts +20 -0
  36. package/dist/engines/pragma.d.ts.map +1 -0
  37. package/dist/engines/pragma.js +83 -0
  38. package/dist/engines/pragma.js.map +1 -0
  39. package/dist/engines/property-test.d.ts +3 -0
  40. package/dist/engines/property-test.d.ts.map +1 -0
  41. package/dist/engines/property-test.js +134 -0
  42. package/dist/engines/property-test.js.map +1 -0
  43. package/dist/engines/pyright.d.ts +10 -0
  44. package/dist/engines/pyright.d.ts.map +1 -0
  45. package/dist/engines/pyright.js +143 -0
  46. package/dist/engines/pyright.js.map +1 -0
  47. package/dist/engines/pysa.d.ts +3 -0
  48. package/dist/engines/pysa.d.ts.map +1 -0
  49. package/dist/engines/pysa.js +83 -0
  50. package/dist/engines/pysa.js.map +1 -0
  51. package/dist/engines/python-sinks.d.ts +82 -0
  52. package/dist/engines/python-sinks.d.ts.map +1 -0
  53. package/dist/engines/python-sinks.js +459 -0
  54. package/dist/engines/python-sinks.js.map +1 -0
  55. package/dist/engines/registry.d.ts +26 -0
  56. package/dist/engines/registry.d.ts.map +1 -0
  57. package/dist/engines/registry.js +70 -0
  58. package/dist/engines/registry.js.map +1 -0
  59. package/dist/engines/secret-scan.d.ts +22 -0
  60. package/dist/engines/secret-scan.d.ts.map +1 -0
  61. package/dist/engines/secret-scan.js +179 -0
  62. package/dist/engines/secret-scan.js.map +1 -0
  63. package/dist/engines/semgrep.d.ts +10 -0
  64. package/dist/engines/semgrep.d.ts.map +1 -0
  65. package/dist/engines/semgrep.js +200 -0
  66. package/dist/engines/semgrep.js.map +1 -0
  67. package/dist/engines/treesitter.d.ts +18 -0
  68. package/dist/engines/treesitter.d.ts.map +1 -0
  69. package/dist/engines/treesitter.js +135 -0
  70. package/dist/engines/treesitter.js.map +1 -0
  71. package/dist/engines/tsc.d.ts +10 -0
  72. package/dist/engines/tsc.d.ts.map +1 -0
  73. package/dist/engines/tsc.js +142 -0
  74. package/dist/engines/tsc.js.map +1 -0
  75. package/dist/engines/types.d.ts +47 -0
  76. package/dist/engines/types.d.ts.map +1 -0
  77. package/dist/engines/types.js +27 -0
  78. package/dist/engines/types.js.map +1 -0
  79. package/dist/findings.d.ts +121 -0
  80. package/dist/findings.d.ts.map +1 -0
  81. package/dist/findings.js +98 -0
  82. package/dist/findings.js.map +1 -0
  83. package/dist/hooks/claude-code.d.ts +3 -0
  84. package/dist/hooks/claude-code.d.ts.map +1 -0
  85. package/dist/hooks/claude-code.js +187 -0
  86. package/dist/hooks/claude-code.js.map +1 -0
  87. package/dist/index/context.d.ts +127 -0
  88. package/dist/index/context.d.ts.map +1 -0
  89. package/dist/index/context.js +267 -0
  90. package/dist/index/context.js.map +1 -0
  91. package/dist/index/embeddings.d.ts +68 -0
  92. package/dist/index/embeddings.d.ts.map +1 -0
  93. package/dist/index/embeddings.js +570 -0
  94. package/dist/index/embeddings.js.map +1 -0
  95. package/dist/index/graph_routing.d.ts +36 -0
  96. package/dist/index/graph_routing.d.ts.map +1 -0
  97. package/dist/index/graph_routing.js +170 -0
  98. package/dist/index/graph_routing.js.map +1 -0
  99. package/dist/index/joern.d.ts +76 -0
  100. package/dist/index/joern.d.ts.map +1 -0
  101. package/dist/index/joern.js +782 -0
  102. package/dist/index/joern.js.map +1 -0
  103. package/dist/index/property-test.d.ts +88 -0
  104. package/dist/index/property-test.d.ts.map +1 -0
  105. package/dist/index/property-test.js +466 -0
  106. package/dist/index/property-test.js.map +1 -0
  107. package/dist/index/proto/scip.proto +897 -0
  108. package/dist/index/pysa.d.ts +91 -0
  109. package/dist/index/pysa.d.ts.map +1 -0
  110. package/dist/index/pysa.js +617 -0
  111. package/dist/index/pysa.js.map +1 -0
  112. package/dist/index/scip.d.ts +76 -0
  113. package/dist/index/scip.d.ts.map +1 -0
  114. package/dist/index/scip.js +541 -0
  115. package/dist/index/scip.js.map +1 -0
  116. package/dist/index/vulrag.d.ts +86 -0
  117. package/dist/index/vulrag.d.ts.map +1 -0
  118. package/dist/index/vulrag.js +242 -0
  119. package/dist/index/vulrag.js.map +1 -0
  120. package/dist/index.d.ts +9 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +8 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/install/claude-code.d.ts +31 -0
  125. package/dist/install/claude-code.d.ts.map +1 -0
  126. package/dist/install/claude-code.js +447 -0
  127. package/dist/install/claude-code.js.map +1 -0
  128. package/dist/lang.d.ts +5 -0
  129. package/dist/lang.d.ts.map +1 -0
  130. package/dist/lang.js +52 -0
  131. package/dist/lang.js.map +1 -0
  132. package/dist/learning/suppressions.d.ts +70 -0
  133. package/dist/learning/suppressions.d.ts.map +1 -0
  134. package/dist/learning/suppressions.js +179 -0
  135. package/dist/learning/suppressions.js.map +1 -0
  136. package/dist/mcp/server.d.ts +2 -0
  137. package/dist/mcp/server.d.ts.map +1 -0
  138. package/dist/mcp/server.js +187 -0
  139. package/dist/mcp/server.js.map +1 -0
  140. package/dist/mcp/tools/explain.d.ts +58 -0
  141. package/dist/mcp/tools/explain.d.ts.map +1 -0
  142. package/dist/mcp/tools/explain.js +60 -0
  143. package/dist/mcp/tools/explain.js.map +1 -0
  144. package/dist/mcp/tools/precheck.d.ts +29 -0
  145. package/dist/mcp/tools/precheck.d.ts.map +1 -0
  146. package/dist/mcp/tools/precheck.js +42 -0
  147. package/dist/mcp/tools/precheck.js.map +1 -0
  148. package/dist/mcp/tools/validate.d.ts +73 -0
  149. package/dist/mcp/tools/validate.d.ts.map +1 -0
  150. package/dist/mcp/tools/validate.js +66 -0
  151. package/dist/mcp/tools/validate.js.map +1 -0
  152. package/dist/mcp/warm.d.ts +88 -0
  153. package/dist/mcp/warm.d.ts.map +1 -0
  154. package/dist/mcp/warm.js +331 -0
  155. package/dist/mcp/warm.js.map +1 -0
  156. package/dist/orchestrator.d.ts +46 -0
  157. package/dist/orchestrator.d.ts.map +1 -0
  158. package/dist/orchestrator.js +596 -0
  159. package/dist/orchestrator.js.map +1 -0
  160. package/dist/policy.d.ts +51 -0
  161. package/dist/policy.d.ts.map +1 -0
  162. package/dist/policy.js +201 -0
  163. package/dist/policy.js.map +1 -0
  164. package/dist/risk.d.ts +31 -0
  165. package/dist/risk.d.ts.map +1 -0
  166. package/dist/risk.js +92 -0
  167. package/dist/risk.js.map +1 -0
  168. package/dist/stats.d.ts +72 -0
  169. package/dist/stats.d.ts.map +1 -0
  170. package/dist/stats.js +217 -0
  171. package/dist/stats.js.map +1 -0
  172. package/dist/telemetry/collector.d.ts +10 -0
  173. package/dist/telemetry/collector.d.ts.map +1 -0
  174. package/dist/telemetry/collector.js +75 -0
  175. package/dist/telemetry/collector.js.map +1 -0
  176. package/dist/telemetry/consent.d.ts +9 -0
  177. package/dist/telemetry/consent.d.ts.map +1 -0
  178. package/dist/telemetry/consent.js +42 -0
  179. package/dist/telemetry/consent.js.map +1 -0
  180. package/dist/telemetry/installation.d.ts +2 -0
  181. package/dist/telemetry/installation.d.ts.map +1 -0
  182. package/dist/telemetry/installation.js +32 -0
  183. package/dist/telemetry/installation.js.map +1 -0
  184. package/dist/telemetry/sanitizer.d.ts +5 -0
  185. package/dist/telemetry/sanitizer.d.ts.map +1 -0
  186. package/dist/telemetry/sanitizer.js +60 -0
  187. package/dist/telemetry/sanitizer.js.map +1 -0
  188. package/dist/telemetry/types.d.ts +39 -0
  189. package/dist/telemetry/types.d.ts.map +1 -0
  190. package/dist/telemetry/types.js +4 -0
  191. package/dist/telemetry/types.js.map +1 -0
  192. package/dist/telemetry/uploader.d.ts +12 -0
  193. package/dist/telemetry/uploader.d.ts.map +1 -0
  194. package/dist/telemetry/uploader.js +92 -0
  195. package/dist/telemetry/uploader.js.map +1 -0
  196. package/dist/util/logger.d.ts +19 -0
  197. package/dist/util/logger.d.ts.map +1 -0
  198. package/dist/util/logger.js +58 -0
  199. package/dist/util/logger.js.map +1 -0
  200. package/dist/util/safe-paths.d.ts +8 -0
  201. package/dist/util/safe-paths.d.ts.map +1 -0
  202. package/dist/util/safe-paths.js +102 -0
  203. package/dist/util/safe-paths.js.map +1 -0
  204. package/dist/util/subprocess.d.ts +32 -0
  205. package/dist/util/subprocess.d.ts.map +1 -0
  206. package/dist/util/subprocess.js +137 -0
  207. package/dist/util/subprocess.js.map +1 -0
  208. package/package.json +93 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * ESLint adapter — uses ESLint as a library (no subprocess), pinned to a small
3
+ * "high-signal for AI-generated code" ruleset.
4
+ *
5
+ * Specifically targets the async-foot-gun bugs that LLMs produce constantly:
6
+ * - no-floating-promises (Promise.then without return/await)
7
+ * - no-misused-promises (Promise in conditions)
8
+ * - require-await
9
+ * - no-unsafe-assignment (TS)
10
+ * - no-unused-vars (catches half-written code)
11
+ *
12
+ * Loads `@typescript-eslint/parser` so it works on .ts/.tsx too.
13
+ */
14
+ import { basename } from "node:path";
15
+ import { makeFindingId } from "../findings.js";
16
+ import { getLogger } from "../util/logger.js";
17
+ const log = getLogger("aegis.engine.eslint");
18
+ const SUPPORTED = ["javascript", "typescript", "jsx", "tsx"];
19
+ const RULES = {
20
+ // built-in
21
+ "no-unused-vars": "warn",
22
+ "no-undef": "error",
23
+ eqeqeq: "warn",
24
+ "no-eval": "error",
25
+ "no-implied-eval": "error",
26
+ "no-throw-literal": "warn",
27
+ "no-self-compare": "warn",
28
+ "no-constant-condition": "warn",
29
+ "no-unreachable": "warn",
30
+ "no-fallthrough": "warn",
31
+ };
32
+ // TS rules that work WITHOUT type information. The four highest-signal async
33
+ // rules (no-floating-promises, no-misused-promises, no-unsafe-assignment,
34
+ // no-unsafe-call) are type-aware and need a real tsconfig + parserOptions
35
+ // {project: ...}; Phase 1 adds project context and we re-enable them there.
36
+ const TS_RULES = {
37
+ "@typescript-eslint/no-unused-vars": "warn",
38
+ };
39
+ /**
40
+ * Common globals available in Node + browser + worker + es2024 environments.
41
+ * Without this, `no-undef` floods on every `process`, `setTimeout`, `console`,
42
+ * `Buffer`, etc. — total noise on real Node code.
43
+ *
44
+ * Kept minimal-and-hard-coded to avoid pulling in the 'globals' npm package
45
+ * (which would add another runtime dep for ~20 names).
46
+ */
47
+ const GLOBALS = {
48
+ // Node + JS runtime
49
+ process: "readonly",
50
+ Buffer: "readonly",
51
+ __dirname: "readonly",
52
+ __filename: "readonly",
53
+ global: "readonly",
54
+ globalThis: "readonly",
55
+ require: "readonly",
56
+ module: "readonly",
57
+ exports: "writable",
58
+ console: "readonly",
59
+ setTimeout: "readonly",
60
+ clearTimeout: "readonly",
61
+ setInterval: "readonly",
62
+ clearInterval: "readonly",
63
+ setImmediate: "readonly",
64
+ clearImmediate: "readonly",
65
+ queueMicrotask: "readonly",
66
+ URL: "readonly",
67
+ URLSearchParams: "readonly",
68
+ TextEncoder: "readonly",
69
+ TextDecoder: "readonly",
70
+ AbortController: "readonly",
71
+ AbortSignal: "readonly",
72
+ fetch: "readonly",
73
+ Headers: "readonly",
74
+ Request: "readonly",
75
+ Response: "readonly",
76
+ performance: "readonly",
77
+ structuredClone: "readonly",
78
+ // Browser (common — included so we don't false-positive on isomorphic code)
79
+ window: "readonly",
80
+ document: "readonly",
81
+ localStorage: "readonly",
82
+ sessionStorage: "readonly",
83
+ navigator: "readonly",
84
+ // Worker
85
+ self: "readonly",
86
+ };
87
+ function langToParser(lang) {
88
+ return lang === "typescript" || lang === "tsx"
89
+ ? "@typescript-eslint/parser"
90
+ : "espree";
91
+ }
92
+ function sevMap(s) {
93
+ return s === 2 ? "high" : "medium";
94
+ }
95
+ function confFor(s) {
96
+ return s === 2 ? 0.85 : 0.7;
97
+ }
98
+ let _Linter = null;
99
+ let _tsParser = null;
100
+ let _tsPlugin = null;
101
+ let _attempted = false;
102
+ /**
103
+ * The TS-eslint packages publish a CJS index that, when imported as ESM,
104
+ * wraps the real exports under `.default`. Pick the right shape so flat
105
+ * config sees a real ``plugin.rules`` / parser.parseForESLint``.
106
+ */
107
+ function unwrapDefault(mod) {
108
+ if (mod &&
109
+ typeof mod === "object" &&
110
+ "default" in mod) {
111
+ return mod.default;
112
+ }
113
+ return mod;
114
+ }
115
+ async function tryLoad() {
116
+ if (_attempted) {
117
+ if (_Linter)
118
+ return { Linter: _Linter, tsParser: _tsParser, tsPlugin: _tsPlugin };
119
+ return null;
120
+ }
121
+ _attempted = true;
122
+ try {
123
+ const { Linter } = await import("eslint");
124
+ _Linter = Linter;
125
+ }
126
+ catch (err) {
127
+ log.warn("eslint not installed", { err: String(err) });
128
+ return null;
129
+ }
130
+ try {
131
+ const mod = await import("@typescript-eslint/parser");
132
+ _tsParser = unwrapDefault(mod);
133
+ }
134
+ catch {
135
+ _tsParser = null;
136
+ }
137
+ try {
138
+ const mod = await import("@typescript-eslint/eslint-plugin");
139
+ _tsPlugin = unwrapDefault(mod);
140
+ }
141
+ catch {
142
+ _tsPlugin = null;
143
+ }
144
+ return { Linter: _Linter, tsParser: _tsParser, tsPlugin: _tsPlugin };
145
+ }
146
+ export class ESLintEngine {
147
+ name = "eslint";
148
+ languages = SUPPORTED;
149
+ async available() {
150
+ const loaded = await tryLoad();
151
+ return loaded !== null;
152
+ }
153
+ async run(input) {
154
+ const t0 = Date.now();
155
+ const loaded = await tryLoad();
156
+ if (!loaded) {
157
+ return {
158
+ engine: this.name,
159
+ findings: [],
160
+ unavailable: true,
161
+ durationMs: Date.now() - t0,
162
+ reason: "eslint_not_installed",
163
+ };
164
+ }
165
+ const { Linter, tsParser, tsPlugin } = loaded;
166
+ const isTs = input.lang === "typescript" || input.lang === "tsx";
167
+ const parser = langToParser(input.lang);
168
+ // The new flat-config style: pass `config` to `verify` directly.
169
+ const rules = { ...RULES };
170
+ if (isTs && tsPlugin) {
171
+ Object.assign(rules, TS_RULES);
172
+ }
173
+ const linter = new Linter({ configType: "flat" });
174
+ // files glob is REQUIRED for ESLint 9 flat config when the filename is an
175
+ // absolute path outside cwd — without it, verify() returns
176
+ // "No matching configuration found for <path>".
177
+ const config = [
178
+ {
179
+ files: ["**/*.{js,jsx,mjs,cjs,ts,tsx}"],
180
+ languageOptions: {
181
+ ecmaVersion: "latest",
182
+ sourceType: "module",
183
+ globals: GLOBALS,
184
+ ...(isTs && tsParser ? { parser: tsParser } : {}),
185
+ ...(input.lang === "jsx" || input.lang === "tsx"
186
+ ? { parserOptions: { ecmaFeatures: { jsx: true } } }
187
+ : {}),
188
+ },
189
+ ...(isTs && tsPlugin
190
+ ? { plugins: { "@typescript-eslint": tsPlugin } }
191
+ : {}),
192
+ rules,
193
+ },
194
+ ];
195
+ let messages = [];
196
+ try {
197
+ // Pass just the basename — ESLint flat-config glob matching is relative
198
+ // to cwd, so an absolute path outside cwd never matches `**/*.js` and
199
+ // returns "No matching configuration found".
200
+ const filenameForVerify = basename(input.filePath);
201
+ messages = linter.verify(input.content, config, {
202
+ filename: filenameForVerify,
203
+ });
204
+ }
205
+ catch (err) {
206
+ log.debug("verify threw", { err: String(err) });
207
+ return {
208
+ engine: this.name,
209
+ findings: [],
210
+ unavailable: true,
211
+ durationMs: Date.now() - t0,
212
+ reason: `verify_threw: ${String(err).slice(0, 100)}`,
213
+ };
214
+ }
215
+ const findings = [];
216
+ for (const m of messages) {
217
+ const rule = m.ruleId ?? "syntax_error";
218
+ const sev = sevMap(m.severity);
219
+ findings.push({
220
+ id: makeFindingId({
221
+ engine: this.name,
222
+ file: input.filePath,
223
+ line: m.line,
224
+ rule_id: rule,
225
+ }),
226
+ engine: "eslint",
227
+ file: input.filePath,
228
+ line: m.line,
229
+ col: m.column,
230
+ rule_id: rule,
231
+ severity: sev,
232
+ message: m.message.slice(0, 1900),
233
+ confidence: confFor(m.severity),
234
+ source: "lint",
235
+ });
236
+ }
237
+ return {
238
+ engine: this.name,
239
+ findings,
240
+ unavailable: false,
241
+ durationMs: Date.now() - t0,
242
+ };
243
+ }
244
+ }
245
+ //# sourceMappingURL=eslint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/engines/eslint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Engine } from "./types.js";
2
+ export declare const joernEngine: Engine;
3
+ //# sourceMappingURL=joern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joern.d.ts","sourceRoot":"","sources":["../../src/engines/joern.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,MAAM,EAAmC,MAAM,YAAY,CAAC;AAgG1E,eAAO,MAAM,WAAW,EAAE,MAA0B,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Joern CPG engine adapter — reads pre-computed findings from cache.
3
+ *
4
+ * The actual CPG build + CPGQL query is in ``src/index/joern.ts``. This
5
+ * module is the realtime fast path: it reads the per-project
6
+ * ``findings.jsonl`` (written by ``aegis index --joern``), filters to the
7
+ * file currently under review, and returns a ``Finding[]``.
8
+ *
9
+ * If the cache is missing the engine reports ``unavailable: true`` with a
10
+ * reason that tells the user how to build it.
11
+ */
12
+ import { existsSync, statSync } from "node:fs";
13
+ import { findJoernDir, findJoernJdk, joernFindingsPath, joernInfoPath, readJoernFindings, } from "../index/joern.js";
14
+ import { getLogger } from "../util/logger.js";
15
+ const log = getLogger("aegis.engine.joern");
16
+ /** Stale-cache warning threshold: if the cached findings.jsonl is older
17
+ * than this, we log a warn so users know to re-run ``aegis index --joern``.
18
+ * Doesn't change correctness — they still get the cached findings. */
19
+ const STALE_WARN_AGE_MS = 24 * 60 * 60 * 1000; // 24 h
20
+ class JoernEngine {
21
+ name = "joern";
22
+ languages = "all";
23
+ availabilityCache = null;
24
+ static AVAILABILITY_TTL_MS = 60_000;
25
+ async available() {
26
+ const now = Date.now();
27
+ if (this.availabilityCache &&
28
+ now - this.availabilityCache.checkedAt < JoernEngine.AVAILABILITY_TTL_MS) {
29
+ return this.availabilityCache.value;
30
+ }
31
+ // Engine is "available" iff joern + JDK 11..21 are installed. Absence
32
+ // of a cache for the current project is NOT unavailability — it just
33
+ // means run() will report "no cache, please run `aegis index --joern`".
34
+ const ok = findJoernDir() !== null && findJoernJdk() !== null;
35
+ this.availabilityCache = { value: ok, checkedAt: now };
36
+ return ok;
37
+ }
38
+ async run(input) {
39
+ const t0 = Date.now();
40
+ if (!input.projectRoot) {
41
+ return {
42
+ engine: this.name,
43
+ findings: [],
44
+ unavailable: false,
45
+ durationMs: Date.now() - t0,
46
+ reason: "no_project_root",
47
+ };
48
+ }
49
+ const findingsPath = joernFindingsPath(input.projectRoot);
50
+ const infoPath = joernInfoPath(input.projectRoot);
51
+ if (!existsSync(findingsPath) || !existsSync(infoPath)) {
52
+ return {
53
+ engine: this.name,
54
+ findings: [],
55
+ unavailable: false,
56
+ durationMs: Date.now() - t0,
57
+ reason: "no_cpg_cache — run `aegis index --joern` to build",
58
+ };
59
+ }
60
+ // Optional stale check — warn but still serve.
61
+ try {
62
+ const age = Date.now() - statSync(findingsPath).mtimeMs;
63
+ if (age > STALE_WARN_AGE_MS) {
64
+ log.debug("joern findings cache is stale", { age_ms: age, path: findingsPath });
65
+ }
66
+ }
67
+ catch {
68
+ // ignore
69
+ }
70
+ const all = readJoernFindings(input.projectRoot);
71
+ // Findings carry POSIX-relative paths. Compare against the file's relative
72
+ // path (relative to projectRoot). On Windows the input.filePath may use
73
+ // backslashes; normalize before compare.
74
+ const relPath = toRelPosix(input.filePath, input.projectRoot);
75
+ // Also match by basename — sometimes Joern emits a path that differs from
76
+ // ours by leading drive-letter or symlink resolution. Basename match is a
77
+ // safe fallback that won't cross-contaminate (same basename in two dirs
78
+ // is rare in real projects).
79
+ const baseName = relPath.split("/").pop() ?? relPath;
80
+ const fileFindings = all.filter((f) => f.file === relPath || f.file === baseName || f.file.endsWith("/" + baseName));
81
+ return {
82
+ engine: this.name,
83
+ findings: fileFindings,
84
+ unavailable: false,
85
+ durationMs: Date.now() - t0,
86
+ };
87
+ }
88
+ }
89
+ function toRelPosix(filePath, projectRoot) {
90
+ const fp = filePath.replace(/\\/g, "/");
91
+ const root = projectRoot.replace(/\\/g, "/").replace(/\/+$/, "");
92
+ if (fp.toLowerCase().startsWith(root.toLowerCase() + "/")) {
93
+ return fp.slice(root.length + 1);
94
+ }
95
+ return fp;
96
+ }
97
+ export const joernEngine = new JoernEngine();
98
+ //# sourceMappingURL=joern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joern.js","sourceRoot":"","sources":["../../src/engines/joern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Deterministic JavaScript / TypeScript dangerous-sinks scanner — no external binary.
3
+ *
4
+ * Covers the textbook patterns every JS/Node security linter flags:
5
+ *
6
+ * Code execution / RCE (CWE-95)
7
+ * - eval(<non-literal>)
8
+ * - new Function(<...>)
9
+ * - setTimeout/setInterval(<string>, ...)
10
+ * XSS (CWE-79)
11
+ * - element.innerHTML / outerHTML = <non-literal>
12
+ * - document.write / writeln(<non-literal>)
13
+ * - React dangerouslySetInnerHTML
14
+ * Command injection (CWE-78)
15
+ * - child_process.exec / execSync(<non-literal>)
16
+ * - child_process.spawn / spawnSync({ shell: true })
17
+ * Path traversal (CWE-22)
18
+ * - fs.{read,write,unlink}File(req.params.x)
19
+ * SSRF (CWE-918)
20
+ * - axios/fetch/got/http.get(req.params.x)
21
+ * Weak crypto (CWE-327 / CWE-338)
22
+ * - crypto.createHash("md5"|"sha1")
23
+ * - Math.random() in security-keyword context
24
+ * JWT misuse (CWE-347 / CWE-798)
25
+ * - jwt.verify(token, secret, { algorithms: ["none"] })
26
+ * - jwt.sign(payload, "<short-hardcoded-secret>")
27
+ * - jwt.verify without algorithms allowlist
28
+ * Open redirect (CWE-601)
29
+ * - res.redirect(req.query.x | req.body.x)
30
+ * CORS misconfig (CWE-942)
31
+ * - Access-Control-Allow-Origin: * AND Access-Control-Allow-Credentials: true
32
+ * Prototype pollution (CWE-1321)
33
+ * - lodash _.merge/set/setWith/defaultsDeep with req.body
34
+ * - Object.assign(prototype, ...)
35
+ *
36
+ * Same architecture as python-sinks: per-rule regex + isDangerous predicate
37
+ * + optional fileGate; severity HIGH or CRITICAL, confidence 0.75; routes
38
+ * the LLM critic for refinement.
39
+ */
40
+ import { Engine, EngineRunInput, EngineRunResult } from "./types.js";
41
+ import { Lang } from "../lang.js";
42
+ interface SinkRule {
43
+ id: string;
44
+ cwe: string;
45
+ severity: "high" | "critical";
46
+ what: string;
47
+ pattern: RegExp;
48
+ isDangerous: (firstArg: string, allArgs: string, fullContent?: string) => boolean;
49
+ fileGate?: (fullContent: string) => boolean;
50
+ remediation: string;
51
+ }
52
+ /** A JS arg "looks tainted" if it is NOT a pure string/number literal. */
53
+ declare function looksTainted(arg: string): boolean;
54
+ /** First positional arg from a parenthesized call body. */
55
+ declare function firstPositionalArg(body: string): string;
56
+ declare function containsTaintSource(s: string): boolean;
57
+ export declare class JsSinksEngine implements Engine {
58
+ readonly name: "js-sinks";
59
+ readonly languages: ReadonlyArray<Lang>;
60
+ available(): Promise<boolean>;
61
+ run(input: EngineRunInput): Promise<EngineRunResult>;
62
+ }
63
+ export declare const _testing: {
64
+ RULES: readonly SinkRule[];
65
+ looksTainted: typeof looksTainted;
66
+ firstPositionalArg: typeof firstPositionalArg;
67
+ containsTaintSource: typeof containsTaintSource;
68
+ };
69
+ export {};
70
+ //# sourceMappingURL=js-sinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js-sinks.d.ts","sourceRoot":"","sources":["../../src/engines/js-sinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGlC,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAClF,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAID,0EAA0E;AAC1E,iBAAS,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgB1C;AAED,2DAA2D;AAC3D,iBAAS,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBhD;AAOD,iBAAS,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AA0RD,qBAAa,aAAc,YAAW,MAAM;IAC1C,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAU;IACpC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,CAAgC;IAEjE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CA6D3D;AAED,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAC"}