@crown-dev-studios/review-council 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.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # Review Council
2
+
3
+ Review Council is a package-first CLI for multi-agent code review orchestration. It runs Claude, Codex, or other local reviewer CLIs against the same target, collects raw artifacts, runs a judge pass, and renders a static review bundle.
4
+
5
+ Use it when you want:
6
+
7
+ - side-by-side raw reviews before creating final todos
8
+ - isolated reviewer runs or separate worktrees
9
+ - a judge step that confirms, contests, or rejects findings
10
+ - a static HTML report plus machine-readable JSON output
11
+
12
+ ## Status
13
+
14
+ The orchestrator handles the happy path and common failure modes:
15
+
16
+ - Stage timeouts with two-phase kill (SIGTERM then SIGKILL) prevent hung runs
17
+ - Automatic retry with exponential backoff handles transient failures
18
+ - Schema validation catches malformed reviewer and judge output
19
+ - Interactive prompts from reviewer CLIs are detected and relayed to the user
20
+ - Partial reviewer failure still allows the judge to run on available data
21
+ - Failed stages surface stderr excerpts and validation errors in the HTML report
22
+
23
+ ## Requirements
24
+
25
+ - Node.js 20+
26
+ - `claude` and/or `codex` on `PATH`
27
+ - a Git working tree to review
28
+ - reviewer CLIs authenticated and able to run non-interactively when possible
29
+
30
+ ## Install
31
+
32
+ Run it directly:
33
+
34
+ ```bash
35
+ npx @crown-dev-studios/review-council --help
36
+ ```
37
+
38
+ Other package install paths:
39
+
40
+ ```bash
41
+ pnpm dlx @crown-dev-studios/review-council --help
42
+ npm install -g @crown-dev-studios/review-council
43
+ review-council --help
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ From the project root you want to review:
49
+
50
+ ```bash
51
+ npx @crown-dev-studios/review-council \
52
+ --target "staged changes" \
53
+ --review-id staged-changes-review \
54
+ --claude-command 'claude -p --disable-slash-commands --permission-mode acceptEdits "$(cat "$CLAUDE_DIR/claude-review-export.md")" < /dev/null' \
55
+ --codex-command 'codex exec --sandbox workspace-write -o "$CODEX_DIR/last-message.txt" "$(cat "$CODEX_DIR/codex-review-export.md")"' \
56
+ --judge-command 'codex exec --sandbox workspace-write -o "$JUDGE_DIR/last-message.txt" "$(cat "$JUDGE_DIR/judge.md")"'
57
+ ```
58
+
59
+ That writes a run bundle under `docs/reviews/<review-id>/runs/<run-id>/` in the project being reviewed. Pass `--review-id` explicitly when you want the same review to be easy to correlate across reruns.
60
+
61
+ Main outputs:
62
+
63
+ - `judge/summary.md`
64
+ - `judge/verdict.json`
65
+ - `bundle.json`
66
+ - `index.html`
67
+
68
+ ## Skill Install
69
+
70
+ Optional: install it as a slash-invocable skill by copying or symlinking this directory:
71
+
72
+ ```bash
73
+ cp -R ~/src/review-council ~/.claude/skills/review-council
74
+ cp -R ~/src/review-council ~/.codex/skills/review-council
75
+ ```
76
+
77
+ The skill docs and the published package describe the same runtime: invoke `npx @crown-dev-studios/review-council ...` from the repo you want to review so outputs stay rooted in that caller repo.
78
+
79
+ ## CLI Options
80
+
81
+ ```
82
+ --target <target> Review target label (required)
83
+ --review-id <id> Stable review identifier
84
+ --run-dir <dir> Output directory for this run
85
+ --review-profile <id> Reviewer prompt profile (default: default)
86
+ --judge-profile <id> Judge prompt profile (default: default)
87
+ --claude-prompt-template <path> Override Claude reviewer prompt template
88
+ --codex-prompt-template <path> Override Codex reviewer prompt template
89
+ --judge-prompt-template <path> Override judge prompt template
90
+ --claude-command <command> Shell command for the Claude reviewer
91
+ --codex-command <command> Shell command for the Codex reviewer
92
+ --judge-command <command> Shell command for the judge stage
93
+ --allow-missing-sentinel Treat exit code 0 as success without done.json
94
+ --skip-judge Skip the judge stage
95
+ --skip-html Skip HTML rendering
96
+ --open-html Open index.html after rendering (macOS)
97
+ --timeout <ms> Stage timeout in ms (default: 300000)
98
+ --retries <n> Max retries per stage on failure (default: 2)
99
+ ```
100
+
101
+ ## Operating Notes
102
+
103
+ - Use non-interactive reviewer commands when possible. Interactive prompts are detected and relayed to the user, but explicit non-interactive mode is more reliable.
104
+ - Use `claude -p --disable-slash-commands --permission-mode acceptEdits ... < /dev/null` for Claude reviewer runs. This keeps the run in headless mode, disables skills, allows artifact writes into the stage directory without interactive approval prompts, and prevents Claude from waiting on stdin during fully non-interactive runs.
105
+ - Codex reviewer and judge commands must run with a writable sandbox, for example `codex exec --sandbox workspace-write ...`, because they need to write review artifacts into the run directory.
106
+ - `--skip-judge` disables judge prompt rendering, judge command validation, and judge execution.
107
+ - Keep reviewer artifacts inside the run directory.
108
+ - Every reviewer and judge JSON artifact should carry the same `review_id` and `run_id` as `run.json`.
109
+ - Do not create authoritative files in `todos/` during raw review.
110
+ - If you reuse `workflows-review`, run each reviewer in a separate worktree.
111
+
112
+ ## Failure Triage
113
+
114
+ If a run fails or stalls, inspect:
115
+
116
+ - `<run>/claude/status.json`
117
+ - `<run>/codex/status.json`
118
+ - `<run>/judge/status.json`
119
+ - each stage's `stdout.log` and `stderr.log`
120
+
121
+ The `status.json` for each stage includes `review_id`, `run_id`, `exit_code`, `timed_out`, `attempts`, `missing_artifacts`, `failure_reason`, and `validation_errors`. The HTML report surfaces missing artifacts, stderr excerpts, and validation errors for failed stages in a diagnostics section.
122
+
123
+ If a stage exits `0` but does not write `done.json`, the stage is incomplete and the run should be treated as failed.
124
+
125
+ ## Development
126
+
127
+ Contributor workflow from a source checkout:
128
+
129
+ ```bash
130
+ cd ~/src/review-council
131
+ pnpm install
132
+ pnpm typecheck
133
+ pnpm test
134
+ ```
135
+
136
+ Package verification:
137
+
138
+ ```bash
139
+ pnpm verify:package
140
+ ```
141
+
142
+ That verification path:
143
+
144
+ - builds `dist/`
145
+ - inspects `npm pack --dry-run` output with a repo-local npm cache
146
+ - installs the local tarball into a temporary caller repo
147
+ - verifies `review-council --help` and a minimal end-to-end run
148
+
149
+ First publish and post-publish checks:
150
+
151
+ ```bash
152
+ pnpm release:manual
153
+ npm view @crown-dev-studios/review-council version
154
+ npx @crown-dev-studios/review-council --help
155
+ ```
156
+
157
+ ## Files
158
+
159
+ - [SKILL.md](SKILL.md)
160
+ - [references/cli-integration.md](references/cli-integration.md)
161
+ - [references/output-contract.md](references/output-contract.md)
162
+ - [src/cli.ts](src/cli.ts)
163
+ - [src/orchestrate-review-council.ts](src/orchestrate-review-council.ts)
164
+ - [src/render-review-html.ts](src/render-review-html.ts)
165
+ - [src/interaction-queue.ts](src/interaction-queue.ts)
166
+ - [src/review-session.ts](src/review-session.ts)
167
+ - [src/schemas.ts](src/schemas.ts)
168
+ - [src/types.ts](src/types.ts)
169
+ - [test/package-smoke.test.mjs](test/package-smoke.test.mjs)
170
+ - [test/validate-schema.test.ts](test/validate-schema.test.ts)
package/SKILL.md ADDED
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: review-council
3
+ description: Orchestrate Claude, Codex, or other local CLI reviewers against the same target, wait for their exported findings, run a judge pass, and generate a static HTML plus markdown review bundle. Use when you want side-by-side raw reviews before creating final todos.
4
+ argument-hint: [staged|branch main..HEAD|pr 123|commit abc123]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ # Review Council
9
+
10
+ ## Purpose
11
+
12
+ `/review-council` is the manual entrypoint for multi-agent code review orchestration.
13
+
14
+ This directory is intended to be both a standalone skill repo and the source for the published npm package. The prompt templates, schemas, renderer, and orchestrator all live here.
15
+
16
+ It is intentionally separate from `workflows-review`:
17
+
18
+ - `workflows-review` is optimized for single-agent review and immediate todo creation
19
+ - `review-council` is optimized for parallel raw review, adjudication, and artifact rendering
20
+
21
+ Use this when you want:
22
+
23
+ - a Claude review and a Codex review on the same target
24
+ - isolated worktrees or isolated CLI runs per reviewer
25
+ - raw reviewer artifacts stored outside `todos/`
26
+ - a judge step that decides which findings are valid
27
+ - a static HTML page next to the final markdown judge summary
28
+
29
+ ## Prerequisites
30
+
31
+ - Node.js 20+
32
+ - `claude` and/or `codex` on `PATH` for the stages you want to run
33
+ - A Git working tree to review
34
+ - Reviewer CLIs must already be authenticated and able to run non-interactively
35
+
36
+ ## Quick Start
37
+
38
+ 1. Put this directory somewhere stable, for example `~/src/review-council`.
39
+
40
+ 2. Optional: install it as a slash-invocable skill by copying or symlinking this directory to one or both skill locations:
41
+
42
+ ```bash
43
+ cp -R ~/src/review-council ~/.claude/skills/review-council
44
+ cp -R ~/src/review-council ~/.codex/skills/review-council
45
+ ```
46
+
47
+ 3. Review or customize the command templates in [cli-integration.md](references/cli-integration.md).
48
+
49
+ No external `/review-export` command is required. The orchestrator renders self-contained prompt files into each stage directory before launching reviewer CLIs.
50
+
51
+ 4. From the project root you want to review, run the published CLI. By default it writes each run under `docs/reviews/<review-id>/runs/<run-id>/` in the current project:
52
+
53
+ ```bash
54
+ npx @crown-dev-studios/review-council \
55
+ --target "staged changes" \
56
+ --review-id staged-changes-review \
57
+ --claude-command 'claude -p --disable-slash-commands --permission-mode acceptEdits "$(cat "$CLAUDE_DIR/claude-review-export.md")" < /dev/null' \
58
+ --codex-command 'codex exec --sandbox workspace-write -o "$CODEX_DIR/last-message.txt" "$(cat "$CODEX_DIR/codex-review-export.md")"' \
59
+ --judge-command 'codex exec --sandbox workspace-write -o "$JUDGE_DIR/last-message.txt" "$(cat "$JUDGE_DIR/judge.md")"' \
60
+ --timeout 300000 \
61
+ --retries 2
62
+ ```
63
+
64
+ - `--timeout <ms>`: per-stage timeout (default 300000 — 5 minutes). On timeout the process receives SIGTERM, then SIGKILL after a 5-second grace period.
65
+ - `--retries <n>`: max retries per stage on non-timeout failure (default 2). Uses exponential backoff starting at 2 seconds.
66
+ - For Claude reviewer runs, use `claude -p --disable-slash-commands --permission-mode acceptEdits ... < /dev/null`. This keeps the run headless, disables skills, allows artifact writes into the stage directory without interactive approval prompts, and avoids stdin wait warnings.
67
+ - When using Codex for reviewer or judge stages, include `--sandbox workspace-write` so it can write artifacts into the run directory.
68
+ - `--skip-judge` disables judge prompt rendering, judge command validation, and judge execution.
69
+ - Pass `--review-id` explicitly when you want the same review to be easy to correlate across reruns.
70
+
71
+ If the package is already installed globally, `review-council --target ...` is equivalent.
72
+
73
+ ### Development from a Source Checkout
74
+
75
+ The packaged CLI is the supported runtime. Contributor workflow remains source-first:
76
+
77
+ ```bash
78
+ cd ~/src/review-council
79
+ pnpm install
80
+ pnpm typecheck
81
+ pnpm test
82
+ pnpm verify:package
83
+ ```
84
+
85
+ This produces:
86
+
87
+ - `docs/reviews/<review-id>/runs/<run-id>/judge/summary.md`
88
+ - `docs/reviews/<review-id>/runs/<run-id>/judge/verdict.json`
89
+ - `docs/reviews/<review-id>/runs/<run-id>/bundle.json`
90
+ - `docs/reviews/<review-id>/runs/<run-id>/index.html`
91
+
92
+ ### Example findings.json
93
+
94
+ ```json
95
+ {
96
+ "review_id": "staged-changes-review",
97
+ "run_id": "20260318-143000123-abc12345",
98
+ "reviewer": "claude",
99
+ "target": "staged changes",
100
+ "generated_at": "2026-03-07T18:30:00Z",
101
+ "summary": "Found two issues: one SQL injection and one missing index.",
102
+ "findings": [
103
+ {
104
+ "id": "F001",
105
+ "title": "SQL injection in search endpoint",
106
+ "severity": "p1",
107
+ "confidence": "high",
108
+ "category": "security",
109
+ "description": "Unsanitized user input passed directly to raw SQL query.",
110
+ "evidence": "db.query(`SELECT * FROM users WHERE name = '${input}'`)",
111
+ "recommended_fix": "Use parameterized queries instead of string interpolation.",
112
+ "files": [
113
+ { "path": "src/routes/search.ts", "line": 42 }
114
+ ]
115
+ },
116
+ {
117
+ "id": "F002",
118
+ "title": "Missing index on users.email",
119
+ "severity": "p3",
120
+ "confidence": "medium",
121
+ "category": "performance",
122
+ "description": "The users.email column is queried frequently but has no index.",
123
+ "evidence": "Query plan shows sequential scan on users table.",
124
+ "recommended_fix": "Add a B-tree index on users.email.",
125
+ "files": [
126
+ { "path": "db/migrations/001_create_users.sql" }
127
+ ]
128
+ }
129
+ ]
130
+ }
131
+ ```
132
+
133
+ ### Example verdict.json
134
+
135
+ ```json
136
+ {
137
+ "review_id": "staged-changes-review",
138
+ "run_id": "20260318-143000123-abc12345",
139
+ "target": "staged changes",
140
+ "generated_at": "2026-03-07T14:30:00Z",
141
+ "overall_verdict": "needs-fixes",
142
+ "summary_markdown": "Two confirmed issues require attention before merge.",
143
+ "confirmed_findings": [
144
+ {
145
+ "title": "SQL injection in search endpoint",
146
+ "status": "confirmed",
147
+ "reason": "Both reviewers flagged unsanitized user input passed to raw query.",
148
+ "final_priority": "p1",
149
+ "reviewer_ids": ["claude", "codex"]
150
+ }
151
+ ],
152
+ "contested_findings": [
153
+ {
154
+ "title": "Missing index on users.email",
155
+ "status": "contested",
156
+ "reason": "Claude flagged as p2 but Codex noted the table has <1k rows.",
157
+ "final_priority": "p3",
158
+ "reviewer_ids": ["claude"]
159
+ }
160
+ ],
161
+ "rejected_findings": [
162
+ {
163
+ "title": "Unused import in helpers.ts",
164
+ "status": "rejected",
165
+ "reason": "Import is used in a type-only context; no runtime impact."
166
+ }
167
+ ],
168
+ "todo_recommendations": [
169
+ {
170
+ "title": "Parameterize search query to prevent SQL injection",
171
+ "priority": "p1",
172
+ "reason": "Confirmed by both reviewers as a security vulnerability."
173
+ }
174
+ ]
175
+ }
176
+ ```
177
+
178
+ ## Workflow
179
+
180
+ ### Step 1: Choose the Review Target
181
+
182
+ Normalize the target into one of these forms:
183
+
184
+ - `staged changes`
185
+ - `branch main..feature-branch`
186
+ - `pr 123`
187
+ - `commit abc123`
188
+
189
+ ### Step 2: Spawn Reviewer CLIs
190
+
191
+ The parent agent is the orchestrator. It should not do the review itself.
192
+
193
+ Its job is to:
194
+
195
+ 1. Create a run directory
196
+ 2. Spawn reviewer CLIs with explicit commands
197
+ 3. Wait for both reviewers to finish
198
+ 4. Confirm each reviewer wrote `done.json`
199
+ 5. Run the judge step
200
+ 6. Render HTML
201
+
202
+ Use the environment variables documented in [cli-integration.md](references/cli-integration.md). Prefer the rendered stage prompt files under `$CLAUDE_DIR`, `$CODEX_DIR`, and `$JUDGE_DIR` over the source templates under `templates/`.
203
+
204
+ ### Step 3: Export Raw Reviewer Artifacts
205
+
206
+ Each reviewer should write only raw artifacts:
207
+
208
+ - `report.md`
209
+ - `findings.json`
210
+ - `done.json`
211
+
212
+ Do not create authoritative todos during raw review.
213
+
214
+ If you want to reuse the heuristics from `workflows-review`, copy its review bar and agent choices into the reviewer prompts, but stop before todo creation.
215
+
216
+ ### Step 4: Judge the Combined Result
217
+
218
+ The judge reads both raw reviewer outputs and decides:
219
+
220
+ - which findings are confirmed
221
+ - which findings are contested
222
+ - which findings are rejected
223
+ - which findings are worth turning into final todos
224
+
225
+ The judge writes:
226
+
227
+ - `summary.md`
228
+ - `verdict.json`
229
+ - `done.json`
230
+
231
+ ### Step 5: Render the Reading View
232
+
233
+ Render `index.html` after the judge completes.
234
+
235
+ The HTML page should make these easy to scan:
236
+
237
+ - judge summary
238
+ - candidate findings from each reviewer
239
+ - confirmed versus contested verdicts
240
+ - raw markdown reports from Claude and Codex
241
+
242
+ ## Important Constraints
243
+
244
+ - Do not run `workflows-review` twice in the same working tree if it will write directly to `todos/`
245
+ - If you must reuse `workflows-review` unchanged, run each reviewer in a separate worktree so each run has its own local `todos/`
246
+ - Keep final todo creation as a later, explicit step owned by the judge or a follow-up workflow
247
+ - Interactive prompts from reviewer CLIs are detected and relayed to the user one at a time; explicit non-interactive commands such as `claude -p --disable-slash-commands --permission-mode acceptEdits < /dev/null` or `codex exec` remain the standard mode for raw review runs
248
+
249
+ ## Supporting Files
250
+
251
+ - Output contract: [output-contract.md](references/output-contract.md)
252
+ - CLI examples: [cli-integration.md](references/cli-integration.md)
253
+ - Review schema: [review-findings.schema.json](schemas/review-findings.schema.json)
254
+ - Judge schema: [judge-verdict.schema.json](schemas/judge-verdict.schema.json)
255
+ - Reviewer template: [reviewer-export.md](templates/reviewer-export.md)
256
+ - Judge template: [judge.md](templates/judge.md)
257
+ - HTML template: [report.html](templates/report.html)
258
+ - CLI entrypoint: [src/cli.ts](src/cli.ts)
259
+ - Orchestrator runtime: [src/orchestrate-review-council.ts](src/orchestrate-review-council.ts)
260
+ - Renderer: [src/render-review-html.ts](src/render-review-html.ts)
261
+ - TypeScript package: [package.json](package.json)
262
+ - TypeScript config: [tsconfig.json](tsconfig.json)
package/dist/cli.js ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "./orchestrate-review-council.js";
3
+ try {
4
+ await main();
5
+ }
6
+ catch (error) {
7
+ console.error(error);
8
+ process.exit(1);
9
+ }
@@ -0,0 +1,50 @@
1
+ import { createInterface } from "node:readline";
2
+ const queue = [];
3
+ let processing = false;
4
+ let readlineInterface = null;
5
+ function getReadline() {
6
+ if (!readlineInterface) {
7
+ readlineInterface = createInterface({ input: process.stdin, output: process.stdout });
8
+ }
9
+ return readlineInterface;
10
+ }
11
+ function processNext() {
12
+ if (queue.length === 0) {
13
+ processing = false;
14
+ return;
15
+ }
16
+ processing = true;
17
+ const request = queue.shift();
18
+ if (!request) {
19
+ processing = false;
20
+ return;
21
+ }
22
+ const reader = getReadline();
23
+ process.stderr.write(`\n[${request.stage}] needs your input:\n${request.prompt}\n`);
24
+ reader.question("", (answer) => {
25
+ try {
26
+ request.stdinPipe.write(`${answer}\n`);
27
+ }
28
+ catch {
29
+ // The child process may exit before the response is written.
30
+ }
31
+ request.resolve();
32
+ processNext();
33
+ });
34
+ }
35
+ export function enqueue(request) {
36
+ queue.push(request);
37
+ if (!processing) {
38
+ processNext();
39
+ }
40
+ }
41
+ export function close() {
42
+ if (readlineInterface) {
43
+ readlineInterface.close();
44
+ readlineInterface = null;
45
+ }
46
+ processing = false;
47
+ for (const request of queue.splice(0)) {
48
+ request.resolve();
49
+ }
50
+ }