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,73 @@
1
+ /**
2
+ * `validate_edit` — authoritative gate (PostToolUse).
3
+ *
4
+ * Uses the MCP warm fast-path:
5
+ * 1. in-mem verdict LRU lookup (sub-millisecond on hit)
6
+ * 2. single-flight dedup for concurrent identical scans
7
+ * 3. fresh runGate() with precomputed engine availability
8
+ */
9
+ import { z } from "zod";
10
+ export declare const validateEditInputSchema: z.ZodObject<{
11
+ file_path: z.ZodString;
12
+ content: z.ZodString;
13
+ project_root: z.ZodOptional<z.ZodString>;
14
+ /** Override engines (rare — for tests). */
15
+ engines: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ file_path: string;
18
+ content: string;
19
+ project_root?: string | undefined;
20
+ engines?: string[] | undefined;
21
+ }, {
22
+ file_path: string;
23
+ content: string;
24
+ project_root?: string | undefined;
25
+ engines?: string[] | undefined;
26
+ }>;
27
+ export type ValidateEditInput = z.infer<typeof validateEditInputSchema>;
28
+ export interface ValidateEditOutput {
29
+ verdict: "allow" | "warn" | "block";
30
+ summary: string;
31
+ duration_ms: number;
32
+ truncated: boolean;
33
+ /** Origin of the verdict — "lru" = in-mem cache hit (sub-ms),
34
+ * "fresh" = full gate run. Useful for clients to display "cached" badges. */
35
+ cache_source: "lru" | "single-flight" | "fresh";
36
+ findings: Array<{
37
+ id: string;
38
+ engine: string;
39
+ rule_id: string;
40
+ file: string;
41
+ line?: number;
42
+ col?: number;
43
+ cwe?: string;
44
+ severity: string;
45
+ confidence: number;
46
+ message: string;
47
+ remediation?: string;
48
+ }>;
49
+ /** Phase-1 sidecar: cross-file evidence (definitions of imports + callers).
50
+ * Present iff a SCIP index exists for the project. */
51
+ project_context?: {
52
+ available: boolean;
53
+ languages: string[];
54
+ imported_definitions: Array<{
55
+ symbol: string;
56
+ kind: string;
57
+ file: string;
58
+ line: number;
59
+ snippet?: string;
60
+ }>;
61
+ callers: Array<{
62
+ symbol: string;
63
+ callers: Array<{
64
+ file: string;
65
+ line: number;
66
+ }>;
67
+ }>;
68
+ duration_ms: number;
69
+ };
70
+ remediation_prompt?: string;
71
+ }
72
+ export declare function runValidateEdit(input: ValidateEditInput): Promise<ValidateEditOutput>;
73
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,uBAAuB;;;;IAIlC,2CAA2C;;;;;;;;;;;;EAE3C,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB;iFAC6E;IAC7E,YAAY,EAAE,KAAK,GAAG,eAAe,GAAG,OAAO,CAAC;IAChD,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH;0DACsD;IACtD,eAAe,CAAC,EAAE;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,oBAAoB,EAAE,KAAK,CAAC;YAC1B,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC;SAC5E,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAChE,CAAC,CAAC;QACH,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoC3F"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * `validate_edit` — authoritative gate (PostToolUse).
3
+ *
4
+ * Uses the MCP warm fast-path:
5
+ * 1. in-mem verdict LRU lookup (sub-millisecond on hit)
6
+ * 2. single-flight dedup for concurrent identical scans
7
+ * 3. fresh runGate() with precomputed engine availability
8
+ */
9
+ import { z } from "zod";
10
+ import { runGateFast } from "../warm.js";
11
+ export const validateEditInputSchema = z.object({
12
+ file_path: z.string().min(1),
13
+ content: z.string(),
14
+ project_root: z.string().optional(),
15
+ /** Override engines (rare — for tests). */
16
+ engines: z.array(z.string()).optional(),
17
+ });
18
+ export async function runValidateEdit(input) {
19
+ const { report, source } = await runGateFast({
20
+ filePath: input.file_path,
21
+ content: input.content,
22
+ ...(input.project_root !== undefined ? { projectRoot: input.project_root } : {}),
23
+ });
24
+ const findings = report.findings.map((f) => ({
25
+ id: f.id,
26
+ engine: f.engine,
27
+ rule_id: f.rule_id,
28
+ file: f.file,
29
+ ...(f.line !== undefined ? { line: f.line } : {}),
30
+ ...(f.col !== undefined ? { col: f.col } : {}),
31
+ ...(f.cwe !== undefined ? { cwe: f.cwe } : {}),
32
+ severity: f.severity,
33
+ confidence: f.confidence,
34
+ message: f.message,
35
+ ...(f.remediation !== undefined ? { remediation: f.remediation } : {}),
36
+ }));
37
+ const out = {
38
+ verdict: report.decision.action,
39
+ summary: report.decision.summary,
40
+ duration_ms: report.durationMs,
41
+ truncated: report.truncated,
42
+ cache_source: source,
43
+ findings,
44
+ };
45
+ if (report.projectContext) {
46
+ out.project_context = report.projectContext;
47
+ }
48
+ if (report.decision.action === "block") {
49
+ out.remediation_prompt = formatRemediation(report.filePath, findings.slice(0, 5));
50
+ }
51
+ return out;
52
+ }
53
+ function formatRemediation(filePath, top) {
54
+ const lines = [];
55
+ lines.push(`The proposed write to ${filePath} was blocked by Aegis. Fix:`);
56
+ for (const f of top) {
57
+ const loc = f.line ? `:${f.line}` : "";
58
+ const cwe = f.cwe ? ` [${f.cwe}]` : "";
59
+ lines.push(`- ${f.engine}/${f.rule_id}${cwe} at ${f.file}${loc} — ${f.message}`);
60
+ if (f.remediation)
61
+ lines.push(` fix: ${f.remediation}`);
62
+ }
63
+ lines.push("Regenerate the file applying all the items above, then save again.");
64
+ return lines.join("\n");
65
+ }
66
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/mcp/tools/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import type { Engine } from "../engines/types.js";
2
+ import { type GateInput, type GateReport } from "../orchestrator.js";
3
+ declare class VerdictLru {
4
+ private readonly cap;
5
+ private readonly ttlMs;
6
+ private readonly map;
7
+ private hits;
8
+ private misses;
9
+ private evictions;
10
+ constructor(cap: number, ttlMs: number);
11
+ get(key: string): GateReport | undefined;
12
+ put(key: string, report: GateReport): void;
13
+ size(): number;
14
+ stats(): {
15
+ hits: number;
16
+ misses: number;
17
+ evictions: number;
18
+ size: number;
19
+ cap: number;
20
+ };
21
+ clear(): void;
22
+ }
23
+ /** sha256 of the full input that determines verdict identity. Same key →
24
+ * same verdict iff our engines and policy haven't changed (we DON'T cache
25
+ * across policy edits — see notes at the call site). */
26
+ export declare function verdictCacheKey(input: GateInput, engineSetTag: string): string;
27
+ /** De-dup concurrent identical scans. Two agents calling ``validate_edit``
28
+ * with the same content at the same instant share ONE underlying gate
29
+ * run; the second callee awaits the same promise. Frees the system from
30
+ * O(N) LLM-critic calls under burst load. */
31
+ export declare function singleFlight(key: string, fn: () => Promise<GateReport>): Promise<GateReport>;
32
+ /** Probe every engine ONCE at boot. Subsequent runGate() calls can rely
33
+ * on this map instead of awaiting `e.available()` per engine per call. */
34
+ export declare function computeAvailability(): Promise<Map<string, boolean>>;
35
+ /** Get the precomputed availability snapshot. Returns null before
36
+ * ``warmAtBoot()`` completes. Callers SHOULD fall back to per-engine
37
+ * ``e.available()`` if null. */
38
+ export declare function availabilitySnapshot(): Map<string, boolean> | null;
39
+ /** Force a fresh probe (e.g. user just ran `pip install semgrep` mid-session). */
40
+ export declare function refreshAvailability(): Promise<Map<string, boolean>>;
41
+ interface WarmState {
42
+ warmedAt: number;
43
+ durationMs: number;
44
+ vulRagOk: boolean;
45
+ vulRagEntries: number;
46
+ engineCount: number;
47
+ engineAvailable: number;
48
+ claudeBin: string | null;
49
+ }
50
+ /** Eagerly load every subsystem that the hook path lazy-loads. Idempotent.
51
+ * Returns the cached state if already warmed. Concurrent callers share
52
+ * the same in-flight warm promise. */
53
+ export declare function warmAtBoot(): Promise<WarmState>;
54
+ /** Snapshot of warm state for ``aegis.health`` probe / debug. */
55
+ export declare function warmStateSnapshot(): WarmState | null;
56
+ /** Run the gate with full warm-path optimisation:
57
+ *
58
+ * 1. In-memory LRU lookup (returns in <0.2 ms when hit).
59
+ * 2. Single-flight dedup: if another call is in flight for the same key,
60
+ * wait for it instead of starting a parallel one.
61
+ * 3. Forward to ``runGate``, passing the warm availability snapshot so
62
+ * the orchestrator skips per-call ``e.available()`` awaits.
63
+ * 4. Store the resulting report in the LRU.
64
+ *
65
+ * Non-cacheable scans (``noCache: true``) bypass steps 1-2-4 — used by
66
+ * the precheck path which always wants fresh.
67
+ */
68
+ export declare function runGateFast(input: GateInput): Promise<{
69
+ report: GateReport;
70
+ source: "lru" | "single-flight" | "fresh";
71
+ }>;
72
+ export declare function warmMetrics(): {
73
+ verdict_lru: ReturnType<VerdictLru["stats"]>;
74
+ inflight: number;
75
+ engine_set_tag: string;
76
+ warm: WarmState | null;
77
+ };
78
+ /** Reset all warm state. Tests only — production code must NOT call this. */
79
+ export declare function _resetWarmStateForTests(): void;
80
+ /** Expose internal hooks for unit tests. */
81
+ export declare const _testing: {
82
+ verdictLru: VerdictLru;
83
+ inflight: Map<string, Promise<GateReport>>;
84
+ ENGINE_SET_TAG: string;
85
+ engineSet: () => ReadonlyArray<Engine>;
86
+ };
87
+ export {};
88
+ //# sourceMappingURL=warm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warm.d.ts","sourceRoot":"","sources":["../../src/mcp/warm.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AA6B9E,cAAM,UAAU;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmC;IACvD,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAK;gBAEV,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAKtC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAkBxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAW1C,IAAI,IAAI,MAAM;IAId,KAAK,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAUvF,KAAK,IAAI,IAAI;CAMd;AAID;;wDAEwD;AACxD,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAW9E;AAMD;;;6CAG6C;AAC7C,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC,CAYrB;AAMD;0EAC0E;AAC1E,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiBzE;AAED;;gCAEgC;AAChC,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAElE;AAED,kFAAkF;AAClF,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEzE;AAID,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA8BD;;sCAEsC;AACtC,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CA2DrD;AAED,iEAAiE;AACjE,wBAAgB,iBAAiB,IAAI,SAAS,GAAG,IAAI,CAEpD;AAYD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;IAC3D,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,KAAK,GAAG,eAAe,GAAG,OAAO,CAAC;CAC3C,CAAC,CA+BD;AAID,wBAAgB,WAAW,IAAI;IAC7B,WAAW,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;CACxB,CAOA;AAID,6EAA6E;AAC7E,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,4CAA4C;AAC5C,eAAO,MAAM,QAAQ;;;;qBAIJ,aAAa,CAAC,MAAM,CAAC;CACrC,CAAC"}
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Process-wide warm state for the MCP server.
3
+ *
4
+ * The aegis hook CLI pays full cold-start cost on every invocation
5
+ * (Vul-RAG KB embed, engine availability probes, LMDB open, claude
6
+ * binary discovery). For an interactive realtime gate this is
7
+ * unacceptable — a single fresh process is ~2-3 s before any actual
8
+ * scan work begins.
9
+ *
10
+ * The MCP server is long-running by design (stdio transport stays
11
+ * open for the entire IDE session). This module owns the state that
12
+ * needs to be hot from the very first tool call:
13
+ *
14
+ * - Vul-RAG: KB + embeddings loaded eagerly at boot.
15
+ * - SCIP indexer singleton: created (its real work is lazy
16
+ * per-project, but the singleton exists).
17
+ * - Claude binary discovery: ``which("claude")`` cached.
18
+ * - Per-engine availability map: computed once at boot, refreshed
19
+ * manually via ``refreshAvailability()`` if engines are
20
+ * installed during the session.
21
+ * - Verdict LRU keyed on (engine-set hash, sha256(content)): a
22
+ * sub-millisecond cache layer above LMDB. Hits return without
23
+ * touching disk.
24
+ * - Single-flight dedup: two concurrent identical scans share one
25
+ * in-flight ``runGate`` promise. Prevents N×LLM-critic blow-up
26
+ * when an agent fans out edits.
27
+ *
28
+ * The warm contract is opt-in — callers must `await warmAtBoot()`
29
+ * before the server's first tool call. ``server.ts`` does this
30
+ * before ``transport.connect()``.
31
+ */
32
+ import { createHash } from "node:crypto";
33
+ import { ALL_ENGINES, ENGINES, STAGE2_ENGINES } from "../engines/registry.js";
34
+ import { getIndexer } from "../index/scip.js";
35
+ import { getVulRag } from "../index/vulrag.js";
36
+ import { runGate } from "../orchestrator.js";
37
+ import { getLogger } from "../util/logger.js";
38
+ import { which } from "../util/subprocess.js";
39
+ const log = getLogger("aegis.mcp.warm");
40
+ // ── Tunables ──────────────────────────────────────────────────────────────
41
+ /** Max verdicts retained in-process. 2k × ~5KB/verdict ≈ 10 MB worst case. */
42
+ const VERDICT_LRU_CAP = Number(process.env.AEGIS_MCP_VERDICT_LRU ?? 2000);
43
+ /** Soft time after which an in-mem verdict is re-validated against LMDB.
44
+ * Same content + same engine set → invariant verdict, so we can hold for
45
+ * a full coding session (8 h). */
46
+ const VERDICT_LRU_TTL_MS = Number(process.env.AEGIS_MCP_VERDICT_TTL_MS ?? 8 * 60 * 60 * 1000);
47
+ /** Per-call timeout for the boot warm-up of each subsystem. Vul-RAG
48
+ * embed of 60 entries on cold CPU is ~600 ms; SCIP indexer construction is
49
+ * trivial; ``which`` is <5 ms. 30 s is a generous upper bound that still
50
+ * fails fast if something is wedged. */
51
+ const WARM_PER_SUBSYSTEM_TIMEOUT_MS = 30_000;
52
+ class VerdictLru {
53
+ cap;
54
+ ttlMs;
55
+ map = new Map();
56
+ hits = 0;
57
+ misses = 0;
58
+ evictions = 0;
59
+ constructor(cap, ttlMs) {
60
+ this.cap = cap;
61
+ this.ttlMs = ttlMs;
62
+ }
63
+ get(key) {
64
+ const e = this.map.get(key);
65
+ if (!e) {
66
+ this.misses++;
67
+ return undefined;
68
+ }
69
+ if (Date.now() - e.storedAt > this.ttlMs) {
70
+ this.map.delete(key);
71
+ this.misses++;
72
+ return undefined;
73
+ }
74
+ // Move-to-end = recency bump.
75
+ this.map.delete(key);
76
+ this.map.set(key, e);
77
+ this.hits++;
78
+ return e.report;
79
+ }
80
+ put(key, report) {
81
+ if (this.map.has(key))
82
+ this.map.delete(key);
83
+ this.map.set(key, { report, storedAt: Date.now() });
84
+ while (this.map.size > this.cap) {
85
+ const oldest = this.map.keys().next().value;
86
+ if (oldest === undefined)
87
+ break;
88
+ this.map.delete(oldest);
89
+ this.evictions++;
90
+ }
91
+ }
92
+ size() {
93
+ return this.map.size;
94
+ }
95
+ stats() {
96
+ return {
97
+ hits: this.hits,
98
+ misses: this.misses,
99
+ evictions: this.evictions,
100
+ size: this.map.size,
101
+ cap: this.cap,
102
+ };
103
+ }
104
+ clear() {
105
+ this.map.clear();
106
+ this.hits = 0;
107
+ this.misses = 0;
108
+ this.evictions = 0;
109
+ }
110
+ }
111
+ const verdictLru = new VerdictLru(VERDICT_LRU_CAP, VERDICT_LRU_TTL_MS);
112
+ /** sha256 of the full input that determines verdict identity. Same key →
113
+ * same verdict iff our engines and policy haven't changed (we DON'T cache
114
+ * across policy edits — see notes at the call site). */
115
+ export function verdictCacheKey(input, engineSetTag) {
116
+ const h = createHash("sha256");
117
+ h.update(engineSetTag);
118
+ h.update("\0");
119
+ h.update(input.filePath);
120
+ h.update("\0");
121
+ // projectRoot affects findings via policy + suppressions + SCIP context.
122
+ h.update(input.projectRoot ?? "");
123
+ h.update("\0");
124
+ h.update(input.content);
125
+ return h.digest("hex").slice(0, 32);
126
+ }
127
+ // ── Single-flight ─────────────────────────────────────────────────────────
128
+ const inflight = new Map();
129
+ /** De-dup concurrent identical scans. Two agents calling ``validate_edit``
130
+ * with the same content at the same instant share ONE underlying gate
131
+ * run; the second callee awaits the same promise. Frees the system from
132
+ * O(N) LLM-critic calls under burst load. */
133
+ export async function singleFlight(key, fn) {
134
+ const existing = inflight.get(key);
135
+ if (existing) {
136
+ return existing;
137
+ }
138
+ const p = fn().finally(() => {
139
+ // Detach AFTER resolution so a follow-up call that arrives 1ms later
140
+ // doesn't latch onto a not-yet-cleared entry expecting fresh data.
141
+ inflight.delete(key);
142
+ });
143
+ inflight.set(key, p);
144
+ return p;
145
+ }
146
+ // ── Engine availability map ───────────────────────────────────────────────
147
+ let _availabilityMap = null;
148
+ /** Probe every engine ONCE at boot. Subsequent runGate() calls can rely
149
+ * on this map instead of awaiting `e.available()` per engine per call. */
150
+ export async function computeAvailability() {
151
+ const m = new Map();
152
+ const checks = ALL_ENGINES.map(async (e) => {
153
+ try {
154
+ m.set(e.name, await e.available());
155
+ }
156
+ catch {
157
+ m.set(e.name, false);
158
+ }
159
+ });
160
+ await Promise.all(checks);
161
+ _availabilityMap = m;
162
+ log.info("availability probed", {
163
+ total: m.size,
164
+ available: [...m.entries()].filter(([, ok]) => ok).map(([n]) => n),
165
+ unavailable: [...m.entries()].filter(([, ok]) => !ok).map(([n]) => n),
166
+ });
167
+ return m;
168
+ }
169
+ /** Get the precomputed availability snapshot. Returns null before
170
+ * ``warmAtBoot()`` completes. Callers SHOULD fall back to per-engine
171
+ * ``e.available()`` if null. */
172
+ export function availabilitySnapshot() {
173
+ return _availabilityMap;
174
+ }
175
+ /** Force a fresh probe (e.g. user just ran `pip install semgrep` mid-session). */
176
+ export async function refreshAvailability() {
177
+ return computeAvailability();
178
+ }
179
+ let _warmState = null;
180
+ let _warmPromise = null;
181
+ /** Unique sentinel for timeout — using a Symbol avoids confusing the
182
+ * "step succeeded but returned null/undefined" case with "step timed out". */
183
+ const TIMEOUT_SENTINEL = Symbol("warm.timeout");
184
+ async function withDeadline(label, ms, fn) {
185
+ const deadline = new Promise((r) => setTimeout(() => r(TIMEOUT_SENTINEL), ms));
186
+ try {
187
+ const res = await Promise.race([fn(), deadline]);
188
+ if (res === TIMEOUT_SENTINEL) {
189
+ log.warn(`warm step timed out`, { step: label, timeoutMs: ms });
190
+ }
191
+ return res;
192
+ }
193
+ catch (err) {
194
+ log.warn(`warm step failed`, { step: label, err: String(err) });
195
+ return TIMEOUT_SENTINEL;
196
+ }
197
+ }
198
+ /** Eagerly load every subsystem that the hook path lazy-loads. Idempotent.
199
+ * Returns the cached state if already warmed. Concurrent callers share
200
+ * the same in-flight warm promise. */
201
+ export async function warmAtBoot() {
202
+ if (_warmState)
203
+ return _warmState;
204
+ if (_warmPromise)
205
+ return _warmPromise;
206
+ const t0 = Date.now();
207
+ _warmPromise = (async () => {
208
+ log.info("warm-at-boot starting", {
209
+ stage1Engines: ENGINES.map((e) => e.name),
210
+ stage2Engines: STAGE2_ENGINES.map((e) => e.name),
211
+ });
212
+ // 1. Engine availability — parallel, fail-safe per engine inside.
213
+ const avail = await withDeadline("availability", WARM_PER_SUBSYSTEM_TIMEOUT_MS, () => computeAvailability());
214
+ const availMap = avail === TIMEOUT_SENTINEL ? new Map() : avail;
215
+ const availCount = [...availMap.values()].filter(Boolean).length;
216
+ // 2. Vul-RAG KB embed (this is the dominant cost — ~0.6-1.5 s cold).
217
+ let vulRagOk = false;
218
+ let vulRagEntries = 0;
219
+ await withDeadline("vulrag", WARM_PER_SUBSYSTEM_TIMEOUT_MS, async () => {
220
+ const rag = getVulRag();
221
+ vulRagOk = await rag.ensureLoaded();
222
+ vulRagEntries = rag.size;
223
+ return null;
224
+ });
225
+ // 3. SCIP indexer singleton — construction is cheap; per-project work
226
+ // is still lazy. We just want the singleton extant so the first
227
+ // runGate() doesn't pay a Map+Cache construction cost.
228
+ await withDeadline("scip-indexer", 2_000, async () => {
229
+ getIndexer();
230
+ return null;
231
+ });
232
+ // 4. Claude binary discovery — `which()` itself is cached, but the
233
+ // first lookup spawns a subprocess on Windows.
234
+ let claudeBin = null;
235
+ await withDeadline("claude-bin", 5_000, async () => {
236
+ claudeBin = await which("claude");
237
+ return null;
238
+ });
239
+ const state = {
240
+ warmedAt: Date.now(),
241
+ durationMs: Date.now() - t0,
242
+ vulRagOk,
243
+ vulRagEntries,
244
+ engineCount: ALL_ENGINES.length,
245
+ engineAvailable: availCount,
246
+ claudeBin,
247
+ };
248
+ _warmState = state;
249
+ log.info("warm-at-boot complete", { ...state });
250
+ return state;
251
+ })();
252
+ return _warmPromise;
253
+ }
254
+ /** Snapshot of warm state for ``aegis.health`` probe / debug. */
255
+ export function warmStateSnapshot() {
256
+ return _warmState;
257
+ }
258
+ // ── Gate fast-path ────────────────────────────────────────────────────────
259
+ /** Build a stable tag identifying the current engine set so the verdict
260
+ * cache invalidates correctly if an engine is added/removed between
261
+ * server restarts. Computed once per process. */
262
+ const ENGINE_SET_TAG = (() => {
263
+ const names = ALL_ENGINES.map((e) => e.name).sort();
264
+ return createHash("sha256").update(names.join("|")).digest("hex").slice(0, 12);
265
+ })();
266
+ /** Run the gate with full warm-path optimisation:
267
+ *
268
+ * 1. In-memory LRU lookup (returns in <0.2 ms when hit).
269
+ * 2. Single-flight dedup: if another call is in flight for the same key,
270
+ * wait for it instead of starting a parallel one.
271
+ * 3. Forward to ``runGate``, passing the warm availability snapshot so
272
+ * the orchestrator skips per-call ``e.available()`` awaits.
273
+ * 4. Store the resulting report in the LRU.
274
+ *
275
+ * Non-cacheable scans (``noCache: true``) bypass steps 1-2-4 — used by
276
+ * the precheck path which always wants fresh.
277
+ */
278
+ export async function runGateFast(input) {
279
+ // Inject the warm availability snapshot into every gate call so the
280
+ // orchestrator doesn't await per-engine availability. If warmAtBoot
281
+ // hasn't completed yet (e.g. someone called runGateFast before await),
282
+ // the override is null and the orchestrator falls back to per-call probes.
283
+ const inputWithOverride = {
284
+ ...input,
285
+ ...(_availabilityMap ? { availabilityOverride: _availabilityMap } : {}),
286
+ };
287
+ if (input.noCache) {
288
+ const report = await runGate(inputWithOverride);
289
+ return { report, source: "fresh" };
290
+ }
291
+ const key = verdictCacheKey(input, ENGINE_SET_TAG);
292
+ const hit = verdictLru.get(key);
293
+ if (hit) {
294
+ return { report: hit, source: "lru" };
295
+ }
296
+ // Note on label correctness: we can't distinguish "original runner"
297
+ // from "joined an in-flight peer" from inside singleFlight() without
298
+ // a check-and-set racey lookup. We label "fresh" uniformly because
299
+ // the LRU put below STILL happens (idempotent — the joined caller
300
+ // re-puts the same report). Telemetry on actual single-flight hits
301
+ // is exposed via warmMetrics().inflight watermark.
302
+ const report = await singleFlight(key, async () => runGate(inputWithOverride));
303
+ verdictLru.put(key, report);
304
+ return { report, source: "fresh" };
305
+ }
306
+ // ── Metrics (for explain_health / debug) ──────────────────────────────────
307
+ export function warmMetrics() {
308
+ return {
309
+ verdict_lru: verdictLru.stats(),
310
+ inflight: inflight.size,
311
+ engine_set_tag: ENGINE_SET_TAG,
312
+ warm: _warmState,
313
+ };
314
+ }
315
+ // ── Test-only helpers ─────────────────────────────────────────────────────
316
+ /** Reset all warm state. Tests only — production code must NOT call this. */
317
+ export function _resetWarmStateForTests() {
318
+ _warmState = null;
319
+ _warmPromise = null;
320
+ _availabilityMap = null;
321
+ verdictLru.clear();
322
+ inflight.clear();
323
+ }
324
+ /** Expose internal hooks for unit tests. */
325
+ export const _testing = {
326
+ verdictLru,
327
+ inflight,
328
+ ENGINE_SET_TAG,
329
+ engineSet: () => ALL_ENGINES,
330
+ };
331
+ //# sourceMappingURL=warm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warm.js","sourceRoot":"","sources":["../../src/mcp/warm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { Engine, EngineRunResult } from "./engines/types.js";
2
+ import { Finding } from "./findings.js";
3
+ import { type ProjectContextBlock } from "./index/context.js";
4
+ import { Lang } from "./lang.js";
5
+ import { ActionDecision } from "./risk.js";
6
+ export interface GateInput {
7
+ filePath: string;
8
+ content: string;
9
+ projectRoot?: string;
10
+ /** Overall budget; default 5_000 ms. */
11
+ totalTimeoutMs?: number;
12
+ /** Override which engines run; default = all available. */
13
+ engines?: ReadonlyArray<Engine>;
14
+ /** Disable caching (tests). */
15
+ noCache?: boolean;
16
+ /** If false, the path safety check WILL NOT reject files that are
17
+ * outside ``projectRoot``. Used by the ad-hoc ``aegis scan`` CLI where
18
+ * the user explicitly chose the file. Hook path leaves it default (true). */
19
+ enforceContainment?: boolean;
20
+ /** Precomputed engine availability map. When supplied, the orchestrator
21
+ * SKIPS the per-call ``await e.available()`` round-trip — used by the
22
+ * MCP server warm path where availability is probed once at boot. Engines
23
+ * NOT present in the map fall back to per-call probing. Engines present
24
+ * with ``false`` are skipped without re-probing. */
25
+ availabilityOverride?: ReadonlyMap<string, boolean>;
26
+ }
27
+ export interface GateReport {
28
+ filePath: string;
29
+ lang: Lang;
30
+ decision: ActionDecision;
31
+ findings: Finding[];
32
+ engineResults: ReadonlyArray<EngineRunResult>;
33
+ durationMs: number;
34
+ truncated: boolean;
35
+ pathCheck: {
36
+ ok: true;
37
+ resolved: string;
38
+ } | {
39
+ ok: false;
40
+ reason: string;
41
+ };
42
+ /** Cross-file evidence assembled from the SCIP index, if available. */
43
+ projectContext?: ProjectContextBlock;
44
+ }
45
+ export declare function runGate(input: GateInput): Promise<GateReport>;
46
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,MAAM,EAAkB,eAAe,EAAW,MAAM,oBAAoB,CAAC;AAEtF,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAuB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKnF,OAAO,EAAc,IAAI,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAU,MAAM,WAAW,CAAC;AAMnD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;iFAE6E;IAC7E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;wDAIoD;IACpD,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EACL;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAC9B;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,uEAAuE;IACvE,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAqKD,wBAAsB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA8WnE"}