feat: add project-review workflow (whole-project / single-feature review)
Adds the project-review workflow for code review independent of the git diff. The scope is parsed from the user instruction: 全面/整个项目 -> whole-project (score every source file), otherwise feature + target keyword (locate the code with semantic search + graph queries). - scoring_tools.py: score_review_func gains all_files=True to score every source file in the graph via store.get_all_files() - main.py: score_review_tool gains all_files param; registers the project_review MCP prompt (prompts 6->7) - prompts.py: project_review_prompt(scope, target) with whole-project and feature branches (fixed a precedence bug that truncated the feature text) - skills.py + skills/project-review/: new read-only project-review skill with shared checklists - .opencode/command/code-review-graph-project-review.md: slash command - tests: test_project_review.py (prompt rendering), TestProjectReviewPrompt, skill count assertions 5->6, all_files wiring checks - docs: prompts (6->7) + project-review entries across COMMANDS, CLAUDE, README (+localized), INDEX, architecture, LLM-OPTIMIZED-REFERENCE, CHANGELOG
This commit is contained in:
@@ -27,6 +27,7 @@ from .prompts import (
|
||||
debug_issue_prompt,
|
||||
onboard_developer_prompt,
|
||||
pre_merge_check_prompt,
|
||||
project_review_prompt,
|
||||
review_changes_prompt,
|
||||
unified_review_prompt,
|
||||
)
|
||||
@@ -697,6 +698,7 @@ async def score_review_tool(
|
||||
include_churn: bool = True,
|
||||
repo_root: Optional[str] = None,
|
||||
detail_level: str = "standard",
|
||||
all_files: bool = False,
|
||||
) -> dict:
|
||||
"""Compute objective Layer-2 review metrics for changed files.
|
||||
|
||||
@@ -717,6 +719,9 @@ async def score_review_tool(
|
||||
repo_root: Repository root path. Auto-detected if omitted.
|
||||
detail_level: "standard" for full output, "minimal" for
|
||||
token-efficient summary. Default: standard.
|
||||
all_files: When True, score every source file in the graph,
|
||||
ignoring ``changed_files`` and the git diff. Used for
|
||||
whole-project reviews (default: False).
|
||||
"""
|
||||
root = _resolve_repo_root(repo_root)
|
||||
|
||||
@@ -724,7 +729,7 @@ async def score_review_tool(
|
||||
return with_provenance(score_review_func(
|
||||
changed_files=changed_files, base=base,
|
||||
include_churn=include_churn, repo_root=root,
|
||||
detail_level=detail_level,
|
||||
detail_level=detail_level, all_files=all_files,
|
||||
), root)
|
||||
|
||||
return await asyncio.to_thread(_run)
|
||||
@@ -763,30 +768,34 @@ async def generate_report_tool(
|
||||
review_data: dict,
|
||||
output_path: Optional[str] = None,
|
||||
repo_root: Optional[str] = None,
|
||||
format: str = "both",
|
||||
) -> dict:
|
||||
"""Generate a self-contained HTML code review report.
|
||||
"""Generate code review reports (HTML and/or Markdown).
|
||||
|
||||
Injects ``review_data`` (output of ``score_review_tool`` plus
|
||||
``dedupe_findings_tool`` results and free-form verdict/tier/scope) into
|
||||
the bundled ``report-template.html`` as ``{{REPORT_DATA}}`` and writes
|
||||
the standalone file (default ``repo_root/code-review-report.html``).
|
||||
the bundled ``report-template.html`` as ``{{REPORT_DATA}}`` (HTML) and/or
|
||||
renders a standalone Chinese Markdown report. Both are written by
|
||||
default. ``output_path`` is the base name without an extension.
|
||||
|
||||
Offloaded to a thread via ``asyncio.to_thread`` — rendering loads the
|
||||
template asset and writes the output file.
|
||||
template asset and writes the output file(s).
|
||||
|
||||
Args:
|
||||
review_data: Review data dict (metrics, findings, verdict, tier,
|
||||
scope, files, baseline, timestamp, manual_review).
|
||||
output_path: Output file path. Defaults to
|
||||
``<repo_root>/code-review-report.html``.
|
||||
output_path: Output base path (no extension). Defaults to
|
||||
``<repo_root>/code-review-report``.
|
||||
repo_root: Repository root path. Auto-detected if omitted.
|
||||
format: Output format. ``html``, ``markdown``, or ``both``
|
||||
(default: both).
|
||||
"""
|
||||
root = _resolve_repo_root(repo_root)
|
||||
|
||||
def _run() -> dict:
|
||||
return with_provenance(generate_report_func(
|
||||
review_data=review_data, output_path=output_path,
|
||||
repo_root=root,
|
||||
repo_root=root, format=format,
|
||||
), root)
|
||||
|
||||
return await asyncio.to_thread(_run)
|
||||
@@ -1140,6 +1149,23 @@ def unified_review(base: str = "HEAD~1", tier: str = "standard") -> list[dict]:
|
||||
return unified_review_prompt(base=base, tier=tier)
|
||||
|
||||
|
||||
@mcp.prompt()
|
||||
def project_review(scope: str = "whole-project", target: str = "") -> list[dict]:
|
||||
"""Whole-project or single-feature code review (not diff-based).
|
||||
|
||||
Reviews the entire codebase (whole-project) or a single feature/module
|
||||
(feature) using graph-wide analysis and objective scoring, independent
|
||||
of the git diff. READ-ONLY: every finding waits for a manual fix
|
||||
decision.
|
||||
|
||||
Args:
|
||||
scope: Review scope. ``whole-project`` reviews every source file;
|
||||
``feature`` reviews only the target's code.
|
||||
target: Feature/module/function keyword when scope="feature".
|
||||
"""
|
||||
return project_review_prompt(scope=scope, target=target)
|
||||
|
||||
|
||||
def _apply_tool_filter(tools: str | None = None) -> None:
|
||||
"""Remove tools not listed in the allow-list.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user