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,447 @@
1
+ /**
2
+ * Claude Code installer — registers aegis as a PreToolUse hook + MCP server
3
+ * + writes a mandatory-validate block to ~/.claude/CLAUDE.md.
4
+ *
5
+ * Cross-platform (Windows / macOS / Linux). Atomic + idempotent + reversible:
6
+ * - Re-running install is a no-op (markers detect prior install).
7
+ * - Backs up every file it touches as <file>.bak-dravix-<unix_ts>.
8
+ * - --dry-run prints what would change without writing.
9
+ * - `aegis uninstall` removes everything cleanly.
10
+ */
11
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { dirname, resolve } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ import { randomBytes } from "node:crypto";
16
+ const BEGIN_MARKER = "<!-- BEGIN DRAVIX-AGENT -->";
17
+ const END_MARKER = "<!-- END DRAVIX-AGENT -->";
18
+ /** Old FixMe block detection — pre-dravix users will have this header.
19
+ * Strip from `# FixMe Agent ...` up to the next top-level `#`/`## ` header
20
+ * (or EOF). Matches the block layout in user's original ~/.claude/CLAUDE.md. */
21
+ const FIXME_HEADER_RE = /^# FixMe Agent[^\n]*\n[\s\S]*?(?=^#{1,2} \S|\Z)/m;
22
+ /** Locate the absolute path of dist/bin/aegis.js. Reads from import.meta.url
23
+ * so it works no matter where the package is installed (global, local, link). */
24
+ function locateAegisBin() {
25
+ const here = fileURLToPath(import.meta.url);
26
+ // here = .../dist/install/claude-code.js
27
+ return resolve(dirname(here), "..", "bin", "aegis.js");
28
+ }
29
+ /** ~/.claude/ on all platforms (Claude Code uses the same path everywhere). */
30
+ function locateClaudeHome(override) {
31
+ if (override)
32
+ return override;
33
+ return resolve(homedir(), ".claude");
34
+ }
35
+ /** Locate ~/.claude.json — the user-scope MCP server config Claude Code reads. */
36
+ function locateClaudeMcpConfig() {
37
+ return resolve(homedir(), ".claude.json");
38
+ }
39
+ /** Atomic write: tmp file + rename. On Windows rename is mostly-atomic; good
40
+ * enough for config files since we always have a .bak alongside. The tmp
41
+ * suffix uses crypto.randomBytes (not for security; just collision-resistant
42
+ * unique naming on concurrent installs). */
43
+ function atomicWriteFile(filePath, content) {
44
+ mkdirSync(dirname(filePath), { recursive: true });
45
+ const tmp = `${filePath}.tmp-${Date.now()}-${randomBytes(3).toString("hex")}`;
46
+ writeFileSync(tmp, content, "utf8");
47
+ renameSync(tmp, filePath);
48
+ }
49
+ /** Backup an existing file as <file>.bak-dravix-<ts>. No-op if file missing. */
50
+ function backupFile(filePath) {
51
+ if (!existsSync(filePath))
52
+ return;
53
+ const bak = `${filePath}.bak-dravix-${Date.now()}`;
54
+ copyFileSync(filePath, bak);
55
+ }
56
+ /** Read JSON file, return parsed object or empty object on missing/bad json.
57
+ * We never throw — config files belong to the user and must round-trip safely. */
58
+ function readJsonSafe(filePath) {
59
+ if (!existsSync(filePath))
60
+ return {};
61
+ try {
62
+ const raw = readFileSync(filePath, "utf8");
63
+ const trimmed = raw.trim();
64
+ if (trimmed.length === 0)
65
+ return {};
66
+ const parsed = JSON.parse(trimmed);
67
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
68
+ return parsed;
69
+ }
70
+ return {};
71
+ }
72
+ catch {
73
+ return {};
74
+ }
75
+ }
76
+ /** Merge our aegis MCP server entry into ~/.claude.json without disturbing
77
+ * other servers. Returns the merged JSON string (pretty-printed). */
78
+ function mergeMcpConfig(existing, aegisBin) {
79
+ const out = { ...existing };
80
+ const servers = out.mcpServers && typeof out.mcpServers === "object" && !Array.isArray(out.mcpServers)
81
+ ? { ...out.mcpServers }
82
+ : {};
83
+ servers.aegis = {
84
+ type: "stdio",
85
+ command: process.execPath,
86
+ args: [aegisBin, "mcp"],
87
+ };
88
+ out.mcpServers = servers;
89
+ return JSON.stringify(out, null, 2) + "\n";
90
+ }
91
+ /** Merge our PreToolUse Write|Edit hook into ~/.claude/settings.json.
92
+ * Preserves other hooks (other matchers, other events). If our exact hook
93
+ * command already exists under the right matcher, we don't double-register. */
94
+ function mergeSettings(existing, aegisBin) {
95
+ const out = { ...existing };
96
+ const hooks = out.hooks ? { ...out.hooks } : {};
97
+ const pre = Array.isArray(hooks.PreToolUse) ? [...hooks.PreToolUse] : [];
98
+ const ourCmd = `${JSON.stringify(process.execPath)} ${JSON.stringify(aegisBin)} hook`;
99
+ // Match an existing aegis-hook entry (any path variant) so re-install
100
+ // upgrades it in place rather than appending a duplicate.
101
+ const isAegisHook = (h) => typeof h.command === "string" && /aegis(?:\.js)?["'\s]+hook(?:\b|$)/.test(h.command);
102
+ let foundMatcher = -1;
103
+ for (let i = 0; i < pre.length; i++) {
104
+ if (pre[i].matcher === "Write|Edit") {
105
+ foundMatcher = i;
106
+ break;
107
+ }
108
+ }
109
+ const aegisHook = { type: "command", command: ourCmd, timeout: 60 };
110
+ if (foundMatcher === -1) {
111
+ pre.push({ matcher: "Write|Edit", hooks: [aegisHook] });
112
+ }
113
+ else {
114
+ const existingHooks = Array.isArray(pre[foundMatcher].hooks) ? pre[foundMatcher].hooks : [];
115
+ const others = existingHooks.filter((h) => !isAegisHook(h));
116
+ pre[foundMatcher] = { matcher: "Write|Edit", hooks: [...others, aegisHook] };
117
+ }
118
+ hooks.PreToolUse = pre;
119
+ out.hooks = hooks;
120
+ return JSON.stringify(out, null, 2) + "\n";
121
+ }
122
+ /** The mandatory-validate block written into ~/.claude/CLAUDE.md.
123
+ * Marked with BEGIN/END comments so uninstall can strip it precisely. */
124
+ function claudeMdBlock() {
125
+ return `${BEGIN_MARKER}
126
+
127
+ # Dravix Agent — Real-Time Code Quality Guard (MANDATORY)
128
+
129
+ ## BLOCKING REQUIREMENT: Pre-Validate ALL Code
130
+
131
+ Before EVERY file write, edit, or creation, you MUST call the Dravix MCP tool \`validate_edit\`:
132
+
133
+ \`\`\`
134
+ mcp__aegis-v2__validate_edit(file_path="absolute/path", content="full file content")
135
+ \`\`\`
136
+
137
+ This is NOT optional. This is NOT a suggestion. This is a hard requirement.
138
+ If you skip this step, the code WILL contain bugs that could have been prevented.
139
+
140
+ ## Step-by-Step Workflow
141
+
142
+ 1. Compose the full post-edit content (for Edit: read the file, apply the swap)
143
+ 2. BEFORE applying the Write/Edit, call \`mcp__aegis-v2__validate_edit(file_path, content)\`
144
+ 3. If \`verdict === "block"\`:
145
+ a. Read the rule ID, line number, severity, remediation
146
+ b. Fix ALL findings
147
+ c. Re-call \`validate_edit\` with the fixed content
148
+ d. Repeat until \`verdict === "allow"\`
149
+ 4. ONLY THEN apply the Write/Edit
150
+ 5. End your response with a Validation Report
151
+
152
+ ## Available Dravix MCP Tools
153
+
154
+ | Tool | Use | When |
155
+ |---|---|---|
156
+ | \`mcp__aegis-v2__validate_edit(file_path, content)\` | Authoritative gate (allow/warn/block + findings) | EVERY Write/Edit |
157
+ | \`mcp__aegis-v2__precheck_change(file_path, content)\` | Fast advisory (<200ms, never blocks) | When deciding whether to attempt an edit |
158
+ | \`mcp__aegis-v2__explain_risk(finding_id OR file_path,line)\` | Look up prior gate decision | When investigating a past block |
159
+ | \`mcp__aegis-v2__aegis_health\` | Engine availability + cache stats | When diagnosing why a tool errored |
160
+
161
+ ## What Dravix Catches
162
+
163
+ - SQL injection, XSS, command injection, path traversal (CRITICAL)
164
+ - Hardcoded secrets, API keys, JWT signing keys (CRITICAL)
165
+ - \`eval()\`, \`exec()\`, \`os.system()\`, \`subprocess(shell=True)\`, pickle.loads (HIGH)
166
+ - Cross-file taint (caller-of-risky import + Joern CPG + Pysa)
167
+ - Race conditions (concurrency hint routing -> LLM critic)
168
+ - Logic bugs (Hypothesis property tests produce concrete counterexamples)
169
+ - Weak crypto (MD5 / SHA1 / Math.random for security)
170
+ - JWT misuse (alg:none, hardcoded secret, no algorithms set)
171
+ - Prompt injection in LLM apps, hardcoded LLM API keys
172
+ - 52+ deterministic rules across Python / JS / TS / multi-lang
173
+
174
+ ## MANDATORY: Validation Report (End of EVERY Response with Code Changes)
175
+
176
+ After completing ANY coding task, you MUST end your response with this exact format:
177
+
178
+ \`\`\`
179
+ ## Validation Report
180
+
181
+ **Issues prevented:** X issues caught and fixed before code was written
182
+ **Issues breakdown:**
183
+ - Critical: X (e.g., SQL injection in db.py:15 -> fixed with parameterized query)
184
+ - High: X (e.g., hardcoded API key in config.py:3 -> moved to env var)
185
+ - Medium: X
186
+ - Low: X
187
+
188
+ **What was caught:**
189
+ 1. [RULE-ID] file:line — what was wrong -> what was fixed
190
+ 2. [RULE-ID] file:line — description -> fix
191
+
192
+ **Verdicts:** orchestrator.ts -> allow, db.py -> block->fixed->allow
193
+ \`\`\`
194
+
195
+ If no issues were caught (all code passed on first try):
196
+
197
+ \`\`\`
198
+ ## Validation Report
199
+ All code passed validation on first attempt. Zero issues detected.
200
+ \`\`\`
201
+
202
+ ## NEVER Skip Validation
203
+
204
+ - Do NOT write code without calling \`validate_edit\` first
205
+ - Do NOT retry the same code that was rejected — fix it first
206
+ - Do NOT ignore warn-level findings — review and address
207
+ - Do NOT apologize for "extra steps" — this protects the user's codebase
208
+
209
+ ${END_MARKER}`;
210
+ }
211
+ /** Strip the legacy FixMe block (if present) and any prior dravix block,
212
+ * then append the fresh dravix block. Preserves all other user content. */
213
+ function injectClaudeMdBlock(existing) {
214
+ let out = existing;
215
+ let fixmeRemoved = false;
216
+ // Strip prior dravix block (BEGIN_MARKER ... END_MARKER, inclusive +
217
+ // surrounding blank lines).
218
+ const dravixBlock = new RegExp(`\\n*${escapeRe(BEGIN_MARKER)}[\\s\\S]*?${escapeRe(END_MARKER)}\\n*`, "g");
219
+ out = out.replace(dravixBlock, "\n");
220
+ // Strip legacy FixMe block, if present.
221
+ if (FIXME_HEADER_RE.test(out)) {
222
+ out = out.replace(FIXME_HEADER_RE, "");
223
+ fixmeRemoved = true;
224
+ }
225
+ // Trim trailing whitespace, then append our block + a trailing newline.
226
+ out = out.replace(/\s+$/, "");
227
+ if (out.length > 0)
228
+ out += "\n\n";
229
+ out += claudeMdBlock() + "\n";
230
+ return { content: out, fixmeRemoved };
231
+ }
232
+ function escapeRe(s) {
233
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
234
+ }
235
+ /** Public entry: register aegis in Claude Code. */
236
+ export function installClaudeCode(opts = {}) {
237
+ const aegisBin = locateAegisBin();
238
+ const claudeHome = locateClaudeHome(opts.claudeHome);
239
+ const mcpFile = locateClaudeMcpConfig();
240
+ const settingsFile = resolve(claudeHome, "settings.json");
241
+ const claudeMdFile = resolve(claudeHome, "CLAUDE.md");
242
+ const changes = [];
243
+ // 1. ~/.claude.json (MCP servers)
244
+ {
245
+ const before = existsSync(mcpFile) ? readFileSync(mcpFile, "utf8") : "";
246
+ const merged = mergeMcpConfig(readJsonSafe(mcpFile), aegisBin);
247
+ if (before.trim() === merged.trim()) {
248
+ changes.push({ file: mcpFile, op: "skip", reason: "aegis MCP already registered" });
249
+ }
250
+ else {
251
+ if (!opts.dryRun) {
252
+ backupFile(mcpFile);
253
+ atomicWriteFile(mcpFile, merged);
254
+ }
255
+ changes.push({
256
+ file: mcpFile,
257
+ op: existsSync(mcpFile) ? "modify" : "create",
258
+ reason: "added mcpServers.aegis",
259
+ before: before.slice(0, 800),
260
+ after: merged.slice(0, 800),
261
+ });
262
+ }
263
+ }
264
+ // 2. ~/.claude/settings.json (PreToolUse hook)
265
+ {
266
+ const before = existsSync(settingsFile) ? readFileSync(settingsFile, "utf8") : "";
267
+ const merged = mergeSettings(readJsonSafe(settingsFile), aegisBin);
268
+ if (before.trim() === merged.trim()) {
269
+ changes.push({ file: settingsFile, op: "skip", reason: "PreToolUse hook already registered" });
270
+ }
271
+ else {
272
+ if (!opts.dryRun) {
273
+ backupFile(settingsFile);
274
+ atomicWriteFile(settingsFile, merged);
275
+ }
276
+ changes.push({
277
+ file: settingsFile,
278
+ op: existsSync(settingsFile) ? "modify" : "create",
279
+ reason: "added PreToolUse Write|Edit hook",
280
+ before: before.slice(0, 800),
281
+ after: merged.slice(0, 800),
282
+ });
283
+ }
284
+ }
285
+ // 3. ~/.claude/CLAUDE.md (mandatory-validate block)
286
+ let fixmeBlockRemoved = false;
287
+ if (!opts.skipClaudeMd) {
288
+ const before = existsSync(claudeMdFile) ? readFileSync(claudeMdFile, "utf8") : "";
289
+ const { content: merged, fixmeRemoved } = injectClaudeMdBlock(before);
290
+ fixmeBlockRemoved = fixmeRemoved;
291
+ if (before === merged) {
292
+ changes.push({ file: claudeMdFile, op: "skip", reason: "Dravix block already present and current" });
293
+ }
294
+ else {
295
+ if (!opts.dryRun) {
296
+ backupFile(claudeMdFile);
297
+ atomicWriteFile(claudeMdFile, merged);
298
+ }
299
+ changes.push({
300
+ file: claudeMdFile,
301
+ op: existsSync(claudeMdFile) ? "modify" : "create",
302
+ reason: fixmeRemoved
303
+ ? "replaced legacy FixMe block with Dravix block"
304
+ : "added Dravix block",
305
+ });
306
+ }
307
+ }
308
+ return {
309
+ dryRun: opts.dryRun === true,
310
+ aegisBinPath: aegisBin,
311
+ claudeHome,
312
+ changes,
313
+ fixmeBlockRemoved,
314
+ };
315
+ }
316
+ /** Public entry: remove aegis from Claude Code. Idempotent. */
317
+ export function uninstallClaudeCode(opts = {}) {
318
+ const aegisBin = locateAegisBin();
319
+ const claudeHome = locateClaudeHome(opts.claudeHome);
320
+ const mcpFile = locateClaudeMcpConfig();
321
+ const settingsFile = resolve(claudeHome, "settings.json");
322
+ const claudeMdFile = resolve(claudeHome, "CLAUDE.md");
323
+ const changes = [];
324
+ // 1. ~/.claude.json — remove mcpServers.aegis
325
+ if (existsSync(mcpFile)) {
326
+ const data = readJsonSafe(mcpFile);
327
+ const servers = data.mcpServers && typeof data.mcpServers === "object" && !Array.isArray(data.mcpServers)
328
+ ? { ...data.mcpServers }
329
+ : null;
330
+ if (servers && "aegis" in servers) {
331
+ delete servers.aegis;
332
+ data.mcpServers = servers;
333
+ const merged = JSON.stringify(data, null, 2) + "\n";
334
+ if (!opts.dryRun) {
335
+ backupFile(mcpFile);
336
+ atomicWriteFile(mcpFile, merged);
337
+ }
338
+ changes.push({ file: mcpFile, op: "modify", reason: "removed mcpServers.aegis" });
339
+ }
340
+ else {
341
+ changes.push({ file: mcpFile, op: "skip", reason: "aegis MCP not registered" });
342
+ }
343
+ }
344
+ else {
345
+ changes.push({ file: mcpFile, op: "skip", reason: "file does not exist" });
346
+ }
347
+ // 2. ~/.claude/settings.json — remove our hook
348
+ if (existsSync(settingsFile)) {
349
+ const data = readJsonSafe(settingsFile);
350
+ const pre = Array.isArray(data.hooks?.PreToolUse) ? [...data.hooks.PreToolUse] : [];
351
+ let removed = false;
352
+ const cleaned = [];
353
+ for (const m of pre) {
354
+ if (!Array.isArray(m.hooks)) {
355
+ cleaned.push(m);
356
+ continue;
357
+ }
358
+ const filtered = m.hooks.filter((h) => {
359
+ const isOurs = typeof h.command === "string" && /aegis(?:\.js)?["'\s]+hook(?:\b|$)/.test(h.command);
360
+ if (isOurs)
361
+ removed = true;
362
+ return !isOurs;
363
+ });
364
+ if (filtered.length > 0)
365
+ cleaned.push({ ...m, hooks: filtered });
366
+ }
367
+ if (removed) {
368
+ if (cleaned.length > 0) {
369
+ data.hooks = { ...data.hooks, PreToolUse: cleaned };
370
+ }
371
+ else if (data.hooks) {
372
+ const h = { ...data.hooks };
373
+ delete h.PreToolUse;
374
+ data.hooks = h;
375
+ }
376
+ const merged = JSON.stringify(data, null, 2) + "\n";
377
+ if (!opts.dryRun) {
378
+ backupFile(settingsFile);
379
+ atomicWriteFile(settingsFile, merged);
380
+ }
381
+ changes.push({ file: settingsFile, op: "modify", reason: "removed PreToolUse aegis hook" });
382
+ }
383
+ else {
384
+ changes.push({ file: settingsFile, op: "skip", reason: "aegis hook not present" });
385
+ }
386
+ }
387
+ else {
388
+ changes.push({ file: settingsFile, op: "skip", reason: "file does not exist" });
389
+ }
390
+ // 3. ~/.claude/CLAUDE.md — strip Dravix block (leaves user content + legacy
391
+ // FixMe block, if any, untouched).
392
+ if (existsSync(claudeMdFile)) {
393
+ const before = readFileSync(claudeMdFile, "utf8");
394
+ const stripRe = new RegExp(`\\n*${escapeRe(BEGIN_MARKER)}[\\s\\S]*?${escapeRe(END_MARKER)}\\n*`, "g");
395
+ const after = before.replace(stripRe, "\n").replace(/\s+$/, "") + "\n";
396
+ if (after === before) {
397
+ changes.push({ file: claudeMdFile, op: "skip", reason: "no Dravix block to remove" });
398
+ }
399
+ else {
400
+ if (!opts.dryRun) {
401
+ backupFile(claudeMdFile);
402
+ atomicWriteFile(claudeMdFile, after);
403
+ }
404
+ changes.push({ file: claudeMdFile, op: "modify", reason: "removed Dravix block" });
405
+ }
406
+ }
407
+ else {
408
+ changes.push({ file: claudeMdFile, op: "skip", reason: "file does not exist" });
409
+ }
410
+ return {
411
+ dryRun: opts.dryRun === true,
412
+ aegisBinPath: aegisBin,
413
+ claudeHome,
414
+ changes,
415
+ fixmeBlockRemoved: false,
416
+ };
417
+ }
418
+ /** Human-readable summary for the CLI. */
419
+ export function formatReport(r) {
420
+ const lines = [];
421
+ lines.push(r.dryRun ? "(dry-run — no files written)" : "Done.");
422
+ lines.push("");
423
+ lines.push(`Aegis binary: ${r.aegisBinPath}`);
424
+ lines.push(`Claude home: ${r.claudeHome}`);
425
+ if (r.fixmeBlockRemoved) {
426
+ lines.push("Removed legacy FixMe block from CLAUDE.md.");
427
+ }
428
+ lines.push("");
429
+ lines.push("Changes:");
430
+ for (const c of r.changes) {
431
+ const op = c.op.padEnd(7);
432
+ lines.push(` ${op} ${c.file}`);
433
+ lines.push(` ${c.reason}`);
434
+ }
435
+ lines.push("");
436
+ if (!r.dryRun) {
437
+ lines.push("Next steps:");
438
+ lines.push(" 1. Restart Claude Code so it picks up the new MCP + hook.");
439
+ lines.push(" 2. Open a new conversation and try editing a file —");
440
+ lines.push(" the PreToolUse hook should fire, and Claude should");
441
+ lines.push(" proactively call mcp__aegis-v2__validate_edit.");
442
+ lines.push(" 3. Run `aegis doctor` to see which engines are live.");
443
+ lines.push(" 4. To remove later: `aegis uninstall`.");
444
+ }
445
+ return lines.join("\n");
446
+ }
447
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/install/claude-code.ts"],"names":[],"mappings":"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"}
package/dist/lang.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type Lang = "python" | "javascript" | "typescript" | "jsx" | "tsx" | "go" | "rust" | "java" | "ruby" | "php" | "c" | "cpp" | "csharp" | "shell" | "yaml" | "json" | "dockerfile" | "unknown";
2
+ export declare function detectLang(filePath: string): Lang;
3
+ /** Focus-language predicate — covers our primary engines */
4
+ export declare function isFocusLang(lang: Lang): boolean;
5
+ //# sourceMappingURL=lang.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lang.d.ts","sourceRoot":"","sources":["../src/lang.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,IAAI,GACZ,QAAQ,GACR,YAAY,GACZ,YAAY,GACZ,KAAK,GACL,KAAK,GACL,IAAI,GACJ,MAAM,GACN,MAAM,GACN,MAAM,GACN,KAAK,GACL,GAAG,GACH,KAAK,GACL,QAAQ,GACR,OAAO,GACP,MAAM,GACN,MAAM,GACN,YAAY,GACZ,SAAS,CAAC;AAyCd,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMjD;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE/C"}
package/dist/lang.js ADDED
@@ -0,0 +1,52 @@
1
+ /** Language detection from file extension. */
2
+ import { basename, extname } from "node:path";
3
+ const EXT_LANG = {
4
+ ".py": "python",
5
+ ".pyi": "python",
6
+ ".js": "javascript",
7
+ ".mjs": "javascript",
8
+ ".cjs": "javascript",
9
+ ".jsx": "jsx",
10
+ ".ts": "typescript",
11
+ ".tsx": "tsx",
12
+ ".mts": "typescript",
13
+ ".cts": "typescript",
14
+ ".go": "go",
15
+ ".rs": "rust",
16
+ ".java": "java",
17
+ ".rb": "ruby",
18
+ ".php": "php",
19
+ ".c": "c",
20
+ ".h": "c",
21
+ ".cpp": "cpp",
22
+ ".cc": "cpp",
23
+ ".cxx": "cpp",
24
+ ".hpp": "cpp",
25
+ ".cs": "csharp",
26
+ ".sh": "shell",
27
+ ".bash": "shell",
28
+ ".zsh": "shell",
29
+ ".yml": "yaml",
30
+ ".yaml": "yaml",
31
+ ".json": "json",
32
+ };
33
+ const FILENAME_LANG = {
34
+ Dockerfile: "dockerfile",
35
+ dockerfile: "dockerfile",
36
+ Makefile: "shell",
37
+ ".eslintrc.cjs": "javascript",
38
+ ".eslintrc.js": "javascript",
39
+ };
40
+ export function detectLang(filePath) {
41
+ const base = basename(filePath);
42
+ const byName = FILENAME_LANG[base];
43
+ if (byName)
44
+ return byName;
45
+ const ext = extname(filePath).toLowerCase();
46
+ return EXT_LANG[ext] ?? "unknown";
47
+ }
48
+ /** Focus-language predicate — covers our primary engines */
49
+ export function isFocusLang(lang) {
50
+ return ["python", "javascript", "typescript", "jsx", "tsx", "go"].includes(lang);
51
+ }
52
+ //# sourceMappingURL=lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lang.js","sourceRoot":"","sources":["../src/lang.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsB9C,MAAM,QAAQ,GAAmC;IAC/C,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;CAChB,CAAC;AAEF,MAAM,aAAa,GAAmC;IACpD,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,OAAO;IACjB,eAAe,EAAE,YAAY;IAC7B,cAAc,EAAE,YAAY;CAC7B,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;AACpC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { z } from "zod";
2
+ declare const SuppressionEntry: z.ZodObject<{
3
+ op: z.ZodEnum<["add", "remove"]>;
4
+ id: z.ZodString;
5
+ ts: z.ZodString;
6
+ reason: z.ZodOptional<z.ZodString>;
7
+ expires_at: z.ZodOptional<z.ZodString>;
8
+ who: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ id: string;
11
+ op: "add" | "remove";
12
+ ts: string;
13
+ reason?: string | undefined;
14
+ expires_at?: string | undefined;
15
+ who?: string | undefined;
16
+ }, {
17
+ id: string;
18
+ op: "add" | "remove";
19
+ ts: string;
20
+ reason?: string | undefined;
21
+ expires_at?: string | undefined;
22
+ who?: string | undefined;
23
+ }>;
24
+ export type SuppressionEntry = z.infer<typeof SuppressionEntry>;
25
+ export interface ActiveSuppression {
26
+ id: string;
27
+ added_at: string;
28
+ reason?: string;
29
+ expires_at?: string;
30
+ who?: string;
31
+ }
32
+ export declare function suppressionsPath(projectRoot: string): string;
33
+ export interface SuppressOptions {
34
+ reason?: string;
35
+ expiresAt?: string;
36
+ who?: string;
37
+ }
38
+ /** Add an `add` event to the log. Idempotent — adding an already-active
39
+ * suppression is a no-op log entry (we still append for audit). */
40
+ export declare function suppress(projectRoot: string, findingId: string, opts?: SuppressOptions): {
41
+ ok: true;
42
+ entry: SuppressionEntry;
43
+ } | {
44
+ ok: false;
45
+ reason: string;
46
+ };
47
+ /** Add a `remove` event — the finding will be ALLOWED through again on
48
+ * the next gate run. */
49
+ export declare function unsuppress(projectRoot: string, findingId: string, opts?: {
50
+ who?: string;
51
+ reason?: string;
52
+ }): {
53
+ ok: true;
54
+ entry: SuppressionEntry;
55
+ } | {
56
+ ok: false;
57
+ reason: string;
58
+ };
59
+ /** Return the currently-active suppressions (folded from the append log,
60
+ * with expired entries dropped). O(1) hit on the per-project cache when
61
+ * the log mtime hasn't changed since the last call. */
62
+ export declare function listActive(projectRoot: string): ActiveSuppression[];
63
+ /** Fast O(1) check used by the orchestrator. Returns true iff the finding
64
+ * id is currently suppressed (added + not removed + not expired). */
65
+ export declare function isSuppressed(projectRoot: string, findingId: string): boolean;
66
+ /** Test-only — wipe the in-memory cache so a test can re-read after
67
+ * writing fresh entries. */
68
+ export declare function _resetActiveCacheForTests(): void;
69
+ export {};
70
+ //# sourceMappingURL=suppressions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/learning/suppressions.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAOpB,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAYD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AASD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;mEACmE;AACnE,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,eAAe,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAavE;AAED;wBACwB;AACxB,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAYvE;AAoBD;;uDAEuD;AACvD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAEnE;AAED;qEACqE;AACrE,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5E;AA6DD;4BAC4B;AAC5B,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}