openspec_get_review_summary
Retrieve a summary of reviews for a change, covering all files in the change request.
Instructions
Get review summary for a change (all files)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| changeId | Yes | Change ID |
Implementation Reference
- src/server/tools/reviews.ts:191-227 (handler)Handler function for 'openspec_get_review_summary' tool. Calls reviewManager.getChangeReviews() to fetch reviews across proposal, design, and tasks files, then formats a text summary including overall counts, per-file breakdown, per-type breakdown, and a warning about blocking issues.
server.registerTool( 'openspec_get_review_summary', { description: 'Get review summary for a change (all files)', inputSchema: { changeId: z.string().describe('Change ID'), }, }, async ({ changeId }) => { const { proposal, design, tasks, summary } = await reviewManager.getChangeReviews(changeId); let text = `Review Summary for: ${changeId}\n`; text += `${'='.repeat(40)}\n\n`; text += `đ Overall: ${summary.total} reviews\n`; text += ` đ´ Open: ${summary.open}\n`; text += ` â Resolved: ${summary.resolved}\n`; text += ` âī¸ Won't Fix: ${summary.wontFix}\n\n`; text += `đ By File:\n`; text += ` proposal.md: ${proposal.length}\n`; text += ` design.md: ${design.length}\n`; text += ` tasks.md: ${tasks.length}\n\n`; text += `đ By Type:\n`; text += ` đŦ Comments: ${summary.byType.comment}\n`; text += ` đĄ Suggestions: ${summary.byType.suggestion}\n`; text += ` â Questions: ${summary.byType.question}\n`; text += ` đ¨ Issues: ${summary.byType.issue}\n\n`; if (summary.hasBlockingIssues) { text += `â ī¸ Blocking issues exist! Cannot request approval.\n`; } return { content: [{ type: 'text', text }] }; } ); - src/core/review-manager.ts:77-85 (schema)Type definition for ReviewSummary used as the return type for getChangeReviews(). Contains total/open/resolved/wontFix counts, byType and bySeverity breakdowns, and a hasBlockingIssues flag.
export interface ReviewSummary { total: number; open: number; resolved: number; wontFix: number; byType: Record<ReviewType, number>; bySeverity: Record<ReviewSeverity, number>; hasBlockingIssues: boolean; } - src/core/review-manager.ts:330-362 (helper)Helper method getChangeReviews() on the ReviewManager class. Loads all reviews for a changeId across proposal, design, and tasks files, computes summary statistics (total, open, resolved, wontFix, byType, bySeverity, hasBlockingIssues) and returns them alongside the grouped review arrays.
async getChangeReviews(changeId: string): Promise<{ proposal: ReviewComment[]; design: ReviewComment[]; tasks: ReviewComment[]; summary: ReviewSummary; }> { const proposal = await this.loadReviews('proposal', changeId); const design = await this.loadReviews('design', changeId); const tasks = await this.loadReviews('tasks', changeId); const allReviews = [...proposal, ...design, ...tasks]; // čŽĄįŽæģäŊįģ莥 const summary: ReviewSummary = { total: allReviews.length, open: allReviews.filter((r) => r.status === 'open').length, resolved: allReviews.filter((r) => r.status === 'resolved').length, wontFix: allReviews.filter((r) => r.status === 'wont_fix').length, byType: { comment: 0, suggestion: 0, question: 0, issue: 0 }, bySeverity: { low: 0, medium: 0, high: 0 }, hasBlockingIssues: false, }; for (const review of allReviews) { summary.byType[review.type]++; if (review.severity) summary.bySeverity[review.severity]++; if (review.status === 'open' && review.type === 'issue' && review.severity === 'high') { summary.hasBlockingIssues = true; } } return { proposal, design, tasks, summary }; } - src/server/tools/reviews.ts:10-10 (registration)Registration entry point for all review tools including 'openspec_get_review_summary'. The function is called with an McpServer instance and ReviewManager, then registers the tool via server.registerTool().
export function registerReviewTools(server: McpServer, reviewManager: ReviewManager): void {