kuzushi 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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/dist/agent-runtime/claude.d.ts +8 -0
  4. package/dist/agent-runtime/claude.js +124 -0
  5. package/dist/agent-runtime/claude.js.map +1 -0
  6. package/dist/agent-runtime/index.d.ts +9 -0
  7. package/dist/agent-runtime/index.js +31 -0
  8. package/dist/agent-runtime/index.js.map +1 -0
  9. package/dist/agent-runtime/model-spec.d.ts +8 -0
  10. package/dist/agent-runtime/model-spec.js +17 -0
  11. package/dist/agent-runtime/model-spec.js.map +1 -0
  12. package/dist/agent-runtime/pi-ai.d.ts +8 -0
  13. package/dist/agent-runtime/pi-ai.js +365 -0
  14. package/dist/agent-runtime/pi-ai.js.map +1 -0
  15. package/dist/agent-runtime/tools.d.ts +3 -0
  16. package/dist/agent-runtime/tools.js +330 -0
  17. package/dist/agent-runtime/tools.js.map +1 -0
  18. package/dist/agent-runtime/types.d.ts +72 -0
  19. package/dist/agent-runtime/types.js +2 -0
  20. package/dist/agent-runtime/types.js.map +1 -0
  21. package/dist/agents/index.d.ts +7 -0
  22. package/dist/agents/index.js +24 -0
  23. package/dist/agents/index.js.map +1 -0
  24. package/dist/agents/registry.d.ts +14 -0
  25. package/dist/agents/registry.js +97 -0
  26. package/dist/agents/registry.js.map +1 -0
  27. package/dist/agents/scanner-adapter.d.ts +5 -0
  28. package/dist/agents/scanner-adapter.js +18 -0
  29. package/dist/agents/scanner-adapter.js.map +1 -0
  30. package/dist/agents/tasks/augur-analyze.d.ts +22 -0
  31. package/dist/agents/tasks/augur-analyze.js +418 -0
  32. package/dist/agents/tasks/augur-analyze.js.map +1 -0
  33. package/dist/agents/tasks/augur-extraction-agent.d.ts +44 -0
  34. package/dist/agents/tasks/augur-extraction-agent.js +507 -0
  35. package/dist/agents/tasks/augur-extraction-agent.js.map +1 -0
  36. package/dist/agents/tasks/augur-label.d.ts +21 -0
  37. package/dist/agents/tasks/augur-label.js +627 -0
  38. package/dist/agents/tasks/augur-label.js.map +1 -0
  39. package/dist/agents/tasks/augur-preflight.d.ts +36 -0
  40. package/dist/agents/tasks/augur-preflight.js +471 -0
  41. package/dist/agents/tasks/augur-preflight.js.map +1 -0
  42. package/dist/agents/tasks/augur-types.d.ts +111 -0
  43. package/dist/agents/tasks/augur-types.js +169 -0
  44. package/dist/agents/tasks/augur-types.js.map +1 -0
  45. package/dist/agents/tasks/context-gatherer.d.ts +6 -0
  46. package/dist/agents/tasks/context-gatherer.js +320 -0
  47. package/dist/agents/tasks/context-gatherer.js.map +1 -0
  48. package/dist/agents/types.d.ts +28 -0
  49. package/dist/agents/types.js +2 -0
  50. package/dist/agents/types.js.map +1 -0
  51. package/dist/bus/adapters/google-pubsub.d.ts +13 -0
  52. package/dist/bus/adapters/google-pubsub.js +26 -0
  53. package/dist/bus/adapters/google-pubsub.js.map +1 -0
  54. package/dist/bus/adapters/in-process.d.ts +12 -0
  55. package/dist/bus/adapters/in-process.js +118 -0
  56. package/dist/bus/adapters/in-process.js.map +1 -0
  57. package/dist/bus/adapters/index.d.ts +6 -0
  58. package/dist/bus/adapters/index.js +22 -0
  59. package/dist/bus/adapters/index.js.map +1 -0
  60. package/dist/bus/adapters/nats.d.ts +13 -0
  61. package/dist/bus/adapters/nats.js +26 -0
  62. package/dist/bus/adapters/nats.js.map +1 -0
  63. package/dist/bus/adapters/redis.d.ts +13 -0
  64. package/dist/bus/adapters/redis.js +26 -0
  65. package/dist/bus/adapters/redis.js.map +1 -0
  66. package/dist/bus/events.d.ts +295 -0
  67. package/dist/bus/events.js +2 -0
  68. package/dist/bus/events.js.map +1 -0
  69. package/dist/bus/helpers.d.ts +7 -0
  70. package/dist/bus/helpers.js +16 -0
  71. package/dist/bus/helpers.js.map +1 -0
  72. package/dist/bus/index.d.ts +30 -0
  73. package/dist/bus/index.js +66 -0
  74. package/dist/bus/index.js.map +1 -0
  75. package/dist/bus/orchestrator.d.ts +51 -0
  76. package/dist/bus/orchestrator.js +1350 -0
  77. package/dist/bus/orchestrator.js.map +1 -0
  78. package/dist/bus/types.d.ts +23 -0
  79. package/dist/bus/types.js +2 -0
  80. package/dist/bus/types.js.map +1 -0
  81. package/dist/bus/workers/audit-worker.d.ts +9 -0
  82. package/dist/bus/workers/audit-worker.js +125 -0
  83. package/dist/bus/workers/audit-worker.js.map +1 -0
  84. package/dist/bus/workers/poc-harness-worker.d.ts +9 -0
  85. package/dist/bus/workers/poc-harness-worker.js +96 -0
  86. package/dist/bus/workers/poc-harness-worker.js.map +1 -0
  87. package/dist/bus/workers/report-worker.d.ts +11 -0
  88. package/dist/bus/workers/report-worker.js +235 -0
  89. package/dist/bus/workers/report-worker.js.map +1 -0
  90. package/dist/bus/workers/scan-worker.d.ts +13 -0
  91. package/dist/bus/workers/scan-worker.js +223 -0
  92. package/dist/bus/workers/scan-worker.js.map +1 -0
  93. package/dist/bus/workers/store-worker.d.ts +10 -0
  94. package/dist/bus/workers/store-worker.js +62 -0
  95. package/dist/bus/workers/store-worker.js.map +1 -0
  96. package/dist/bus/workers/triage-worker.d.ts +13 -0
  97. package/dist/bus/workers/triage-worker.js +129 -0
  98. package/dist/bus/workers/triage-worker.js.map +1 -0
  99. package/dist/bus/workers/verification-worker.d.ts +9 -0
  100. package/dist/bus/workers/verification-worker.js +91 -0
  101. package/dist/bus/workers/verification-worker.js.map +1 -0
  102. package/dist/cli.d.ts +2 -0
  103. package/dist/cli.js +513 -0
  104. package/dist/cli.js.map +1 -0
  105. package/dist/config.d.ts +17 -0
  106. package/dist/config.js +866 -0
  107. package/dist/config.js.map +1 -0
  108. package/dist/context.d.ts +5 -0
  109. package/dist/context.js +26 -0
  110. package/dist/context.js.map +1 -0
  111. package/dist/deps.d.ts +15 -0
  112. package/dist/deps.js +18 -0
  113. package/dist/deps.js.map +1 -0
  114. package/dist/llm/anthropic.d.ts +3 -0
  115. package/dist/llm/anthropic.js +21 -0
  116. package/dist/llm/anthropic.js.map +1 -0
  117. package/dist/poc-harness.d.ts +49 -0
  118. package/dist/poc-harness.js +420 -0
  119. package/dist/poc-harness.js.map +1 -0
  120. package/dist/report-markdown.d.ts +3 -0
  121. package/dist/report-markdown.js +197 -0
  122. package/dist/report-markdown.js.map +1 -0
  123. package/dist/report-sarif.d.ts +3 -0
  124. package/dist/report-sarif.js +253 -0
  125. package/dist/report-sarif.js.map +1 -0
  126. package/dist/report.d.ts +18 -0
  127. package/dist/report.js +146 -0
  128. package/dist/report.js.map +1 -0
  129. package/dist/retry.d.ts +6 -0
  130. package/dist/retry.js +25 -0
  131. package/dist/retry.js.map +1 -0
  132. package/dist/scanner/claude-adk.d.ts +26 -0
  133. package/dist/scanner/claude-adk.js +265 -0
  134. package/dist/scanner/claude-adk.js.map +1 -0
  135. package/dist/scanner/resolve.d.ts +10 -0
  136. package/dist/scanner/resolve.js +99 -0
  137. package/dist/scanner/resolve.js.map +1 -0
  138. package/dist/scanner.d.ts +47 -0
  139. package/dist/scanner.js +123 -0
  140. package/dist/scanner.js.map +1 -0
  141. package/dist/scanners/agentic.d.ts +11 -0
  142. package/dist/scanners/agentic.js +71 -0
  143. package/dist/scanners/agentic.js.map +1 -0
  144. package/dist/scanners/claude-adk.d.ts +11 -0
  145. package/dist/scanners/claude-adk.js +74 -0
  146. package/dist/scanners/claude-adk.js.map +1 -0
  147. package/dist/scanners/codeql.d.ts +15 -0
  148. package/dist/scanners/codeql.js +97 -0
  149. package/dist/scanners/codeql.js.map +1 -0
  150. package/dist/scanners/finding-selection.d.ts +7 -0
  151. package/dist/scanners/finding-selection.js +120 -0
  152. package/dist/scanners/finding-selection.js.map +1 -0
  153. package/dist/scanners/index.d.ts +4 -0
  154. package/dist/scanners/index.js +14 -0
  155. package/dist/scanners/index.js.map +1 -0
  156. package/dist/scanners/registry.d.ts +12 -0
  157. package/dist/scanners/registry.js +70 -0
  158. package/dist/scanners/registry.js.map +1 -0
  159. package/dist/scanners/resolve-codeql.d.ts +9 -0
  160. package/dist/scanners/resolve-codeql.js +38 -0
  161. package/dist/scanners/resolve-codeql.js.map +1 -0
  162. package/dist/scanners/resolve-semgrep.d.ts +10 -0
  163. package/dist/scanners/resolve-semgrep.js +96 -0
  164. package/dist/scanners/resolve-semgrep.js.map +1 -0
  165. package/dist/scanners/run-agentic.d.ts +33 -0
  166. package/dist/scanners/run-agentic.js +267 -0
  167. package/dist/scanners/run-agentic.js.map +1 -0
  168. package/dist/scanners/run-claude-adk.d.ts +33 -0
  169. package/dist/scanners/run-claude-adk.js +267 -0
  170. package/dist/scanners/run-claude-adk.js.map +1 -0
  171. package/dist/scanners/run-codeql.d.ts +100 -0
  172. package/dist/scanners/run-codeql.js +538 -0
  173. package/dist/scanners/run-codeql.js.map +1 -0
  174. package/dist/scanners/run-semgrep.d.ts +41 -0
  175. package/dist/scanners/run-semgrep.js +115 -0
  176. package/dist/scanners/run-semgrep.js.map +1 -0
  177. package/dist/scanners/scoring.d.ts +7 -0
  178. package/dist/scanners/scoring.js +14 -0
  179. package/dist/scanners/scoring.js.map +1 -0
  180. package/dist/scanners/semgrep.d.ts +11 -0
  181. package/dist/scanners/semgrep.js +64 -0
  182. package/dist/scanners/semgrep.js.map +1 -0
  183. package/dist/scanners/types.d.ts +36 -0
  184. package/dist/scanners/types.js +2 -0
  185. package/dist/scanners/types.js.map +1 -0
  186. package/dist/scanners.d.ts +25 -0
  187. package/dist/scanners.js +88 -0
  188. package/dist/scanners.js.map +1 -0
  189. package/dist/store.d.ts +106 -0
  190. package/dist/store.js +609 -0
  191. package/dist/store.js.map +1 -0
  192. package/dist/triage.d.ts +74 -0
  193. package/dist/triage.js +314 -0
  194. package/dist/triage.js.map +1 -0
  195. package/dist/types.d.ts +166 -0
  196. package/dist/types.js +2 -0
  197. package/dist/types.js.map +1 -0
  198. package/dist/utils.d.ts +6 -0
  199. package/dist/utils.js +19 -0
  200. package/dist/utils.js.map +1 -0
  201. package/dist/verify.d.ts +56 -0
  202. package/dist/verify.js +298 -0
  203. package/dist/verify.js.map +1 -0
  204. package/package.json +55 -0
package/dist/report.js ADDED
@@ -0,0 +1,146 @@
1
+ import chalk from "chalk";
2
+ import path from "node:path";
3
+ import { getActionableFindings, getPocHarnessCounts, getTotalCost, getTotalPocHarnessCost, getTotalVerificationCost, getVerificationCounts, getVerdictCounts, } from "./store.js";
4
+ /** Color a verdict string. */
5
+ function colorVerdict(verdict) {
6
+ switch (verdict) {
7
+ case "tp":
8
+ return chalk.red.bold("TRUE POSITIVE");
9
+ case "fp":
10
+ return chalk.green("false positive");
11
+ case "needs_review":
12
+ return chalk.yellow("needs review");
13
+ }
14
+ }
15
+ /** Print a progress line for a single triage result. */
16
+ export function printTriageProgress(result, index, total, attempts) {
17
+ const verdict = colorVerdict(result.verdict);
18
+ const conf = chalk.dim(`(${(result.confidence * 100).toFixed(0)}%)`);
19
+ const cost = result.triageCostUsd && result.triageCostUsd > 0
20
+ ? chalk.dim(`$${result.triageCostUsd.toFixed(4)}`)
21
+ : "";
22
+ const retry = attempts && attempts > 1
23
+ ? chalk.dim(`(retry #${attempts})`)
24
+ : "";
25
+ console.log(` [${index}/${total}] ${verdict} ${conf}${cost ? ` ${cost}` : ""}${retry ? ` ${retry}` : ""} ${chalk.dim(result.fingerprint.slice(0, 12))}...`);
26
+ }
27
+ /** Print the final scan summary to terminal. */
28
+ export function printSummary(db, repo, options = {}) {
29
+ const counts = getVerdictCounts(db, repo);
30
+ const totalCostUsd = getTotalCost(db, repo);
31
+ const verificationCostUsd = getTotalVerificationCost(db, repo);
32
+ const pocHarnessCostUsd = getTotalPocHarnessCost(db, repo);
33
+ const verificationCounts = getVerificationCounts(db, repo);
34
+ const pocHarnessCounts = getPocHarnessCounts(db, repo);
35
+ const hasVerificationStats = verificationCounts.exploitable + verificationCounts.notExploitable > 0;
36
+ const hasVerificationSpend = verificationCostUsd > 0;
37
+ const hasVerificationData = hasVerificationStats || hasVerificationSpend;
38
+ const hasPocHarnessData = (pocHarnessCounts.generated > 0
39
+ || pocHarnessCounts.skipped > 0
40
+ || (options.stats?.pocHarnessErrors ?? 0) > 0
41
+ || pocHarnessCostUsd > 0);
42
+ const total = counts.tp + counts.fp + counts.needs_review;
43
+ const actionable = getActionableFindings(db, repo);
44
+ console.log("");
45
+ console.log(chalk.bold("─".repeat(60)));
46
+ console.log(chalk.bold(" Kuzushi Scan Results"));
47
+ console.log(chalk.bold("─".repeat(60)));
48
+ console.log("");
49
+ console.log(` ${chalk.dim("Total triaged:")} ${total}`);
50
+ console.log(` ${chalk.red.bold("True positives:")} ${counts.tp}`);
51
+ console.log(` ${chalk.green("False positives:")} ${counts.fp}`);
52
+ console.log(` ${chalk.yellow("Needs review:")} ${counts.needs_review}`);
53
+ if ((options.stats?.skippedLowConfidence ?? 0) > 0) {
54
+ console.log(` ${chalk.dim("Skipped (low confidence):")} ${options.stats?.skippedLowConfidence}`);
55
+ }
56
+ if (hasVerificationData) {
57
+ console.log("");
58
+ if (hasVerificationStats) {
59
+ console.log(` ${chalk.red.bold("Exploitable:")} ${verificationCounts.exploitable}`);
60
+ console.log(` ${chalk.green("Not exploitable:")} ${verificationCounts.notExploitable}`);
61
+ }
62
+ else {
63
+ console.log(` ${chalk.yellow("Verification:")} errors only`);
64
+ }
65
+ }
66
+ if (hasPocHarnessData) {
67
+ console.log("");
68
+ console.log(` ${chalk.cyan("PoC harnesses generated:")} ${pocHarnessCounts.generated}`);
69
+ console.log(` ${chalk.yellow("PoC harnesses skipped:")} ${pocHarnessCounts.skipped}`);
70
+ console.log(` ${chalk.red("PoC harness errors:")} ${options.stats?.pocHarnessErrors ?? 0}`);
71
+ if (options.repoRoot) {
72
+ const pocDir = path.join(options.repoRoot, ".kuzushi", "poc");
73
+ console.log(` ${chalk.dim("PoC output dir:")} ${pocDir}/`);
74
+ }
75
+ }
76
+ if (actionable.length > 0) {
77
+ console.log("");
78
+ console.log(chalk.bold(" Actionable Findings:"));
79
+ console.log("");
80
+ for (const f of actionable) {
81
+ const verdict = colorVerdict(f.verdict);
82
+ const location = chalk.cyan(`${f.filePath}:${f.startLine}`);
83
+ const conf = chalk.dim(`${(f.confidence * 100).toFixed(0)}%`);
84
+ const severity = f.severity === "ERROR" ? chalk.red(f.severity) : chalk.yellow(f.severity);
85
+ const scanner = chalk.dim(`[${f.scanner}]`);
86
+ const verificationBadge = f.verifyExploitable === 1
87
+ ? chalk.bgRed.white.bold(" EXPLOITABLE ")
88
+ : f.verifyExploitable === 0
89
+ ? chalk.bgGreen.black(" NOT EXPLOITABLE ")
90
+ : "";
91
+ console.log(` ${verdict} ${conf} ${severity} ${scanner}${verificationBadge ? ` ${verificationBadge}` : ""}`);
92
+ console.log(` ${location}`);
93
+ console.log(` ${chalk.dim(f.ruleId)}`);
94
+ console.log(` ${f.rationale.slice(0, 120)}${f.rationale.length > 120 ? "..." : ""}`);
95
+ if (f.verifyExploitable === 1 && f.verifyPocPayload) {
96
+ const payload = f.verifyPocPayload.length > 80
97
+ ? `${f.verifyPocPayload.slice(0, 77)}...`
98
+ : f.verifyPocPayload;
99
+ console.log(` ${chalk.magenta("PoC:")} ${payload}`);
100
+ }
101
+ if (f.verifyAttackVector) {
102
+ console.log(` ${chalk.cyan("Vector:")} ${f.verifyAttackVector}`);
103
+ }
104
+ if (f.pocHarnessPath) {
105
+ console.log(` ${chalk.blue("PoC Harness:")} ${f.pocHarnessPath}`);
106
+ }
107
+ else if (f.pocHarnessSkipped === 1) {
108
+ console.log(` ${chalk.yellow("PoC Harness:")} skipped (${f.pocHarnessSkipReason ?? "no reason provided"})`);
109
+ }
110
+ if (f.pocHarnessParsed === 0 && f.pocHarnessParseError) {
111
+ console.log(` ${chalk.red("PoC Parse Error:")} ${f.pocHarnessParseError}`);
112
+ }
113
+ console.log("");
114
+ }
115
+ }
116
+ else if (total > 0) {
117
+ console.log("");
118
+ console.log(chalk.green.bold(" All findings triaged as false positives. Code looks clean."));
119
+ }
120
+ console.log("");
121
+ console.log(` ${chalk.dim("Total triage cost:")} $${totalCostUsd.toFixed(4)}`);
122
+ if (hasVerificationData) {
123
+ console.log(` ${chalk.dim("Total verification cost:")} $${verificationCostUsd.toFixed(4)}`);
124
+ }
125
+ if (hasPocHarnessData) {
126
+ console.log(` ${chalk.dim("Total PoC harness cost:")} $${pocHarnessCostUsd.toFixed(4)}`);
127
+ }
128
+ if (options.auditLog && options.repoRoot && options.runId) {
129
+ const runDir = path.join(options.repoRoot, ".kuzushi", "runs", options.runId);
130
+ console.log(` ${chalk.dim("Audit log:")} ${runDir}/`);
131
+ }
132
+ console.log(chalk.bold("─".repeat(60)));
133
+ }
134
+ /** Print a short line when starting a scan. */
135
+ export function printScanStart(repoName, findingCount, total, scanners) {
136
+ console.log("");
137
+ console.log(chalk.bold(` Kuzushi v0.1 — scanning ${repoName}`));
138
+ console.log(` Scanners: ${scanners.join(", ")}`);
139
+ console.log(` ${total} findings, ${findingCount} selected for AI triage`);
140
+ console.log("");
141
+ }
142
+ /** Print when resuming with skipped findings. */
143
+ export function printResumeInfo(skipped, remaining) {
144
+ console.log(chalk.dim(` Skipping ${skipped} already-triaged findings, ${remaining} remaining`));
145
+ }
146
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface RetryOptions {
2
+ maxRetries: number;
3
+ backoffMs: number;
4
+ multiplier: number;
5
+ }
6
+ export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T>;
package/dist/retry.js ADDED
@@ -0,0 +1,25 @@
1
+ export async function withRetry(fn, options) {
2
+ let lastError;
3
+ for (let attempt = 0; attempt <= options.maxRetries; attempt += 1) {
4
+ try {
5
+ return await fn();
6
+ }
7
+ catch (error) {
8
+ lastError = error;
9
+ if (attempt < options.maxRetries) {
10
+ const delay = options.backoffMs * Math.pow(options.multiplier, attempt);
11
+ await sleep(delay);
12
+ }
13
+ }
14
+ }
15
+ throw lastError;
16
+ }
17
+ function sleep(ms) {
18
+ if (!Number.isFinite(ms) || ms <= 0) {
19
+ return Promise.resolve();
20
+ }
21
+ return new Promise((resolve) => {
22
+ setTimeout(resolve, ms);
23
+ });
24
+ }
25
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,OAAqB;IAErB,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACxE,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { RawFinding, ScanOpts } from "../types.js";
2
+ interface ClaudeAdkFinding {
3
+ ruleId: string;
4
+ filePath: string;
5
+ startLine: number;
6
+ severity: string;
7
+ message: string;
8
+ confidence: string;
9
+ subcategory: string[];
10
+ likelihood: string;
11
+ impact: string;
12
+ cwe: string[];
13
+ evidence: string;
14
+ }
15
+ export interface ClaudeAdkOutput {
16
+ findings: ClaudeAdkFinding[];
17
+ }
18
+ /** Run the Claude Agent SDK scanner and return structured findings. */
19
+ export declare function runClaudeAdk(repoRoot: string, opts: ScanOpts, model: string, defaultMaxFindings: number): Promise<ClaudeAdkOutput>;
20
+ /** Rank and map Claude ADK findings into normalized RawFinding records. */
21
+ export declare function selectClaudeFindings(output: ClaudeAdkOutput, repoRoot: string, repoName: string, ref: string, maxFindings?: number): RawFinding[];
22
+ /** Parse and normalize structured output from the claude-adk scanner. */
23
+ export declare function parseClaudeAdkOutput(raw: unknown): ClaudeAdkOutput;
24
+ /** Stable fingerprint for claude-adk findings. */
25
+ export declare function computeClaudeAdkFingerprint(repoName: string, ref: string, finding: ClaudeAdkFinding): string;
26
+ export {};
@@ -0,0 +1,265 @@
1
+ import { createHash } from "node:crypto";
2
+ import path from "node:path";
3
+ import { query } from "@anthropic-ai/claude-agent-sdk";
4
+ import { scoreFindingMetadata } from "../scanner.js";
5
+ const SEVERITY_LEVELS = new Set(["ERROR", "WARNING", "INFO"]);
6
+ const CONFIDENCE_LEVELS = new Set(["HIGH", "MEDIUM", "LOW"]);
7
+ const SUBCATEGORIES = new Set(["vuln", "audit"]);
8
+ const CLAUDE_ADK_SCHEMA = {
9
+ type: "object",
10
+ additionalProperties: false,
11
+ required: ["findings"],
12
+ properties: {
13
+ findings: {
14
+ type: "array",
15
+ items: {
16
+ type: "object",
17
+ additionalProperties: false,
18
+ required: ["ruleId", "filePath", "startLine", "severity", "message"],
19
+ properties: {
20
+ ruleId: { type: "string" },
21
+ filePath: { type: "string" },
22
+ startLine: { type: "integer", minimum: 1 },
23
+ severity: { type: "string", enum: ["ERROR", "WARNING", "INFO"] },
24
+ message: { type: "string" },
25
+ confidence: { type: "string", enum: ["HIGH", "MEDIUM", "LOW"] },
26
+ subcategory: {
27
+ type: "array",
28
+ items: { type: "string", enum: ["vuln", "audit"] },
29
+ },
30
+ likelihood: { type: "string", enum: ["HIGH", "MEDIUM", "LOW"] },
31
+ impact: { type: "string", enum: ["HIGH", "MEDIUM", "LOW"] },
32
+ cwe: {
33
+ type: "array",
34
+ items: { type: "string" },
35
+ },
36
+ evidence: { type: "string" },
37
+ },
38
+ },
39
+ },
40
+ },
41
+ };
42
+ /** Run the Claude Agent SDK scanner and return structured findings. */
43
+ export async function runClaudeAdk(repoRoot, opts, model, defaultMaxFindings) {
44
+ const requestedMax = Math.max(1, opts.maxFindings ?? defaultMaxFindings);
45
+ const prompt = buildPrompt(opts, requestedMax);
46
+ let resultText = "";
47
+ let structuredOutput = undefined;
48
+ let executionError = null;
49
+ for await (const message of query({
50
+ prompt,
51
+ options: {
52
+ cwd: repoRoot,
53
+ model,
54
+ maxTurns: 20,
55
+ allowedTools: ["Read", "Glob", "Grep"],
56
+ permissionMode: "dontAsk",
57
+ outputFormat: {
58
+ type: "json_schema",
59
+ schema: CLAUDE_ADK_SCHEMA,
60
+ },
61
+ },
62
+ })) {
63
+ if (message.type !== "result")
64
+ continue;
65
+ if (message.subtype === "success") {
66
+ resultText = message.result;
67
+ structuredOutput = message.structured_output;
68
+ continue;
69
+ }
70
+ executionError = message.errors.join("; ") || message.subtype;
71
+ }
72
+ if (executionError) {
73
+ throw new Error(`claude-adk scanner failed: ${executionError}`);
74
+ }
75
+ const parsed = parseClaudeAdkOutput(structuredOutput ?? resultText);
76
+ return {
77
+ findings: parsed.findings.slice(0, requestedMax),
78
+ };
79
+ }
80
+ /** Rank and map Claude ADK findings into normalized RawFinding records. */
81
+ export function selectClaudeFindings(output, repoRoot, repoName, ref, maxFindings) {
82
+ const deduped = new Map();
83
+ for (const finding of output.findings) {
84
+ const filePath = normalizeFilePath(repoRoot, finding.filePath);
85
+ const fingerprint = computeClaudeAdkFingerprint(repoName, ref, {
86
+ ...finding,
87
+ filePath,
88
+ });
89
+ const score = scoreFindingMetadata({
90
+ severity: finding.severity,
91
+ likelihood: finding.likelihood,
92
+ impact: finding.impact,
93
+ subcategory: finding.subcategory,
94
+ });
95
+ const rawFinding = {
96
+ scanner: "claude-adk",
97
+ fingerprint,
98
+ ruleId: finding.ruleId,
99
+ filePath,
100
+ startLine: finding.startLine,
101
+ severity: finding.severity,
102
+ message: finding.message,
103
+ scannerConfidence: finding.confidence,
104
+ subcategory: finding.subcategory,
105
+ likelihood: finding.likelihood,
106
+ impact: finding.impact,
107
+ cwe: finding.cwe,
108
+ score,
109
+ };
110
+ const existing = deduped.get(fingerprint);
111
+ if (!existing || rawFinding.score > existing.score) {
112
+ deduped.set(fingerprint, rawFinding);
113
+ }
114
+ }
115
+ return [...deduped.values()]
116
+ .sort((a, b) => b.score - a.score)
117
+ .slice(0, maxFindings);
118
+ }
119
+ /** Parse and normalize structured output from the claude-adk scanner. */
120
+ export function parseClaudeAdkOutput(raw) {
121
+ const data = parseRawOutput(raw);
122
+ if (!isRecord(data) || !Array.isArray(data["findings"])) {
123
+ throw new Error("claude-adk scanner returned invalid output shape");
124
+ }
125
+ const findings = [];
126
+ for (const item of data["findings"]) {
127
+ if (!isRecord(item))
128
+ continue;
129
+ const ruleId = asString(item["ruleId"], "claude-adk.security.finding");
130
+ const filePath = asString(item["filePath"], "").trim();
131
+ if (!filePath)
132
+ continue;
133
+ const startLine = asPositiveInt(item["startLine"], 1);
134
+ const severity = normalizeSeverity(item["severity"], "WARNING");
135
+ const message = asString(item["message"], "Potential security issue");
136
+ const confidence = normalizeConfidence(item["confidence"], "MEDIUM");
137
+ const subcategory = normalizeSubcategory(item["subcategory"]);
138
+ const likelihood = normalizeConfidence(item["likelihood"], "MEDIUM");
139
+ const impact = normalizeConfidence(item["impact"], "MEDIUM");
140
+ const cwe = normalizeStringArray(item["cwe"]);
141
+ const evidence = asString(item["evidence"], "");
142
+ findings.push({
143
+ ruleId,
144
+ filePath,
145
+ startLine,
146
+ severity,
147
+ message,
148
+ confidence,
149
+ subcategory,
150
+ likelihood,
151
+ impact,
152
+ cwe,
153
+ evidence,
154
+ });
155
+ }
156
+ return { findings };
157
+ }
158
+ /** Stable fingerprint for claude-adk findings. */
159
+ export function computeClaudeAdkFingerprint(repoName, ref, finding) {
160
+ const source = [
161
+ repoName,
162
+ ref,
163
+ "claude-adk",
164
+ finding.ruleId,
165
+ finding.filePath,
166
+ String(finding.startLine),
167
+ finding.message,
168
+ finding.evidence,
169
+ ].join("|");
170
+ return createHash("sha256").update(source).digest("hex");
171
+ }
172
+ function buildPrompt(opts, maxFindings) {
173
+ return [
174
+ "You are a static analysis security scanner.",
175
+ "Analyze the repository for concrete application security issues.",
176
+ "Return only findings with enough evidence in code.",
177
+ "",
178
+ `Severity filter: ${opts.severity.join(", ") || "ERROR, WARNING, INFO"}`,
179
+ `Max findings: ${maxFindings}`,
180
+ `Exclude paths/globs: ${opts.excludePatterns.join(", ") || "(none)"}`,
181
+ "",
182
+ "For each finding return:",
183
+ "- ruleId (string)",
184
+ "- filePath (relative path preferred)",
185
+ "- startLine (1-based integer)",
186
+ "- severity (ERROR|WARNING|INFO)",
187
+ "- message (short finding summary)",
188
+ "- confidence (HIGH|MEDIUM|LOW)",
189
+ "- subcategory (vuln or audit; default to audit when unsure)",
190
+ "- likelihood (HIGH|MEDIUM|LOW)",
191
+ "- impact (HIGH|MEDIUM|LOW)",
192
+ "- cwe (array of CWE strings, optional)",
193
+ "- evidence (short evidence snippet)",
194
+ "",
195
+ "Do not propose remediations. Do not include non-security style issues.",
196
+ ].join("\n");
197
+ }
198
+ function parseRawOutput(raw) {
199
+ if (typeof raw !== "string")
200
+ return raw;
201
+ const text = raw.trim();
202
+ if (!text)
203
+ return { findings: [] };
204
+ try {
205
+ return JSON.parse(text);
206
+ }
207
+ catch {
208
+ const extracted = extractJsonObject(text);
209
+ return JSON.parse(extracted);
210
+ }
211
+ }
212
+ function extractJsonObject(text) {
213
+ const fenceMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
214
+ if (fenceMatch)
215
+ return fenceMatch[1].trim();
216
+ const start = text.indexOf("{");
217
+ const end = text.lastIndexOf("}");
218
+ if (start !== -1 && end > start) {
219
+ return text.slice(start, end + 1);
220
+ }
221
+ return text;
222
+ }
223
+ function normalizeFilePath(repoRoot, filePath) {
224
+ if (!path.isAbsolute(filePath))
225
+ return filePath;
226
+ const relative = path.relative(repoRoot, filePath);
227
+ if (relative.startsWith(".."))
228
+ return filePath;
229
+ return relative || filePath;
230
+ }
231
+ function normalizeSeverity(value, fallback) {
232
+ const normalized = asString(value, fallback).toUpperCase();
233
+ return SEVERITY_LEVELS.has(normalized) ? normalized : fallback;
234
+ }
235
+ function normalizeConfidence(value, fallback) {
236
+ const normalized = asString(value, fallback).toUpperCase();
237
+ return CONFIDENCE_LEVELS.has(normalized) ? normalized : fallback;
238
+ }
239
+ function normalizeSubcategory(value) {
240
+ const items = normalizeStringArray(value).map((v) => v.toLowerCase());
241
+ const valid = items.filter((v) => SUBCATEGORIES.has(v));
242
+ return valid.length > 0 ? valid : ["audit"];
243
+ }
244
+ function normalizeStringArray(value) {
245
+ if (!Array.isArray(value))
246
+ return [];
247
+ return value.map((v) => String(v).trim()).filter(Boolean);
248
+ }
249
+ function asPositiveInt(value, fallback) {
250
+ const numeric = Number(value);
251
+ if (!Number.isFinite(numeric) || numeric < 1)
252
+ return fallback;
253
+ return Math.floor(numeric);
254
+ }
255
+ function asString(value, fallback) {
256
+ if (typeof value === "string")
257
+ return value;
258
+ if (value == null)
259
+ return fallback;
260
+ return String(value);
261
+ }
262
+ function isRecord(value) {
263
+ return value !== null && typeof value === "object";
264
+ }
265
+ //# sourceMappingURL=claude-adk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-adk.js","sourceRoot":"","sources":["../../src/scanner/claude-adk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Resolve the scanner binary path.
3
+ *
4
+ * Precedence:
5
+ * 1. `opengrep` on PATH
6
+ * 2. `semgrep` on PATH
7
+ * 3. Previously downloaded binary at ~/.kuzushi/bin/opengrep
8
+ * 4. Auto-download from GitHub releases
9
+ */
10
+ export declare function resolveScanner(): Promise<string>;
@@ -0,0 +1,99 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { createWriteStream, chmodSync, existsSync, mkdirSync } from "node:fs";
3
+ import { pipeline } from "node:stream/promises";
4
+ import { get } from "node:https";
5
+ import path from "node:path";
6
+ import os from "node:os";
7
+ const BIN_DIR = path.join(os.homedir(), ".kuzushi", "bin");
8
+ const GITHUB_RELEASE_URL = "https://api.github.com/repos/opengrep/opengrep/releases/latest";
9
+ /** Map Node's process.platform + process.arch to Opengrep asset name. */
10
+ function getAssetName() {
11
+ const platform = process.platform;
12
+ const arch = process.arch;
13
+ if (platform === "darwin" && arch === "arm64")
14
+ return "opengrep_osx_arm64";
15
+ if (platform === "darwin" && arch === "x64")
16
+ return "opengrep_osx_x86";
17
+ if (platform === "linux" && arch === "x64")
18
+ return "opengrep_manylinux_x86";
19
+ if (platform === "linux" && arch === "arm64")
20
+ return "opengrep_manylinux_aarch64";
21
+ if (platform === "win32" && arch === "x64")
22
+ return "opengrep_windows_x86.exe";
23
+ throw new Error(`Unsupported platform: ${platform}/${arch}. Install semgrep or opengrep manually.`);
24
+ }
25
+ /** Check if a binary exists on PATH. */
26
+ function which(name) {
27
+ try {
28
+ return execFileSync("which", [name], { encoding: "utf-8" }).trim() || null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /** Follow redirects and return the final response. */
35
+ function httpsGet(url) {
36
+ return new Promise((resolve, reject) => {
37
+ get(url, { headers: { "User-Agent": "kuzushi/0.1" } }, (res) => {
38
+ if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
39
+ httpsGet(res.headers.location).then(resolve, reject);
40
+ return;
41
+ }
42
+ resolve(res);
43
+ }).on("error", reject);
44
+ });
45
+ }
46
+ /** Fetch latest release info from GitHub. */
47
+ async function getLatestReleaseDownloadUrl(assetName) {
48
+ const res = await httpsGet(GITHUB_RELEASE_URL);
49
+ const chunks = [];
50
+ for await (const chunk of res)
51
+ chunks.push(chunk);
52
+ const body = JSON.parse(Buffer.concat(chunks).toString());
53
+ const asset = body.assets?.find((a) => a.name === assetName);
54
+ if (!asset) {
55
+ throw new Error(`Could not find asset "${assetName}" in latest opengrep release (${body.tag_name}).`);
56
+ }
57
+ return asset.browser_download_url;
58
+ }
59
+ /** Download a file from a URL to a local path. */
60
+ async function downloadFile(url, dest) {
61
+ const res = await httpsGet(url);
62
+ if (res.statusCode !== 200) {
63
+ throw new Error(`Download failed: HTTP ${res.statusCode}`);
64
+ }
65
+ await pipeline(res, createWriteStream(dest));
66
+ }
67
+ /**
68
+ * Resolve the scanner binary path.
69
+ *
70
+ * Precedence:
71
+ * 1. `opengrep` on PATH
72
+ * 2. `semgrep` on PATH
73
+ * 3. Previously downloaded binary at ~/.kuzushi/bin/opengrep
74
+ * 4. Auto-download from GitHub releases
75
+ */
76
+ export async function resolveScanner() {
77
+ // 1. Check PATH
78
+ const onPath = which("opengrep") ?? which("semgrep");
79
+ if (onPath)
80
+ return onPath;
81
+ // 2. Check local cache
82
+ const localBin = path.join(BIN_DIR, process.platform === "win32" ? "opengrep.exe" : "opengrep");
83
+ if (existsSync(localBin))
84
+ return localBin;
85
+ // 3. Download
86
+ console.log(" No scanner found on PATH. Downloading opengrep...");
87
+ const assetName = getAssetName();
88
+ const downloadUrl = await getLatestReleaseDownloadUrl(assetName);
89
+ if (!existsSync(BIN_DIR))
90
+ mkdirSync(BIN_DIR, { recursive: true });
91
+ console.log(` Downloading ${assetName}...`);
92
+ await downloadFile(downloadUrl, localBin);
93
+ if (process.platform !== "win32") {
94
+ chmodSync(localBin, 0o755);
95
+ }
96
+ console.log(` Installed opengrep to ${localBin}`);
97
+ return localBin;
98
+ }
99
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/scanner/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAC3D,MAAM,kBAAkB,GACtB,gEAAgE,CAAC;AAEnE,yEAAyE;AACzE,SAAS,YAAY;IACnB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1B,IAAI,QAAQ,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,oBAAoB,CAAC;IAC3E,IAAI,QAAQ,KAAK,QAAQ,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,kBAAkB,CAAC;IACvE,IAAI,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,wBAAwB,CAAC;IAC5E,IAAI,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,4BAA4B,CAAC;IAClF,IAAI,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,0BAA0B,CAAC;IAE9E,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,IAAI,IAAI,yCAAyC,CACnF,CAAC;AACJ,CAAC;AAED,wCAAwC;AACxC,SAAS,KAAK,CAAC,IAAY;IACzB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;YAC7D,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC5F,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6CAA6C;AAC7C,KAAK,UAAU,2BAA2B,CAAC,SAAiB;IAC1D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG;QAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE1D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAC7B,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAC9C,CAAC;IACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,yBAAyB,SAAS,iCAAiC,IAAI,CAAC,QAAQ,IAAI,CACrF,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,oBAAoB,CAAC;AACpC,CAAC;AAED,kDAAkD;AAClD,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,gBAAgB;IAChB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,uBAAuB;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAChG,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE1C,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,WAAW,GAAG,MAAM,2BAA2B,CAAC,SAAS,CAAC,CAAC;IAEjE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,KAAK,CAAC,CAAC;IAC7C,MAAM,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAE1C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC;AAClB,CAAC"}