review-council 1.0.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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +210 -0
  3. package/dist/config/defaults.d.ts +17 -0
  4. package/dist/config/defaults.js +27 -0
  5. package/dist/config/defaults.js.map +1 -0
  6. package/dist/config/loader.d.ts +2 -0
  7. package/dist/config/loader.js +66 -0
  8. package/dist/config/loader.js.map +1 -0
  9. package/dist/config/schema.d.ts +79 -0
  10. package/dist/config/schema.js +49 -0
  11. package/dist/config/schema.js.map +1 -0
  12. package/dist/consensus/deduper.d.ts +6 -0
  13. package/dist/consensus/deduper.js +127 -0
  14. package/dist/consensus/deduper.js.map +1 -0
  15. package/dist/consensus/parser.d.ts +6 -0
  16. package/dist/consensus/parser.js +90 -0
  17. package/dist/consensus/parser.js.map +1 -0
  18. package/dist/consensus/types.d.ts +57 -0
  19. package/dist/consensus/types.js +2 -0
  20. package/dist/consensus/types.js.map +1 -0
  21. package/dist/consensus/voter.d.ts +3 -0
  22. package/dist/consensus/voter.js +198 -0
  23. package/dist/consensus/voter.js.map +1 -0
  24. package/dist/dispatch/adapter.d.ts +15 -0
  25. package/dist/dispatch/adapter.js +24 -0
  26. package/dist/dispatch/adapter.js.map +1 -0
  27. package/dist/dispatch/anthropic.d.ts +9 -0
  28. package/dist/dispatch/anthropic.js +132 -0
  29. package/dist/dispatch/anthropic.js.map +1 -0
  30. package/dist/dispatch/google.d.ts +9 -0
  31. package/dist/dispatch/google.js +87 -0
  32. package/dist/dispatch/google.js.map +1 -0
  33. package/dist/dispatch/openai-compat.d.ts +18 -0
  34. package/dist/dispatch/openai-compat.js +90 -0
  35. package/dist/dispatch/openai-compat.js.map +1 -0
  36. package/dist/dispatch/openai.d.ts +9 -0
  37. package/dist/dispatch/openai.js +90 -0
  38. package/dist/dispatch/openai.js.map +1 -0
  39. package/dist/dispatch/runner.d.ts +11 -0
  40. package/dist/dispatch/runner.js +67 -0
  41. package/dist/dispatch/runner.js.map +1 -0
  42. package/dist/dispatch/utils.d.ts +6 -0
  43. package/dist/dispatch/utils.js +15 -0
  44. package/dist/dispatch/utils.js.map +1 -0
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +262 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/output/github.d.ts +3 -0
  49. package/dist/output/github.js +95 -0
  50. package/dist/output/github.js.map +1 -0
  51. package/dist/output/json.d.ts +3 -0
  52. package/dist/output/json.js +8 -0
  53. package/dist/output/json.js.map +1 -0
  54. package/dist/output/markdown.d.ts +3 -0
  55. package/dist/output/markdown.js +81 -0
  56. package/dist/output/markdown.js.map +1 -0
  57. package/dist/output/terminal.d.ts +2 -0
  58. package/dist/output/terminal.js +141 -0
  59. package/dist/output/terminal.js.map +1 -0
  60. package/dist/prepare/chunker.d.ts +9 -0
  61. package/dist/prepare/chunker.js +62 -0
  62. package/dist/prepare/chunker.js.map +1 -0
  63. package/dist/prepare/language.d.ts +1 -0
  64. package/dist/prepare/language.js +99 -0
  65. package/dist/prepare/language.js.map +1 -0
  66. package/dist/prepare/prompt-builder.d.ts +11 -0
  67. package/dist/prepare/prompt-builder.js +65 -0
  68. package/dist/prepare/prompt-builder.js.map +1 -0
  69. package/dist/prompts/base.d.ts +3 -0
  70. package/dist/prompts/base.js +53 -0
  71. package/dist/prompts/base.js.map +1 -0
  72. package/dist/prompts/hardening.d.ts +7 -0
  73. package/dist/prompts/hardening.js +30 -0
  74. package/dist/prompts/hardening.js.map +1 -0
  75. package/dist/prompts/languages/elixir.d.ts +1 -0
  76. package/dist/prompts/languages/elixir.js +13 -0
  77. package/dist/prompts/languages/elixir.js.map +1 -0
  78. package/dist/prompts/languages/generic.d.ts +1 -0
  79. package/dist/prompts/languages/generic.js +11 -0
  80. package/dist/prompts/languages/generic.js.map +1 -0
  81. package/dist/prompts/languages/python.d.ts +1 -0
  82. package/dist/prompts/languages/python.js +14 -0
  83. package/dist/prompts/languages/python.js.map +1 -0
  84. package/dist/prompts/languages/typescript.d.ts +1 -0
  85. package/dist/prompts/languages/typescript.js +13 -0
  86. package/dist/prompts/languages/typescript.js.map +1 -0
  87. package/dist/resolver/github.d.ts +8 -0
  88. package/dist/resolver/github.js +70 -0
  89. package/dist/resolver/github.js.map +1 -0
  90. package/dist/resolver/local.d.ts +3 -0
  91. package/dist/resolver/local.js +75 -0
  92. package/dist/resolver/local.js.map +1 -0
  93. package/dist/resolver/types.d.ts +28 -0
  94. package/dist/resolver/types.js +2 -0
  95. package/dist/resolver/types.js.map +1 -0
  96. package/dist/roles/builtin.d.ts +4 -0
  97. package/dist/roles/builtin.js +234 -0
  98. package/dist/roles/builtin.js.map +1 -0
  99. package/dist/roles/dispatcher.d.ts +23 -0
  100. package/dist/roles/dispatcher.js +87 -0
  101. package/dist/roles/dispatcher.js.map +1 -0
  102. package/dist/roles/loader.d.ts +11 -0
  103. package/dist/roles/loader.js +107 -0
  104. package/dist/roles/loader.js.map +1 -0
  105. package/dist/roles/types.d.ts +13 -0
  106. package/dist/roles/types.js +2 -0
  107. package/dist/roles/types.js.map +1 -0
  108. package/package.json +67 -0
@@ -0,0 +1,75 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { detectLanguage } from '../prepare/language.js';
3
+ function parseDiffText(diffText) {
4
+ const hunks = [];
5
+ const fileBlocks = diffText.split(/^diff --git /m).filter(Boolean);
6
+ for (const block of fileBlocks) {
7
+ const lines = block.split('\n');
8
+ const headerLine = lines[0] ?? '';
9
+ // Extract filenames from "a/path b/path"
10
+ const headerMatch = headerLine.match(/^a\/(.+) b\/(.+)$/);
11
+ if (!headerMatch)
12
+ continue;
13
+ const aPath = headerMatch[1];
14
+ const bPath = headerMatch[2];
15
+ let status = 'modified';
16
+ let previousFilename;
17
+ const deletedMatch = block.match(/^deleted file mode/m);
18
+ const newFileMatch = block.match(/^new file mode/m);
19
+ const renameFromMatch = block.match(/^rename from (.+)$/m);
20
+ const renameToMatch = block.match(/^rename to (.+)$/m);
21
+ if (deletedMatch) {
22
+ status = 'deleted';
23
+ }
24
+ else if (newFileMatch) {
25
+ status = 'added';
26
+ }
27
+ else if (renameFromMatch && renameToMatch) {
28
+ status = 'renamed';
29
+ previousFilename = renameFromMatch[1].trim();
30
+ }
31
+ const filename = status === 'deleted' ? aPath : bPath;
32
+ // Extract the actual patch lines (@@...)
33
+ const patchStart = block.indexOf('\n@@');
34
+ const patch = patchStart >= 0 ? block.slice(patchStart + 1) : '';
35
+ let additions = 0;
36
+ let deletions = 0;
37
+ for (const line of patch.split('\n')) {
38
+ if (line.startsWith('+') && !line.startsWith('+++'))
39
+ additions++;
40
+ if (line.startsWith('-') && !line.startsWith('---'))
41
+ deletions++;
42
+ }
43
+ hunks.push({
44
+ filename,
45
+ status,
46
+ previousFilename,
47
+ patch,
48
+ additions,
49
+ deletions,
50
+ });
51
+ }
52
+ return hunks;
53
+ }
54
+ export async function loadLocalDiff(filePath) {
55
+ const content = await readFile(filePath, 'utf-8');
56
+ return parseDiffFromString(content);
57
+ }
58
+ export function parseDiffFromString(diffText) {
59
+ const hunks = parseDiffText(diffText);
60
+ const files = hunks.map((h) => ({
61
+ filename: h.filename,
62
+ status: h.status,
63
+ additions: h.additions,
64
+ deletions: h.deletions,
65
+ patch: h.patch,
66
+ language: detectLanguage(h.filename),
67
+ previousFilename: h.previousFilename,
68
+ }));
69
+ return {
70
+ files,
71
+ source: 'local',
72
+ rawDiff: diffText,
73
+ };
74
+ }
75
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/resolver/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export interface FileChange {
2
+ filename: string;
3
+ status: 'added' | 'modified' | 'deleted' | 'renamed';
4
+ additions: number;
5
+ deletions: number;
6
+ patch: string;
7
+ language: string;
8
+ previousFilename?: string;
9
+ }
10
+ export interface PRMetadata {
11
+ owner: string;
12
+ repo: string;
13
+ number: number;
14
+ title: string;
15
+ body: string;
16
+ author: string;
17
+ base: string;
18
+ head: string;
19
+ url: string;
20
+ labels: string[];
21
+ draft: boolean;
22
+ }
23
+ export interface Diff {
24
+ files: FileChange[];
25
+ metadata?: PRMetadata;
26
+ source: 'github' | 'local';
27
+ rawDiff?: string;
28
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/resolver/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { Role } from './types.js';
2
+ export declare const BUILTIN_ROLES: Role[];
3
+ export declare function getRoleByName(name: string): Role | undefined;
4
+ export declare function getBuiltinRoleNames(): string[];
@@ -0,0 +1,234 @@
1
+ export const BUILTIN_ROLES = [
2
+ {
3
+ name: 'general',
4
+ description: 'Comprehensive code review covering all dimensions',
5
+ isSpecialized: false,
6
+ focus: ['security', 'correctness', 'best-practices', 'tests', 'api-design'],
7
+ systemPrompt: `You are an expert code reviewer performing a comprehensive review. Your role is to identify all types of issues: security vulnerabilities, logic errors, performance problems, missing tests, API design flaws, and code quality issues.
8
+
9
+ Be thorough but focused — only report real issues visible in the diff. Prioritize severity accurately. Consider the full context of each change.`,
10
+ },
11
+ {
12
+ name: 'security-auditor',
13
+ description: 'Focused on security vulnerabilities: auth, injection, XSS, CSRF, IDOR',
14
+ isSpecialized: true,
15
+ focus: ['security'],
16
+ severityBias: { security: 1.2 },
17
+ systemPrompt: `You are a security-focused code reviewer with deep expertise in application security. Your primary mission is to identify security vulnerabilities and weaknesses.
18
+
19
+ Focus areas:
20
+ - Authentication and authorization flaws (broken auth, privilege escalation, IDOR)
21
+ - Injection vulnerabilities (SQL, NoSQL, command, LDAP, XPath injection)
22
+ - Cross-site scripting (XSS) — reflected, stored, and DOM-based
23
+ - Cross-site request forgery (CSRF)
24
+ - Sensitive data exposure (hardcoded secrets, improper encryption, insecure transmission)
25
+ - Security misconfigurations (debug mode in prod, overly permissive CORS, insecure defaults)
26
+ - Insecure deserialization
27
+ - Input validation failures
28
+ - Race conditions with security implications
29
+ - Dependency vulnerabilities (if visible)
30
+
31
+ Be specific about attack vectors and potential impact. Prefer security findings as "critical" or "important" when there is a real exploitable vulnerability.`,
32
+ },
33
+ {
34
+ name: 'performance-engineer',
35
+ description: 'Focus on performance: N+1 queries, caching, algorithmic complexity',
36
+ isSpecialized: true,
37
+ focus: ['correctness', 'best-practices'],
38
+ systemPrompt: `You are a performance-focused code reviewer. Your mission is to identify performance bottlenecks, inefficiencies, and scalability concerns.
39
+
40
+ Focus areas:
41
+ - N+1 query problems (database queries in loops)
42
+ - Missing database indexes (new query patterns without indexes)
43
+ - Inefficient algorithms (O(n²) when O(n log n) is available)
44
+ - Missing caching opportunities (repeated expensive computations)
45
+ - Memory inefficiencies (large object retention, missing streaming)
46
+ - Unnecessary computation (recalculating constants, redundant processing)
47
+ - Synchronous blocking in async contexts
48
+ - Large payload sizes (over-fetching, missing pagination)
49
+ - Connection pool exhaustion
50
+ - Missing batch operations
51
+
52
+ Estimate impact where possible (e.g., "for 10k rows, this will issue 10k queries").`,
53
+ },
54
+ {
55
+ name: 'api-design',
56
+ description: 'API contracts, backwards compatibility, interface design',
57
+ isSpecialized: true,
58
+ focus: ['api-design'],
59
+ systemPrompt: `You are an API design expert. Your mission is to evaluate the quality and correctness of API design, with particular attention to backwards compatibility and consumer experience.
60
+
61
+ Focus areas:
62
+ - Breaking changes to public APIs (changed signatures, removed fields, altered semantics)
63
+ - REST conventions (correct HTTP methods, status codes, resource naming)
64
+ - Backwards compatibility (new required fields, changed field types, deprecated but not removed)
65
+ - Versioning strategy
66
+ - Error response consistency
67
+ - Missing or inadequate API documentation
68
+ - Inconsistent naming conventions
69
+ - Overly coupled interfaces
70
+ - Missing pagination, filtering, or sorting for collection endpoints
71
+ - GraphQL: N+1 in resolvers, missing rate limiting, overly broad queries allowed
72
+ - gRPC/Protobuf: field numbering, backward compatibility of message changes
73
+
74
+ Flag breaking changes as "critical" severity.`,
75
+ },
76
+ {
77
+ name: 'test-coverage',
78
+ description: 'Missing tests, edge cases, flawed test logic',
79
+ isSpecialized: true,
80
+ focus: ['tests'],
81
+ systemPrompt: `You are a testing expert. Your mission is to evaluate test coverage quality and identify missing or inadequate tests.
82
+
83
+ Focus areas:
84
+ - Missing tests for new functionality added in the diff
85
+ - Edge cases not covered (empty inputs, null/undefined, boundary values, max values)
86
+ - Error path testing (what happens when things fail)
87
+ - Flawed test logic (tests that always pass, testing implementation not behavior)
88
+ - Test isolation issues (shared state, ordering dependencies, missing cleanup)
89
+ - Missing integration tests for critical paths
90
+ - Mocking anti-patterns (over-mocking, mocking what you own)
91
+ - Missing negative test cases
92
+ - Tests without assertions
93
+ - Brittle tests (relying on specific timing, order, or environment)
94
+
95
+ Suggest specific test cases and scenarios that should be covered.`,
96
+ },
97
+ {
98
+ name: 'dx-critic',
99
+ description: 'Developer experience: readability, naming, documentation',
100
+ isSpecialized: true,
101
+ focus: ['best-practices'],
102
+ systemPrompt: `You are a developer experience (DX) expert. Your mission is to evaluate code readability, maintainability, and developer ergonomics.
103
+
104
+ Focus areas:
105
+ - Poor naming (unclear variable/function/class names that don't convey intent)
106
+ - Excessive complexity (functions doing too many things, deep nesting)
107
+ - Missing or inadequate documentation (complex algorithms without explanation)
108
+ - Magic numbers and strings without constants
109
+ - Inconsistent patterns within the codebase
110
+ - Long functions that should be decomposed
111
+ - Unclear error messages (from the developer/user perspective)
112
+ - Missing or unhelpful logging
113
+ - Over-engineering (unnecessary abstraction layers)
114
+ - Code duplication that should be extracted
115
+ - Confusing control flow
116
+
117
+ Be constructive — suggest better names and approaches. Rate issues as "minor" or "nitpick" unless they significantly impact maintainability.`,
118
+ },
119
+ {
120
+ name: 'architecture',
121
+ description: 'Module boundaries, coupling, architectural patterns',
122
+ isSpecialized: true,
123
+ focus: ['best-practices', 'api-design'],
124
+ systemPrompt: `You are a software architect. Your mission is to evaluate architectural decisions, module boundaries, and coupling.
125
+
126
+ Focus areas:
127
+ - Violation of module/layer boundaries (e.g., UI code accessing DB directly)
128
+ - Tight coupling between components that should be independent
129
+ - Missing dependency inversion (high-level modules depending on low-level details)
130
+ - Circular dependencies
131
+ - God objects or modules that know too much
132
+ - Missing abstractions (concrete implementations where interfaces are needed)
133
+ - Architectural inconsistencies (mixing patterns in the same layer)
134
+ - Side effects in unexpected places
135
+ - State management issues (global state, inappropriate mutation)
136
+ - Missing or incorrect use of design patterns
137
+ - Scalability concerns at the architectural level
138
+
139
+ Think in terms of long-term maintainability and the ability to change components independently.`,
140
+ },
141
+ {
142
+ name: 'bug-hunter',
143
+ description: 'Logic errors, null paths, race conditions, off-by-one',
144
+ isSpecialized: true,
145
+ focus: ['correctness'],
146
+ systemPrompt: `You are a bug hunter specializing in finding logic errors and correctness issues. Your mission is to find bugs in the code.
147
+
148
+ Focus areas:
149
+ - Logic errors (conditions that are always true/false, incorrect operator precedence)
150
+ - Off-by-one errors (loop bounds, array indices, pagination)
151
+ - Null/undefined dereference without proper checks
152
+ - Race conditions and concurrency bugs (shared mutable state, TOCTOU)
153
+ - Integer overflow/underflow
154
+ - Floating point precision issues
155
+ - Incorrect comparison (== vs ===, reference vs value equality)
156
+ - Missing or incorrect error propagation
157
+ - Incorrect state machine transitions
158
+ - Resource cleanup in error paths
159
+ - Incorrect handling of empty collections
160
+ - Assumption violations (assuming sorted input, assuming specific locale)
161
+
162
+ Be precise about when and how the bug manifests. Prefer "critical" or "important" severity for bugs that can cause incorrect behavior in production.`,
163
+ },
164
+ {
165
+ name: 'accessibility-auditor',
166
+ description: 'WCAG compliance, ARIA, keyboard navigation',
167
+ isSpecialized: true,
168
+ focus: ['best-practices'],
169
+ systemPrompt: `You are an accessibility expert. Your mission is to evaluate code for accessibility issues per WCAG 2.1 AA standards.
170
+
171
+ Focus areas:
172
+ - Missing or incorrect ARIA labels and roles
173
+ - Images without alt text (or with poor alt text)
174
+ - Color contrast issues (where identifiable from code)
175
+ - Keyboard navigation (elements not reachable by keyboard, missing focus management)
176
+ - Screen reader compatibility (missing live regions, incorrect reading order)
177
+ - Form accessibility (labels not associated with inputs, missing error announcements)
178
+ - Interactive elements not usable without mouse
179
+ - Missing skip navigation links
180
+ - Time-based content without controls
181
+ - Missing captions or transcripts references
182
+ - Focus traps (modal dialogs without proper focus management)
183
+ - Semantic HTML violations (using divs where buttons/links are appropriate)
184
+
185
+ Only flag issues visible in the code diff. Rate WCAG Level A violations as "critical", Level AA as "important".`,
186
+ },
187
+ {
188
+ name: 'project-rules',
189
+ description: 'Enforces repo conventions from AGENTS.md, CLAUDE.md, etc.',
190
+ isSpecialized: true,
191
+ focus: ['best-practices'],
192
+ systemPrompt: `You are a project conventions enforcer. Your mission is to ensure the code follows the repository's established rules, conventions, and patterns as defined in the project's rules files (AGENTS.md, CLAUDE.md, CONTRIBUTING.md, etc.).
193
+
194
+ The project rules file content will be provided in the context section above. Review the diff against those rules specifically.
195
+
196
+ Focus areas:
197
+ - Naming conventions defined in the rules
198
+ - File organization and structure requirements
199
+ - Required patterns or anti-patterns to avoid
200
+ - Commit message or PR conventions (if visible)
201
+ - Testing requirements
202
+ - Documentation requirements
203
+ - Any project-specific architectural decisions
204
+
205
+ Reference specific rule violations by quoting the rule that is being violated.`,
206
+ },
207
+ {
208
+ name: 'spec-compliance',
209
+ description: 'Checks implementation against a spec or plan file',
210
+ isSpecialized: true,
211
+ focus: ['correctness', 'api-design'],
212
+ systemPrompt: `You are a specification compliance reviewer. Your mission is to verify that the implementation matches the provided specification or design document.
213
+
214
+ The specification content will be provided in the context section above. Review the diff against that specification.
215
+
216
+ Focus areas:
217
+ - Deviations from specified behavior
218
+ - Missing required features or endpoints
219
+ - Incorrect data types or field names vs spec
220
+ - Missing validation described in spec
221
+ - Incorrect error handling vs spec
222
+ - Unspecified behavior that contradicts the spirit of the spec
223
+ - Implementation gaps (things in spec not yet implemented)
224
+
225
+ Be precise about which part of the spec is being violated or not met.`,
226
+ },
227
+ ];
228
+ export function getRoleByName(name) {
229
+ return BUILTIN_ROLES.find((r) => r.name === name);
230
+ }
231
+ export function getBuiltinRoleNames() {
232
+ return BUILTIN_ROLES.map((r) => r.name);
233
+ }
234
+ //# sourceMappingURL=builtin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/roles/builtin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,mDAAmD;QAChE,aAAa,EAAE,KAAK;QACpB,KAAK,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,CAAC;QAC3E,YAAY,EAAE;;iJAE+H;KAC9I;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,uEAAuE;QACpF,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,UAAU,CAAC;QACnB,YAAY,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;QAC/B,YAAY,EAAE;;;;;;;;;;;;;;6JAc2I;KAC1J;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,oEAAoE;QACjF,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,aAAa,EAAE,gBAAgB,CAAC;QACxC,YAAY,EAAE;;;;;;;;;;;;;;oFAckE;KACjF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,0DAA0D;QACvE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,YAAY,CAAC;QACrB,YAAY,EAAE;;;;;;;;;;;;;;;8CAe4B;KAC3C;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,8CAA8C;QAC3D,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,YAAY,EAAE;;;;;;;;;;;;;;kEAcgD;KAC/D;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,0DAA0D;QACvE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,gBAAgB,CAAC;QACzB,YAAY,EAAE;;;;;;;;;;;;;;;6IAe2H;KAC1I;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,qDAAqD;QAClE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,gBAAgB,EAAE,YAAY,CAAC;QACvC,YAAY,EAAE;;;;;;;;;;;;;;;gGAe8E;KAC7F;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,uDAAuD;QACpE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,aAAa,CAAC;QACtB,YAAY,EAAE;;;;;;;;;;;;;;;;qJAgBmI;KAClJ;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,4CAA4C;QACzD,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,gBAAgB,CAAC;QACzB,YAAY,EAAE;;;;;;;;;;;;;;;;gHAgB8F;KAC7G;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,2DAA2D;QACxE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,gBAAgB,CAAC;QACzB,YAAY,EAAE;;;;;;;;;;;;;+EAa6D;KAC5E;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,mDAAmD;QAChE,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC;QACpC,YAAY,EAAE;;;;;;;;;;;;;sEAaoD;KACnE;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Role, ReviewAssignment } from './types.js';
2
+ import type { ReviewerPair } from '../config/schema.js';
3
+ export type ModelProvider = 'anthropic' | 'openai' | 'google' | 'openai-compat';
4
+ export declare function detectProvider(model: string): ModelProvider;
5
+ /**
6
+ * Build assignments from explicit reviewer pairs (--reviewer model:role)
7
+ */
8
+ export declare function buildExplicitAssignments(reviewerPairs: ReviewerPair[], roleMap: Map<string, Role>): ReviewAssignment[];
9
+ /**
10
+ * Build assignments using the dispatch algorithm:
11
+ * - general role: runs on ALL models
12
+ * - specialized roles: spread across models via shuffled round-robin
13
+ */
14
+ export declare function buildRoleAssignments(models: string[], roles: Role[]): ReviewAssignment[];
15
+ /**
16
+ * Main dispatch builder — handles explicit pairs or role-based assignment
17
+ */
18
+ export declare function buildAssignments(opts: {
19
+ models: string[];
20
+ roles: Role[];
21
+ explicitReviewers?: ReviewerPair[];
22
+ roleMap: Map<string, Role>;
23
+ }): ReviewAssignment[];
@@ -0,0 +1,87 @@
1
+ export function detectProvider(model) {
2
+ // Handle explicit provider prefix (e.g. "anthropic/claude-sonnet-4-5")
3
+ if (model.startsWith('anthropic/'))
4
+ return 'anthropic';
5
+ if (model.startsWith('openai/'))
6
+ return 'openai';
7
+ if (model.startsWith('google/'))
8
+ return 'google';
9
+ if (model.startsWith('openai-compat/'))
10
+ return 'openai-compat';
11
+ // Detect by model name prefix
12
+ if (model.startsWith('claude'))
13
+ return 'anthropic';
14
+ if (model.startsWith('gpt') ||
15
+ model.startsWith('o1') ||
16
+ model.startsWith('o3') ||
17
+ model.startsWith('o4'))
18
+ return 'openai';
19
+ if (model.startsWith('gemini'))
20
+ return 'google';
21
+ // OpenAI-compatible for anything else (local models, etc.)
22
+ return 'openai-compat';
23
+ }
24
+ function shuffle(arr) {
25
+ const out = [...arr];
26
+ for (let i = out.length - 1; i > 0; i--) {
27
+ const j = Math.floor(Math.random() * (i + 1));
28
+ [out[i], out[j]] = [out[j], out[i]];
29
+ }
30
+ return out;
31
+ }
32
+ /**
33
+ * Build assignments from explicit reviewer pairs (--reviewer model:role)
34
+ */
35
+ export function buildExplicitAssignments(reviewerPairs, roleMap) {
36
+ return reviewerPairs.flatMap(({ model, role: roleName }) => {
37
+ const role = roleMap.get(roleName);
38
+ if (!role) {
39
+ console.warn(`Warning: unknown role "${roleName}" in reviewer pair, skipping`);
40
+ return [];
41
+ }
42
+ return [{ model, role, provider: detectProvider(model) }];
43
+ });
44
+ }
45
+ /**
46
+ * Build assignments using the dispatch algorithm:
47
+ * - general role: runs on ALL models
48
+ * - specialized roles: spread across models via shuffled round-robin
49
+ */
50
+ export function buildRoleAssignments(models, roles) {
51
+ const assignments = [];
52
+ const generalRoles = roles.filter((r) => !r.isSpecialized);
53
+ const specializedRoles = roles.filter((r) => r.isSpecialized);
54
+ // General roles: every model runs every general role
55
+ for (const model of models) {
56
+ for (const role of generalRoles) {
57
+ assignments.push({
58
+ model,
59
+ role,
60
+ provider: detectProvider(model),
61
+ });
62
+ }
63
+ }
64
+ // Specialized roles: shuffled round-robin across models
65
+ if (specializedRoles.length > 0 && models.length > 0) {
66
+ const shuffledModels = shuffle(models);
67
+ specializedRoles.forEach((role, index) => {
68
+ const model = shuffledModels[index % shuffledModels.length];
69
+ assignments.push({
70
+ model,
71
+ role,
72
+ provider: detectProvider(model),
73
+ });
74
+ });
75
+ }
76
+ return assignments;
77
+ }
78
+ /**
79
+ * Main dispatch builder — handles explicit pairs or role-based assignment
80
+ */
81
+ export function buildAssignments(opts) {
82
+ if (opts.explicitReviewers && opts.explicitReviewers.length > 0) {
83
+ return buildExplicitAssignments(opts.explicitReviewers, opts.roleMap);
84
+ }
85
+ return buildRoleAssignments(opts.models, opts.roles);
86
+ }
87
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/roles/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Role } from './types.js';
2
+ import type { Config } from '../config/schema.js';
3
+ export declare function findProjectRulesFile(cwd?: string): Promise<string | null>;
4
+ export declare function loadProjectRulesContent(cwd?: string): Promise<string | null>;
5
+ export declare function buildCustomRole(config: {
6
+ name: string;
7
+ systemPrompt?: string;
8
+ focus?: string[];
9
+ severityBias?: Record<string, number>;
10
+ }): Role;
11
+ export declare function resolveRoles(config: Config, requestedRoles?: string[], projectRulesContent?: string, specContent?: string): Promise<Role[]>;
@@ -0,0 +1,107 @@
1
+ import { readFile, access } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { BUILTIN_ROLES, getRoleByName } from './builtin.js';
4
+ const PROJECT_RULES_FILES = [
5
+ 'AGENTS.md',
6
+ 'CLAUDE.md',
7
+ 'CONTRIBUTING.md',
8
+ '.github/CONTRIBUTING.md',
9
+ 'DEVELOPMENT.md',
10
+ 'docs/CONTRIBUTING.md',
11
+ ];
12
+ export async function findProjectRulesFile(cwd = process.cwd()) {
13
+ for (const filename of PROJECT_RULES_FILES) {
14
+ const fullPath = join(cwd, filename);
15
+ try {
16
+ await access(fullPath);
17
+ return fullPath;
18
+ }
19
+ catch {
20
+ // not found, try next
21
+ }
22
+ }
23
+ return null;
24
+ }
25
+ export async function loadProjectRulesContent(cwd) {
26
+ const filePath = await findProjectRulesFile(cwd);
27
+ if (!filePath)
28
+ return null;
29
+ try {
30
+ return await readFile(filePath, 'utf-8');
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ export function buildCustomRole(config) {
37
+ // If it extends a builtin, start from that base
38
+ const base = getRoleByName(config.name);
39
+ return {
40
+ name: config.name,
41
+ description: `Custom role: ${config.name}`,
42
+ isSpecialized: true,
43
+ focus: config.focus ?? base?.focus ?? ['best-practices'],
44
+ severityBias: config.severityBias ?? base?.severityBias,
45
+ systemPrompt: config.systemPrompt ??
46
+ base?.systemPrompt ??
47
+ `You are a code reviewer with focus on: ${config.focus?.join(', ') ?? 'general quality'}.`,
48
+ };
49
+ }
50
+ export async function resolveRoles(config, requestedRoles, projectRulesContent, specContent) {
51
+ const roles = new Map();
52
+ // Add all builtin roles
53
+ for (const role of BUILTIN_ROLES) {
54
+ roles.set(role.name, role);
55
+ }
56
+ // Add custom roles from config (override builtins if same name)
57
+ if (config.customRoles) {
58
+ for (const customConfig of config.customRoles) {
59
+ roles.set(customConfig.name, buildCustomRole(customConfig));
60
+ }
61
+ }
62
+ // Augment project-rules role with actual content
63
+ if (projectRulesContent) {
64
+ const projectRulesRole = roles.get('project-rules');
65
+ roles.set('project-rules', {
66
+ ...projectRulesRole,
67
+ systemPrompt: projectRulesRole.systemPrompt +
68
+ '\n\n## Project Rules File Content\n\n' +
69
+ projectRulesContent,
70
+ });
71
+ }
72
+ // Augment spec-compliance role with actual spec content
73
+ if (specContent) {
74
+ const specRole = roles.get('spec-compliance');
75
+ roles.set('spec-compliance', {
76
+ ...specRole,
77
+ systemPrompt: specRole.systemPrompt +
78
+ '\n\n## Specification Content\n\n' +
79
+ specContent,
80
+ });
81
+ }
82
+ // Determine which roles to use
83
+ const requested = requestedRoles ?? config.roles;
84
+ if (requested && requested.length > 0) {
85
+ const hasAll = requested.some((r) => r.toLowerCase() === 'all');
86
+ if (hasAll) {
87
+ if (requested.length > 1) {
88
+ throw new Error(`'all' cannot be combined with other roles. Got: ${requested.join(', ')}`);
89
+ }
90
+ return Array.from(roles.values());
91
+ }
92
+ const result = [];
93
+ for (const name of requested) {
94
+ const role = roles.get(name);
95
+ if (role) {
96
+ result.push(role);
97
+ }
98
+ else {
99
+ console.warn(`Warning: unknown role "${name}", skipping`);
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ // Default: general + all specialized
105
+ return Array.from(roles.values());
106
+ }
107
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/roles/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface Role {
2
+ name: string;
3
+ systemPrompt: string;
4
+ focus: string[];
5
+ severityBias?: Record<string, number>;
6
+ description: string;
7
+ isSpecialized: boolean;
8
+ }
9
+ export interface ReviewAssignment {
10
+ model: string;
11
+ role: Role;
12
+ provider: string;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/roles/types.ts"],"names":[],"mappings":""}