"""MCP prompt templates for Code Review Graph. Provides 7 pre-built prompt workflows, all enforcing token-efficient detail_level="minimal" first patterns with get_minimal_context entry point. 1. review_changes - pre-commit review using detect_changes + affected_flows 2. architecture_map - architecture docs using communities, flows, Mermaid 3. debug_issue - guided debugging using search, flow tracing 4. onboard_developer - new dev orientation using stats, architecture, flows 5. pre_merge_check - PR readiness with risk scoring, test gaps, dead code 6. unified_review - three-layer review: graph context + scoring + dedupe + report 7. project_review - whole-project or single-feature review (not diff-based) """ from __future__ import annotations from fastmcp.prompts.prompt import Message _TOKEN_EFFICIENCY_PREAMBLE = ( # nosec B105 — prompt template, not a password """\ ## Rules for Token-Efficient Graph Usage 1. ALWAYS call `get_minimal_context` first with a task description. 2. Use `detail_level="minimal"` on all tool calls unless the minimal output \ is insufficient. 3. Only escalate to `detail_level="standard"` or `"verbose"` for the specific \ entities that need deeper inspection. 4. Never request more than 3 tool calls per turn unless absolutely necessary. 5. Prefer targeted queries (query_graph with a specific symbol) over broad \ scans (list_communities with full members). 6. When reviewing changes: detect_changes(detail_level="minimal") → only \ expand on high-risk items. """ ) def _user(content: str) -> list[Message]: """Wrap content as a single-message user prompt. fastmcp >=3.2 rejects raw dicts in prompt return values; each message must be a ``Message`` instance (or a plain ``str``). We standardise on ``Message`` so role is explicit and future multi-turn prompts compose naturally. """ return [Message(role="user", content=content)] def review_changes_prompt(base: str = "HEAD~1") -> list[Message]: """Pre-commit review workflow. Args: base: Git ref to diff against. Default: HEAD~1. """ return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" f"## Review Workflow\n" f'1. Call `get_minimal_context(task="review changes against ' f'{base}")` to get risk overview.\n' f'2. If risk is "low": call ' f'`detect_changes(detail_level="minimal")` → report summary ' f"+ any test gaps.\n" f'3. If risk is "medium" or "high":\n' f' a. Call `detect_changes(detail_level="standard")` for ' f"full change list.\n" f" b. For each high-risk function, call " f'`query_graph(pattern="callers_of", target=, ' f'detail_level="minimal")`.\n' f' c. Call `get_affected_flows(detail_level="minimal")` ' f"only if >3 changed functions.\n" f"4. Summarize: risk level, what changed, test gaps, " f"specific improvements needed.\n\n" f"Do NOT call get_review_context unless you need source code " f"snippets for a specific function." ) def architecture_map_prompt() -> list[Message]: """Architecture documentation workflow.""" return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" "## Architecture Mapping Workflow\n" '1. Call `get_minimal_context(task="map architecture")`.\n' '2. Call `get_architecture_overview(detail_level="minimal")` ' "for community coupling summary.\n" '3. Call `list_flows(detail_level="minimal")` for critical ' "flow names + criticality scores.\n" "4. Only call `get_community(name=, " 'detail_level="standard")` for the 1-2 communities the user ' "is most interested in.\n" "5. Produce a concise Mermaid diagram showing communities as " "boxes and key flows as arrows." ) def debug_issue_prompt(description: str = "") -> list[Message]: """Guided debugging workflow. Args: description: Description of the issue to debug. """ desc_part = description or "" return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" "## Debug Workflow\n" f'1. Call `get_minimal_context(task="debug: ' f'{desc_part}")`.\n' "2. Call `semantic_search_nodes(query=, detail_level="minimal", limit=5)`.\n' "3. For the top 1-2 results, call " '`query_graph(pattern="callers_of", target=, ' 'detail_level="minimal")`.\n' "4. If the issue involves execution flow: call " "`get_flow(name=)` for the single most " "relevant flow.\n" "5. Only call `get_review_context` or `get_impact_radius` " "if you need to trace the blast radius of a specific change." ) def onboard_developer_prompt() -> list[Message]: """New developer orientation workflow.""" return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" "## Onboarding Workflow\n" '1. Call `get_minimal_context(task="onboard developer")`.\n' "2. Call `list_graph_stats()` for technology overview.\n" '3. Call `get_architecture_overview(detail_level="minimal")` ' "for the 30-second mental model.\n" '4. Call `list_communities(detail_level="minimal")` — ' "present as a table of module names + sizes.\n" '5. Call `list_flows(detail_level="minimal")` — highlight ' "the top 3 critical flows.\n" "6. Only drill into a specific community or flow if the " "developer asks." ) def pre_merge_check_prompt(base: str = "HEAD~1") -> list[Message]: """PR readiness check workflow. Args: base: Git ref to diff against. Default: HEAD~1. """ return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" "## Pre-Merge Check Workflow\n" '1. Call `get_minimal_context(task="pre-merge check")`.\n' '2. Call `detect_changes(detail_level="minimal")` for risk ' "score and test gaps.\n" "3. If risk > 0.4: call " '`get_affected_flows(detail_level="minimal")`.\n' "4. If test_gap_count > 0: call " '`query_graph(pattern="tests_for", ' 'target=, detail_level="minimal")` ' "for up to 3 functions.\n" '5. Call `refactor(mode="dead_code", ' 'detail_level="minimal")` to check for newly dead code.\n' "6. Only call `find_large_functions` or `get_impact_radius` " "if risk > 0.7.\n" "7. Output: GO/NO-GO recommendation with 1-sentence " "justification + list of required follow-ups." ) def unified_review_prompt( base: str = "HEAD~1", ) -> list[Message]: """Three-layer unified review workflow (READ-ONLY). Fuses CRG graph context with the objective scoring metrics (score_review), finding merge (dedupe_findings), and the standalone HTML report (generate_report). Every finding is presented for a manual fix decision -- this workflow never modifies code. Args: base: Git ref to diff against. Default: HEAD~1. """ return _user( f"{_TOKEN_EFFICIENCY_PREAMBLE}\n" f"## Unified Review Workflow (base={base})\n" "Standard tier: run all layers.\n" "**READ-ONLY.** Present every finding for a manual fix decision. " "Never modify code, commit, or push.\n" '1. Call `get_minimal_context(task="unified review")` for the ' "risk overview.\n" '2. Call `build_or_update_graph()` to ensure the graph is ' "current.\n" '3. Call `detect_changes(detail_level="minimal")` for changed ' "files, risk score, test gaps and affected flows.\n" '4. Call `score_review(detail_level="standard")` for the ' "objective metrics (sql_risk, exception_coverage, redundancy, " "high-risk density, vulnerability). Trust the tool grades.\n" "5. Review the changed source (Layer 1 chain decomposition) and " "produce findings with severity (blocker/major/minor), " "confidence (1-10), file:line and a proposed fix.\n" '6. Call `dedupe_findings(findings=)` to merge ' "by fingerprint, boost multi-source confidence and compute the " "PR quality score.\n" '7. Call `generate_report(review_data=)` to write code-review-report.html ' "and code-review-report.md (format=\"both\").\n" "8. Output: verdict (✅ PASS / ❌ FAIL), severity counts, each " "issue with confidence + fix, and the manual-review items. " "Any blocker → verdict ❌ FAIL." ) def project_review_prompt( scope: str = "whole-project", target: str = "", ) -> list[Message]: """Whole-project or single-feature code review workflow (not diff-based). Reviews the entire codebase (``scope="whole-project"``) or a single feature/module/function (``scope="feature"`` with ``target``), using graph-wide analysis and objective scoring independent of the git diff. READ-ONLY: every finding waits for a manual fix decision. Args: scope: ``whole-project`` reviews every source file in the graph; ``feature`` reviews only the code related to ``target``. target: Feature/module/function keyword when ``scope="feature"`` (e.g. "payment", "auth", "checkout flow"). """ scope_note = ( "whole-project scope: score every source file with " "`score_review(all_files=True)`." if scope == "whole-project" else ( "feature scope: locate the target's files with semantic search " "and graph queries, then score only those files." ) ) common = ( f"## Project Review Workflow (scope={scope}, target={target})\n" f"{scope_note}\n" "**READ-ONLY.** Present every finding for a manual fix decision. " "Never modify code, commit, or push.\n" '1. Call `get_minimal_context(task="project review")` for graph ' "stats and community overview.\n" '2. Call `build_or_update_graph()` to ensure the graph is current.\n' '3. Map the architecture: `get_architecture_overview(' 'detail_level="minimal")` and `list_communities(' 'detail_level="minimal")`.\n' '4. Locate high-risk areas: `get_knowledge_gaps()`, ' '`get_hub_nodes()`, `get_bridge_nodes()`, `find_large_functions()` ' "and `get_surprising_connections()`.\n" ) if scope == "whole-project": workflow = ( '5. Score every source file: `score_review(all_files=True)`.\n' "6. For the top-risk communities, drill in with " '`get_community(include_members=True)` and ' '`query_graph(pattern="children_of", target=)`.\n' "7. Produce findings with severity (blocker/major/minor), " "confidence (1-10), file:line and a proposed fix.\n" "8. Call `dedupe_findings(findings=)` to merge " "and compute the PR quality score.\n" '9. Call `generate_report(review_data=)` (format="both").\n' "10. Output the verdict (✅ PASS / ❌ FAIL), severity counts, " "each issue, and the manual-review items.\n" ) else: workflow = ( '5. Locate the feature code: `semantic_search_nodes(query=' ')` and `query_graph(pattern="children_of", ' 'target=)`; collect the related files.\n' "6. Map the blast radius: `get_impact_radius(changed_files=" ")`.\n" '7. Score the feature: `score_review(changed_files=)`.\n' "8. Review the feature code (Layer 1 chain decomposition) and " "produce findings with severity, confidence, file:line and a " "proposed fix.\n" "9. Call `dedupe_findings(findings=)` to merge " "and compute the PR quality score.\n" '10. Call `generate_report(review_data=)` (format="both").\n' "11. Output the verdict (✅ PASS / ❌ FAIL), severity counts, " "each issue, and the manual-review items.\n" ) return _user(f"{_TOKEN_EFFICIENCY_PREAMBLE}\n{common}{workflow}")