revu-ai 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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +252 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/concurrency.d.ts +1 -0
  7. package/dist/concurrency.js +31 -0
  8. package/dist/concurrency.js.map +1 -0
  9. package/dist/config.d.ts +18 -0
  10. package/dist/config.js +70 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/discovery.d.ts +3 -0
  13. package/dist/discovery.js +39 -0
  14. package/dist/discovery.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.js +6 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/init.d.ts +26 -0
  19. package/dist/init.js +50 -0
  20. package/dist/init.js.map +1 -0
  21. package/dist/mcp/aggregator.d.ts +11 -0
  22. package/dist/mcp/aggregator.js +47 -0
  23. package/dist/mcp/aggregator.js.map +1 -0
  24. package/dist/mcp/server.d.ts +14 -0
  25. package/dist/mcp/server.js +105 -0
  26. package/dist/mcp/server.js.map +1 -0
  27. package/dist/mcp/tools.d.ts +33 -0
  28. package/dist/mcp/tools.js +32 -0
  29. package/dist/mcp/tools.js.map +1 -0
  30. package/dist/output/github.d.ts +2 -0
  31. package/dist/output/github.js +36 -0
  32. package/dist/output/github.js.map +1 -0
  33. package/dist/output/json.d.ts +2 -0
  34. package/dist/output/json.js +9 -0
  35. package/dist/output/json.js.map +1 -0
  36. package/dist/output/pretty.d.ts +2 -0
  37. package/dist/output/pretty.js +142 -0
  38. package/dist/output/pretty.js.map +1 -0
  39. package/dist/prompts/init-system.d.ts +4 -0
  40. package/dist/prompts/init-system.js +148 -0
  41. package/dist/prompts/init-system.js.map +1 -0
  42. package/dist/prompts/init-user.d.ts +5 -0
  43. package/dist/prompts/init-user.js +20 -0
  44. package/dist/prompts/init-user.js.map +1 -0
  45. package/dist/prompts/review-system.d.ts +6 -0
  46. package/dist/prompts/review-system.js +61 -0
  47. package/dist/prompts/review-system.js.map +1 -0
  48. package/dist/prompts/review-user.d.ts +2 -0
  49. package/dist/prompts/review-user.js +10 -0
  50. package/dist/prompts/review-user.js.map +1 -0
  51. package/dist/providers/claude-code.d.ts +9 -0
  52. package/dist/providers/claude-code.js +481 -0
  53. package/dist/providers/claude-code.js.map +1 -0
  54. package/dist/providers/registry.d.ts +8 -0
  55. package/dist/providers/registry.js +60 -0
  56. package/dist/providers/registry.js.map +1 -0
  57. package/dist/providers/types.d.ts +70 -0
  58. package/dist/providers/types.js +2 -0
  59. package/dist/providers/types.js.map +1 -0
  60. package/dist/refs.d.ts +9 -0
  61. package/dist/refs.js +81 -0
  62. package/dist/refs.js.map +1 -0
  63. package/dist/runner.d.ts +23 -0
  64. package/dist/runner.js +106 -0
  65. package/dist/runner.js.map +1 -0
  66. package/dist/types.d.ts +68 -0
  67. package/dist/types.js +8 -0
  68. package/dist/types.js.map +1 -0
  69. package/examples/github-workflow.yml +38 -0
  70. package/package.json +73 -0
@@ -0,0 +1,481 @@
1
+ import { isAbsolute, relative, resolve } from "node:path";
2
+ import { query } from "@anthropic-ai/claude-agent-sdk";
3
+ import { buildSystemPrompt } from "../prompts/review-system.js";
4
+ import { buildUserPrompt } from "../prompts/review-user.js";
5
+ import { buildInitSystemPrompt } from "../prompts/init-system.js";
6
+ import { buildInitUserPrompt } from "../prompts/init-user.js";
7
+ const ALWAYS_ALLOWED_TOOLS = [
8
+ "Read",
9
+ "Grep",
10
+ "Glob",
11
+ "mcp__revu__report_finding",
12
+ ];
13
+ const RESTRICTED_TOOLSET = ["Read", "Grep", "Glob", "Bash"];
14
+ export const claudeCodeProvider = (cfg) => ({
15
+ name: "claude-code",
16
+ async run(input) {
17
+ const start = Date.now();
18
+ const abort = new AbortController();
19
+ if (input.signal) {
20
+ input.signal.addEventListener("abort", () => abort.abort(), { once: true });
21
+ }
22
+ let timedOut = false;
23
+ const timer = input.timeoutMs && input.timeoutMs > 0
24
+ ? setTimeout(() => {
25
+ timedOut = true;
26
+ abort.abort();
27
+ }, input.timeoutMs)
28
+ : undefined;
29
+ try {
30
+ const q = query({
31
+ prompt: buildUserPrompt(input.reviewTarget),
32
+ options: {
33
+ cwd: input.repoRoot,
34
+ ...(cfg.model ? { model: cfg.model } : {}),
35
+ systemPrompt: buildSystemPrompt({
36
+ ruleId: input.ruleId,
37
+ rulesContent: input.rulesContent,
38
+ reviewTarget: input.reviewTarget,
39
+ }),
40
+ tools: RESTRICTED_TOOLSET,
41
+ allowedTools: ALWAYS_ALLOWED_TOOLS,
42
+ mcpServers: {
43
+ revu: {
44
+ type: "http",
45
+ url: input.mcp.url,
46
+ headers: {
47
+ Authorization: `Bearer ${input.mcp.authToken}`,
48
+ "X-Revu-Rule-Id": input.ruleId,
49
+ },
50
+ },
51
+ },
52
+ canUseTool: async (toolName, toolInput) => {
53
+ if (toolName === "Bash") {
54
+ const command = typeof toolInput.command === "string" ? toolInput.command : "";
55
+ if (isReadOnlyShellCommand(command)) {
56
+ return { behavior: "allow", updatedInput: toolInput };
57
+ }
58
+ return {
59
+ behavior: "deny",
60
+ message: `Bash command rejected for safety: revu reviewers may only run read-only commands (git diff/log/show/status, cat, head, tail, ls, wc, find). Got: ${truncate(command, 200)}`,
61
+ };
62
+ }
63
+ return { behavior: "allow", updatedInput: toolInput };
64
+ },
65
+ permissionMode: "default",
66
+ settingSources: [],
67
+ persistSession: false,
68
+ abortController: abort,
69
+ stderr: (data) => {
70
+ if (process.env.REVU_DEBUG) {
71
+ process.stderr.write(`[${input.ruleId}] ${data}`);
72
+ }
73
+ },
74
+ },
75
+ });
76
+ // Drain the message stream. Findings flow through the MCP sidecar; we
77
+ // watch for a `result` message so we can surface SDK errors meaningfully.
78
+ // The agent SDK throws on non-zero subprocess exit AFTER emitting `result`,
79
+ // so we capture the result-derived error first and prefer it in the catch.
80
+ let resultErrorMessage;
81
+ try {
82
+ for await (const msg of q) {
83
+ const m = msg;
84
+ if (process.env.REVU_DEBUG) {
85
+ if (m.type === "result") {
86
+ process.stderr.write(`[${input.ruleId}] RESULT subtype=${m.subtype} is_error=${m.is_error} num_turns=${m.num_turns} errors=${JSON.stringify(m.errors)} result=${JSON.stringify(m.result)?.slice(0, 600)}\n`);
87
+ }
88
+ else if (m.type === "assistant") {
89
+ process.stderr.write(`[${input.ruleId}] ASSISTANT content=${JSON.stringify(m.message?.content)?.slice(0, 800)}\n`);
90
+ }
91
+ else if (m.type === "system") {
92
+ process.stderr.write(`[${input.ruleId}] system\n`);
93
+ }
94
+ else {
95
+ process.stderr.write(`[${input.ruleId}] msg.type=${m.type}\n`);
96
+ }
97
+ }
98
+ if (m.type === "assistant" && input.onActivity) {
99
+ emitAssistantActivity(m.message?.content, input.onActivity);
100
+ }
101
+ if (m.type === "result" && (m.is_error || m.subtype !== "success")) {
102
+ const text = m.result ?? m.errors?.join("; ") ?? "unknown error";
103
+ resultErrorMessage = m.subtype === "success"
104
+ ? text
105
+ : `${m.subtype ?? "error"}: ${text}`;
106
+ }
107
+ }
108
+ }
109
+ catch (streamErr) {
110
+ // If the stream throws but we already captured a meaningful result-level
111
+ // error, that's the one to surface — the stream throw is a downstream
112
+ // symptom of the same condition.
113
+ if (!resultErrorMessage) {
114
+ resultErrorMessage = streamErr.message ?? String(streamErr);
115
+ }
116
+ }
117
+ if (timedOut) {
118
+ return {
119
+ ruleId: input.ruleId,
120
+ ok: false,
121
+ durationMs: Date.now() - start,
122
+ errorMessage: `timed out after ${input.timeoutMs}ms`,
123
+ timedOut: true,
124
+ };
125
+ }
126
+ if (resultErrorMessage) {
127
+ return {
128
+ ruleId: input.ruleId,
129
+ ok: false,
130
+ durationMs: Date.now() - start,
131
+ errorMessage: resultErrorMessage,
132
+ };
133
+ }
134
+ return { ruleId: input.ruleId, ok: true, durationMs: Date.now() - start };
135
+ }
136
+ catch (e) {
137
+ if (timedOut) {
138
+ return {
139
+ ruleId: input.ruleId,
140
+ ok: false,
141
+ durationMs: Date.now() - start,
142
+ errorMessage: `timed out after ${input.timeoutMs}ms`,
143
+ timedOut: true,
144
+ };
145
+ }
146
+ return {
147
+ ruleId: input.ruleId,
148
+ ok: false,
149
+ durationMs: Date.now() - start,
150
+ errorMessage: e.message ?? String(e),
151
+ };
152
+ }
153
+ finally {
154
+ if (timer)
155
+ clearTimeout(timer);
156
+ }
157
+ },
158
+ });
159
+ const SAFE_LEADING_BINS = new Set([
160
+ "git",
161
+ "cat",
162
+ "head",
163
+ "tail",
164
+ "ls",
165
+ "wc",
166
+ "find",
167
+ "pwd",
168
+ "echo",
169
+ "grep",
170
+ "rg",
171
+ "awk",
172
+ "sed",
173
+ "sort",
174
+ "uniq",
175
+ "tr",
176
+ "cut",
177
+ "tee",
178
+ "true",
179
+ "false",
180
+ "test",
181
+ "[",
182
+ "stat",
183
+ "file",
184
+ "basename",
185
+ "dirname",
186
+ "realpath",
187
+ "readlink",
188
+ ]);
189
+ const FORBIDDEN_GIT_SUBCOMMANDS = new Set([
190
+ "push",
191
+ "commit",
192
+ "checkout",
193
+ "reset",
194
+ "rebase",
195
+ "merge",
196
+ "pull",
197
+ "fetch",
198
+ "clone",
199
+ "tag",
200
+ "rm",
201
+ "restore",
202
+ "stash",
203
+ "apply",
204
+ "am",
205
+ "cherry-pick",
206
+ "switch",
207
+ "remote",
208
+ "init",
209
+ "clean",
210
+ "gc",
211
+ "prune",
212
+ "config",
213
+ "submodule",
214
+ "worktree",
215
+ "filter-branch",
216
+ "filter-repo",
217
+ "update-ref",
218
+ "update-index",
219
+ "hash-object",
220
+ ]);
221
+ export function isReadOnlyShellCommand(command) {
222
+ const trimmed = command.trim();
223
+ if (trimmed.length === 0)
224
+ return false;
225
+ if (trimmed.includes("`"))
226
+ return false; // backtick command substitution
227
+ if (/\$\(/.test(trimmed))
228
+ return false; // $(...) command substitution
229
+ if (/[><]/.test(trimmed))
230
+ return false; // redirects
231
+ if (/(^|\s)(&&|\|\||;|&)(\s|$)/.test(trimmed))
232
+ return false; // chained / backgrounded
233
+ // Allow piping between safe binaries.
234
+ const segments = trimmed.split("|").map((s) => s.trim()).filter(Boolean);
235
+ if (segments.length === 0)
236
+ return false;
237
+ for (const seg of segments) {
238
+ const tokens = seg.split(/\s+/).filter(Boolean);
239
+ if (tokens.length === 0)
240
+ return false;
241
+ const bin = (tokens[0] ?? "").replace(/^.*\//, "");
242
+ if (!SAFE_LEADING_BINS.has(bin))
243
+ return false;
244
+ if (bin === "git") {
245
+ const sub = (tokens[1] ?? "").toLowerCase();
246
+ if (!sub || sub.startsWith("-"))
247
+ return false;
248
+ if (FORBIDDEN_GIT_SUBCOMMANDS.has(sub))
249
+ return false;
250
+ }
251
+ }
252
+ return true;
253
+ }
254
+ function truncate(s, n) {
255
+ return s.length > n ? `${s.slice(0, n)}…` : s;
256
+ }
257
+ function emitAssistantActivity(content, onActivity) {
258
+ if (!Array.isArray(content))
259
+ return;
260
+ for (const block of content) {
261
+ if (block.type === "tool_use" && typeof block.name === "string") {
262
+ onActivity({
263
+ kind: "tool",
264
+ name: block.name,
265
+ detail: summarizeToolInput(block.name, block.input),
266
+ });
267
+ }
268
+ else if (block.type === "text" && typeof block.text === "string") {
269
+ const trimmed = block.text.trim();
270
+ if (trimmed)
271
+ onActivity({ kind: "text", detail: truncate(trimmed.replace(/\s+/g, " "), 120) });
272
+ }
273
+ }
274
+ }
275
+ function summarizeToolInput(name, input) {
276
+ const i = (input ?? {});
277
+ if (name === "Bash" && typeof i["command"] === "string") {
278
+ return truncate(i["command"].replace(/\s+/g, " "), 90);
279
+ }
280
+ if (name === "Read" && typeof i["file_path"] === "string") {
281
+ return i["file_path"];
282
+ }
283
+ if (name === "Grep" && typeof i["pattern"] === "string") {
284
+ const path = typeof i["path"] === "string" ? ` in ${i["path"]}` : "";
285
+ return `${i["pattern"]}${path}`;
286
+ }
287
+ if (name === "Glob" && typeof i["pattern"] === "string") {
288
+ return i["pattern"];
289
+ }
290
+ if (name === "Write" && typeof i["file_path"] === "string") {
291
+ return i["file_path"];
292
+ }
293
+ if (name.startsWith("mcp__")) {
294
+ // Most useful for our own report_finding tool.
295
+ if (typeof i["severity"] === "string" && typeof i["path"] === "string") {
296
+ const line = typeof i["line"] === "number" ? `:${i["line"]}` : "";
297
+ return `${i["severity"]} ${i["path"]}${line}`;
298
+ }
299
+ }
300
+ // Generic fallback: short stringify.
301
+ try {
302
+ const s = JSON.stringify(i);
303
+ return truncate(s, 90);
304
+ }
305
+ catch {
306
+ return "";
307
+ }
308
+ }
309
+ /**
310
+ * The scaffold agent is allowed to call `Write`, but only on `.revu.md` files
311
+ * that resolve to a path inside the repo root. Anything else is denied.
312
+ */
313
+ export function isAllowedRuleFileWrite(repoRoot, filePath) {
314
+ if (typeof filePath !== "string" || filePath.length === 0)
315
+ return false;
316
+ if (!/\.revu\.md$/.test(filePath))
317
+ return false;
318
+ const abs = isAbsolute(filePath) ? filePath : resolve(repoRoot, filePath);
319
+ const rel = relative(resolve(repoRoot), abs);
320
+ if (rel === "" || rel.startsWith("..") || isAbsolute(rel))
321
+ return false;
322
+ return true;
323
+ }
324
+ const SCAFFOLD_TOOLSET = ["Read", "Grep", "Glob", "Bash", "Write"];
325
+ const SCAFFOLD_ALWAYS_ALLOWED = ["Read", "Grep", "Glob"];
326
+ export const claudeCodeScaffoldProvider = (cfg) => ({
327
+ name: "claude-code",
328
+ async run(input) {
329
+ const start = Date.now();
330
+ const abort = new AbortController();
331
+ if (input.signal) {
332
+ input.signal.addEventListener("abort", () => abort.abort(), { once: true });
333
+ }
334
+ let timedOut = false;
335
+ const timer = input.timeoutMs && input.timeoutMs > 0
336
+ ? setTimeout(() => {
337
+ timedOut = true;
338
+ abort.abort();
339
+ }, input.timeoutMs)
340
+ : undefined;
341
+ const filesWritten = [];
342
+ try {
343
+ const q = query({
344
+ prompt: buildInitUserPrompt({ repoRoot: input.repoRoot, force: input.force }),
345
+ options: {
346
+ cwd: input.repoRoot,
347
+ ...(cfg.model ? { model: cfg.model } : {}),
348
+ systemPrompt: buildInitSystemPrompt({ force: input.force }),
349
+ tools: SCAFFOLD_TOOLSET,
350
+ allowedTools: SCAFFOLD_ALWAYS_ALLOWED,
351
+ canUseTool: async (toolName, toolInput) => {
352
+ if (toolName === "Bash") {
353
+ const command = typeof toolInput["command"] === "string" ? toolInput["command"] : "";
354
+ if (isReadOnlyShellCommand(command)) {
355
+ return { behavior: "allow", updatedInput: toolInput };
356
+ }
357
+ return {
358
+ behavior: "deny",
359
+ message: `Bash command rejected for safety: scaffold may only run read-only commands. Got: ${truncate(command, 200)}`,
360
+ };
361
+ }
362
+ if (toolName === "Write") {
363
+ if (isAllowedRuleFileWrite(input.repoRoot, toolInput["file_path"])) {
364
+ return { behavior: "allow", updatedInput: toolInput };
365
+ }
366
+ return {
367
+ behavior: "deny",
368
+ message: "scaffold may only Write `.revu.md` files inside the repository. Refusing this path. " +
369
+ "Globals go in `.revu/<topic>.revu.md`; locals go alongside the thing they cover as `<dir>/<topic>.revu.md`.",
370
+ };
371
+ }
372
+ if (toolName === "Edit" || toolName === "MultiEdit" || toolName === "NotebookEdit") {
373
+ return {
374
+ behavior: "deny",
375
+ message: `scaffold must use Write (not ${toolName}) when creating rule files.`,
376
+ };
377
+ }
378
+ return { behavior: "allow", updatedInput: toolInput };
379
+ },
380
+ permissionMode: "default",
381
+ settingSources: [],
382
+ persistSession: false,
383
+ abortController: abort,
384
+ stderr: (data) => {
385
+ if (process.env.REVU_DEBUG) {
386
+ process.stderr.write(`[scaffold] ${data}`);
387
+ }
388
+ },
389
+ },
390
+ });
391
+ let resultErrorMessage;
392
+ try {
393
+ for await (const msg of q) {
394
+ const m = msg;
395
+ if (process.env.REVU_DEBUG) {
396
+ if (m.type === "result") {
397
+ process.stderr.write(`[scaffold] RESULT subtype=${m.subtype} is_error=${m.is_error} num_turns=${m.num_turns} errors=${JSON.stringify(m.errors)} result=${JSON.stringify(m.result)?.slice(0, 600)}\n`);
398
+ }
399
+ else if (m.type === "assistant") {
400
+ process.stderr.write(`[scaffold] ASSISTANT content=${JSON.stringify(m.message?.content)?.slice(0, 800)}\n`);
401
+ }
402
+ else {
403
+ process.stderr.write(`[scaffold] msg.type=${m.type}\n`);
404
+ }
405
+ }
406
+ if (m.type === "assistant") {
407
+ // Stream activity AND notice successful Write tool_use blocks so we can
408
+ // record what got written and emit live "✱ created ..." lines.
409
+ const content = m.message?.content;
410
+ if (Array.isArray(content)) {
411
+ for (const block of content) {
412
+ if (block.type === "tool_use" && block.name === "Write") {
413
+ const fp = block.input?.file_path;
414
+ if (typeof fp === "string" && isAllowedRuleFileWrite(input.repoRoot, fp)) {
415
+ const abs = isAbsolute(fp) ? fp : resolve(input.repoRoot, fp);
416
+ const rel = relative(resolve(input.repoRoot), abs).split("\\").join("/");
417
+ filesWritten.push(rel);
418
+ input.onFileWritten?.(rel);
419
+ }
420
+ }
421
+ }
422
+ }
423
+ if (input.onActivity)
424
+ emitAssistantActivity(content, input.onActivity);
425
+ }
426
+ if (m.type === "result" && (m.is_error || m.subtype !== "success")) {
427
+ const text = m.result ?? m.errors?.join("; ") ?? "unknown error";
428
+ resultErrorMessage = m.subtype === "success"
429
+ ? text
430
+ : `${m.subtype ?? "error"}: ${text}`;
431
+ }
432
+ }
433
+ }
434
+ catch (streamErr) {
435
+ if (!resultErrorMessage) {
436
+ resultErrorMessage = streamErr.message ?? String(streamErr);
437
+ }
438
+ }
439
+ if (timedOut) {
440
+ return {
441
+ ok: false,
442
+ durationMs: Date.now() - start,
443
+ filesWritten,
444
+ errorMessage: `timed out after ${input.timeoutMs}ms`,
445
+ timedOut: true,
446
+ };
447
+ }
448
+ if (resultErrorMessage) {
449
+ return {
450
+ ok: false,
451
+ durationMs: Date.now() - start,
452
+ filesWritten,
453
+ errorMessage: resultErrorMessage,
454
+ };
455
+ }
456
+ return { ok: true, durationMs: Date.now() - start, filesWritten };
457
+ }
458
+ catch (e) {
459
+ if (timedOut) {
460
+ return {
461
+ ok: false,
462
+ durationMs: Date.now() - start,
463
+ filesWritten,
464
+ errorMessage: `timed out after ${input.timeoutMs}ms`,
465
+ timedOut: true,
466
+ };
467
+ }
468
+ return {
469
+ ok: false,
470
+ durationMs: Date.now() - start,
471
+ filesWritten,
472
+ errorMessage: e.message ?? String(e),
473
+ };
474
+ }
475
+ finally {
476
+ if (timer)
477
+ clearTimeout(timer);
478
+ }
479
+ },
480
+ });
481
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/providers/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAY9D,MAAM,oBAAoB,GAAG;IAC3B,MAAM;IACN,MAAM;IACN,MAAM;IACN,2BAA2B;CAC5B,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,kBAAkB,GAAuB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9D,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,GAAG,CAAC,KAAkB;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC;YAClD,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;YACrB,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,KAAK,CAAC;gBACd,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC;gBAC3C,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,QAAQ;oBACnB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,YAAY,EAAE,iBAAiB,CAAC;wBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,YAAY,EAAE,KAAK,CAAC,YAAY;wBAChC,YAAY,EAAE,KAAK,CAAC,YAAY;qBACjC,CAAC;oBACF,KAAK,EAAE,kBAAkB;oBACzB,YAAY,EAAE,oBAAoB;oBAClC,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,MAAM;4BACZ,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG;4BAClB,OAAO,EAAE;gCACP,aAAa,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE;gCAC9C,gBAAgB,EAAE,KAAK,CAAC,MAAM;6BAC/B;yBACF;qBACF;oBACD,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;wBACxC,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;4BACxB,MAAM,OAAO,GAAG,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC/E,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;gCACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;4BACxD,CAAC;4BACD,OAAO;gCACL,QAAQ,EAAE,MAAM;gCAChB,OAAO,EAAE,oJAAoJ,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;6BACtL,CAAC;wBACJ,CAAC;wBACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;oBACxD,CAAC;oBACD,cAAc,EAAE,SAAS;oBACzB,cAAc,EAAE,EAAE;oBAClB,cAAc,EAAE,KAAK;oBACrB,eAAe,EAAE,KAAK;oBACtB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;wBACvB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;4BAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;wBACpD,CAAC;oBACH,CAAC;iBACF;aACF,CAAC,CAAC;YAEH,sEAAsE;YACtE,0EAA0E;YAC1E,4EAA4E;YAC5E,2EAA2E;YAC3E,IAAI,kBAAsC,CAAC;YAE3C,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,GAAG,GAQT,CAAC;oBACF,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;wBAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,KAAK,CAAC,MAAM,oBAAoB,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,QAAQ,cAAc,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CACvL,CAAC;wBACJ,CAAC;6BAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;4BAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,KAAK,CAAC,MAAM,uBAAuB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAC7F,CAAC;wBACJ,CAAC;6BAAM,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC;wBACrD,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,cAAc,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;wBACjE,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;wBAC/C,qBAAqB,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;oBAC9D,CAAC;oBACD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;wBACnE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;wBACjE,kBAAkB,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS;4BAC1C,CAAC,CAAC,IAAI;4BACN,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,yEAAyE;gBACzE,sEAAsE;gBACtE,iCAAiC;gBACjC,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,kBAAkB,GAAI,SAAmB,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY,EAAE,mBAAmB,KAAK,CAAC,SAAS,IAAI;oBACpD,QAAQ,EAAE,IAAI;iBACf,CAAC;YACJ,CAAC;YACD,IAAI,kBAAkB,EAAE,CAAC;gBACvB,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY,EAAE,kBAAkB;iBACjC,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;QAC5E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY,EAAE,mBAAmB,KAAK,CAAC,SAAS,IAAI;oBACpD,QAAQ,EAAE,IAAI;iBACf,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,EAAE,EAAE,KAAK;gBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAC9B,YAAY,EAAG,CAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC;aAChD,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,GAAG;IACH,MAAM;IACN,MAAM;IACN,UAAU;IACV,SAAS;IACT,UAAU;IACV,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IACxC,MAAM;IACN,QAAQ;IACR,UAAU;IACV,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,KAAK;IACL,IAAI;IACJ,SAAS;IACT,OAAO;IACP,OAAO;IACP,IAAI;IACJ,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,OAAO;IACP,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,WAAW;IACX,UAAU;IACV,eAAe;IACf,aAAa;IACb,YAAY;IACZ,cAAc;IACd,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,CAAW,gCAAgC;IACnF,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,CAAY,8BAA8B;IACjF,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,CAAY,YAAY;IAC/D,IAAI,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,yBAAyB;IAEtF,sCAAsC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC9C,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC9C,IAAI,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QACvD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgB,EAAE,UAAuC;IACtF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO;IACpC,KAAK,MAAM,KAAK,IAAI,OAAkF,EAAE,CAAC;QACvG,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChE,UAAU,CAAC;gBACT,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;aACpD,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,OAAO;gBAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,KAAc;IACtD,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;IACnD,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAE,CAAC,CAAC,SAAS,CAAY,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1D,OAAO,CAAC,CAAC,WAAW,CAAW,CAAC;IAClC,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,CAAC,CAAC,SAAS,CAAW,CAAC;IAChC,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC3D,OAAO,CAAC,CAAC,WAAW,CAAW,CAAC;IAClC,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,+CAA+C;QAC/C,IAAI,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACvE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IACD,qCAAqC;IACrC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC5B,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,QAAiB;IACxE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACxE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACnE,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,0BAA0B,GAAyB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxE,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,GAAG,CAAC,KAAoB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC;YAClD,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;YACrB,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,KAAK,CAAC;gBACd,MAAM,EAAE,mBAAmB,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC7E,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,QAAQ;oBACnB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1C,YAAY,EAAE,qBAAqB,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;oBAC3D,KAAK,EAAE,gBAAgB;oBACvB,YAAY,EAAE,uBAAuB;oBACrC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;wBACxC,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;4BACxB,MAAM,OAAO,GAAG,OAAO,SAAS,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,SAAS,CAAC,SAAS,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC;4BACjG,IAAI,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;gCACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;4BACxD,CAAC;4BACD,OAAO;gCACL,QAAQ,EAAE,MAAM;gCAChB,OAAO,EAAE,oFAAoF,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;6BACtH,CAAC;wBACJ,CAAC;wBACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;4BACzB,IAAI,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;gCACnE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;4BACxD,CAAC;4BACD,OAAO;gCACL,QAAQ,EAAE,MAAM;gCAChB,OAAO,EACL,sFAAsF;oCACtF,6GAA6G;6BAChH,CAAC;wBACJ,CAAC;wBACD,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;4BACnF,OAAO;gCACL,QAAQ,EAAE,MAAM;gCAChB,OAAO,EAAE,gCAAgC,QAAQ,6BAA6B;6BAC/E,CAAC;wBACJ,CAAC;wBACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;oBACxD,CAAC;oBACD,cAAc,EAAE,SAAS;oBACzB,cAAc,EAAE,EAAE;oBAClB,cAAc,EAAE,KAAK;oBACrB,eAAe,EAAE,KAAK;oBACtB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;wBACvB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;4BAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;wBAC7C,CAAC;oBACH,CAAC;iBACF;aACF,CAAC,CAAC;YAEH,IAAI,kBAAsC,CAAC;YAE3C,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,GAAG,GAQT,CAAC;oBACF,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;wBAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6BAA6B,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,QAAQ,cAAc,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAChL,CAAC;wBACJ,CAAC;6BAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;4BAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gCAAgC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CACtF,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;wBAC1D,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBAC3B,wEAAwE;wBACxE,+DAA+D;wBAC/D,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;wBACnC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC3B,KAAK,MAAM,KAAK,IAAI,OAAmE,EAAE,CAAC;gCACxF,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oCACxD,MAAM,EAAE,GAAI,KAAK,CAAC,KAA6C,EAAE,SAAS,CAAC;oCAC3E,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;wCACzE,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;wCAC9D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wCACzE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wCACvB,KAAK,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC;oCAC7B,CAAC;gCACH,CAAC;4BACH,CAAC;wBACH,CAAC;wBACD,IAAI,KAAK,CAAC,UAAU;4BAAE,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;oBACzE,CAAC;oBACD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;wBACnE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;wBACjE,kBAAkB,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS;4BAC1C,CAAC,CAAC,IAAI;4BACN,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,kBAAkB,GAAI,SAAmB,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY;oBACZ,YAAY,EAAE,mBAAmB,KAAK,CAAC,SAAS,IAAI;oBACpD,QAAQ,EAAE,IAAI;iBACf,CAAC;YACJ,CAAC;YACD,IAAI,kBAAkB,EAAE,CAAC;gBACvB,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY;oBACZ,YAAY,EAAE,kBAAkB;iBACjC,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,CAAC;QACpE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,YAAY;oBACZ,YAAY,EAAE,mBAAmB,KAAK,CAAC,SAAS,IAAI;oBACpD,QAAQ,EAAE,IAAI;iBACf,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAC9B,YAAY;gBACZ,YAAY,EAAG,CAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC;aAChD,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ReviewAgentFactory, ScaffoldAgentFactory } from "./types.js";
2
+ export declare function registerProvider(name: string, factory: ReviewAgentFactory): void;
3
+ export declare function unregisterProvider(name: string): void;
4
+ export declare function registerScaffoldProvider(name: string, factory: ScaffoldAgentFactory): void;
5
+ export declare function unregisterScaffoldProvider(name: string): void;
6
+ export declare function getProviderFactory(name: string): ReviewAgentFactory;
7
+ export declare function getScaffoldFactory(name: string): ScaffoldAgentFactory;
8
+ export declare function listProviders(): string[];
@@ -0,0 +1,60 @@
1
+ import { claudeCodeProvider, claudeCodeScaffoldProvider } from "./claude-code.js";
2
+ const REGISTRY = new Map([
3
+ [
4
+ "claude-code",
5
+ {
6
+ review: claudeCodeProvider,
7
+ scaffold: claudeCodeScaffoldProvider,
8
+ },
9
+ ],
10
+ ]);
11
+ function entry(name) {
12
+ let e = REGISTRY.get(name);
13
+ if (!e) {
14
+ e = {};
15
+ REGISTRY.set(name, e);
16
+ }
17
+ return e;
18
+ }
19
+ export function registerProvider(name, factory) {
20
+ entry(name).review = factory;
21
+ }
22
+ export function unregisterProvider(name) {
23
+ const e = REGISTRY.get(name);
24
+ if (!e)
25
+ return;
26
+ delete e.review;
27
+ if (!e.review && !e.scaffold)
28
+ REGISTRY.delete(name);
29
+ }
30
+ export function registerScaffoldProvider(name, factory) {
31
+ entry(name).scaffold = factory;
32
+ }
33
+ export function unregisterScaffoldProvider(name) {
34
+ const e = REGISTRY.get(name);
35
+ if (!e)
36
+ return;
37
+ delete e.scaffold;
38
+ if (!e.review && !e.scaffold)
39
+ REGISTRY.delete(name);
40
+ }
41
+ export function getProviderFactory(name) {
42
+ const factory = REGISTRY.get(name)?.review;
43
+ if (!factory) {
44
+ const known = [...REGISTRY.entries()].filter(([, e]) => e.review).map(([k]) => k).join(", ");
45
+ throw new Error(`Unknown review provider "${name}". Known: ${known}`);
46
+ }
47
+ return factory;
48
+ }
49
+ export function getScaffoldFactory(name) {
50
+ const factory = REGISTRY.get(name)?.scaffold;
51
+ if (!factory) {
52
+ const known = [...REGISTRY.entries()].filter(([, e]) => e.scaffold).map(([k]) => k).join(", ");
53
+ throw new Error(`Unknown scaffold provider "${name}". Known: ${known}`);
54
+ }
55
+ return factory;
56
+ }
57
+ export function listProviders() {
58
+ return [...REGISTRY.keys()];
59
+ }
60
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { ReviewTarget } from "../types.js";
2
+ export interface ReviewActivity {
3
+ /** "tool" for tool-use, "text" for assistant prose. */
4
+ kind: "tool" | "text";
5
+ /** For tool: tool name (e.g. "Bash", "Read", "mcp__revu__report_finding"). */
6
+ name?: string;
7
+ /** Brief one-line summary suitable for terminal printing. */
8
+ detail: string;
9
+ }
10
+ export interface ReviewInput {
11
+ ruleId: string;
12
+ rulesFilePath: string;
13
+ rulesContent: string;
14
+ reviewTarget: ReviewTarget;
15
+ repoRoot: string;
16
+ mcp: {
17
+ url: string;
18
+ authToken: string;
19
+ };
20
+ /** Hard wall-clock cutoff for this single agent run. */
21
+ timeoutMs?: number;
22
+ signal?: AbortSignal;
23
+ /** Optional progress callback — providers should call this for tool use / text turns. */
24
+ onActivity?: (activity: ReviewActivity) => void;
25
+ }
26
+ export interface ReviewResult {
27
+ ruleId: string;
28
+ ok: boolean;
29
+ durationMs: number;
30
+ errorMessage?: string;
31
+ /** True when the agent was stopped by the per-rule timeout. */
32
+ timedOut?: boolean;
33
+ }
34
+ export interface ReviewAgent {
35
+ readonly name: string;
36
+ run(input: ReviewInput): Promise<ReviewResult>;
37
+ }
38
+ export interface ReviewAgentFactory {
39
+ (cfg: {
40
+ model?: string;
41
+ }): ReviewAgent;
42
+ }
43
+ export interface ScaffoldInput {
44
+ repoRoot: string;
45
+ /** If true, the agent may overwrite rule files it decides to (re)create. */
46
+ force: boolean;
47
+ timeoutMs?: number;
48
+ signal?: AbortSignal;
49
+ /** Same shape as the review path — useful for live progress streaming. */
50
+ onActivity?: (activity: ReviewActivity) => void;
51
+ /** Fires once per `.revu.md` file the agent successfully writes. */
52
+ onFileWritten?: (relPath: string) => void;
53
+ }
54
+ export interface ScaffoldResult {
55
+ ok: boolean;
56
+ durationMs: number;
57
+ /** Repo-relative paths of every `.revu.md` file the agent wrote. */
58
+ filesWritten: string[];
59
+ errorMessage?: string;
60
+ timedOut?: boolean;
61
+ }
62
+ export interface ScaffoldAgent {
63
+ readonly name: string;
64
+ run(input: ScaffoldInput): Promise<ScaffoldResult>;
65
+ }
66
+ export interface ScaffoldAgentFactory {
67
+ (cfg: {
68
+ model?: string;
69
+ }): ScaffoldAgent;
70
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}