From 311a0aab5de1a0a8b5a542bd9480b1684f071699 Mon Sep 17 00:00:00 2001 From: svtter Date: Mon, 25 May 2026 10:12:36 +0800 Subject: [PATCH] feat(multi-review): add collapsible reviewer details to coordinator comment Append each reviewer's raw output in
sections after the coordinator synthesis, so users can expand to see individual reviews. Co-Authored-By: Claude Opus 4.7 --- multi-review/dist/index.cjs | 20 +++++++++++++++++++- multi-review/src/index.ts | 5 +++-- multi-review/src/orchestrator.ts | 8 ++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/multi-review/dist/index.cjs b/multi-review/dist/index.cjs index ffdfb01..5617c74 100644 --- a/multi-review/dist/index.cjs +++ b/multi-review/dist/index.cjs @@ -2494,6 +2494,23 @@ ${r.content}`; }); return "**Multi-Review (fallback \u2014 coordinator failed)**\n\n" + parts.join("\n\n---\n\n"); } +function buildReviewerDetails(reviews) { + const details = reviews.map((r) => { + const body = r.success ? r.content : `\uFF08\u5BA1\u67E5\u5931\u8D25: ${r.error}\uFF09`; + return `
+${r.reviewer} + +${body} + +
`; + }); + return `
+\u{1F4CB} \u5404 Reviewer \u8BE6\u7EC6\u5BA1\u67E5\u7ED3\u679C + +${details.join("\n\n")} + +
`; +} // src/comment.ts var import_node_child_process2 = require("child_process"); @@ -2618,11 +2635,12 @@ async function main() { } let comment; try { - comment = await runCoordinator(client2, reviews, { + const synthesis = await runCoordinator(client2, reviews, { globalTimeoutMs: globalTimeout * 1e3, coordinatorTimeoutMs: coordinatorTimeout * 1e3, coordinatorPrompt: env("MULTI_REVIEW_COORDINATOR_PROMPT") }); + comment = synthesis + "\n\n---\n\n" + buildReviewerDetails(reviews); } catch (err) { console.error(`Coordinator failed: ${err}`); comment = buildFallbackComment(reviews); diff --git a/multi-review/src/index.ts b/multi-review/src/index.ts index 24ccb93..3405054 100644 --- a/multi-review/src/index.ts +++ b/multi-review/src/index.ts @@ -2,7 +2,7 @@ import { createOpencode } from "@opencode-ai/sdk"; import { readFileSync } from "node:fs"; import { join } from "node:path"; import { loadReviewers, resolveModel, env, intEnv } from "./reviewers.js"; -import { runParallelReviewers, runCoordinator, buildFallbackComment } from "./orchestrator.js"; +import { runParallelReviewers, runCoordinator, buildFallbackComment, buildReviewerDetails } from "./orchestrator.js"; import { postPRComment, cleanupErrorComments, parseExtraEnv } from "./comment.js"; async function main(): Promise { @@ -64,11 +64,12 @@ async function main(): Promise { // 6. Run coordinator let comment: string; try { - comment = await runCoordinator(client, reviews, { + const synthesis = await runCoordinator(client, reviews, { globalTimeoutMs: globalTimeout * 1000, coordinatorTimeoutMs: coordinatorTimeout * 1000, coordinatorPrompt: env("MULTI_REVIEW_COORDINATOR_PROMPT"), }); + comment = synthesis + "\n\n---\n\n" + buildReviewerDetails(reviews); } catch (err) { console.error(`Coordinator failed: ${err}`); comment = buildFallbackComment(reviews); diff --git a/multi-review/src/orchestrator.ts b/multi-review/src/orchestrator.ts index 24f14ee..785e04b 100644 --- a/multi-review/src/orchestrator.ts +++ b/multi-review/src/orchestrator.ts @@ -148,3 +148,11 @@ export function buildFallbackComment(reviews: ReviewResult[]): string { }); return "**Multi-Review (fallback — coordinator failed)**\n\n" + parts.join("\n\n---\n\n"); } + +export function buildReviewerDetails(reviews: ReviewResult[]): string { + const details = reviews.map((r) => { + const body = r.success ? r.content : `(审查失败: ${r.error})`; + return `
\n${r.reviewer}\n\n${body}\n\n
`; + }); + return `
\n📋 各 Reviewer 详细审查结果\n\n${details.join("\n\n")}\n\n
`; +}