//! AUTO-GENERATED by `scripts/regen-tool-defs.py`. DO NOT EDIT.
//!
//! Source: `crates/codelens-mcp/tools.toml`
//! Run `python3 scripts/regen-tool-defs.py --write` to refresh.
//!
//! See `docs/adr/ADR-0013-tool-defs-codegen.md` for the migration plan.

#![allow(clippy::too_many_lines)]

use crate::protocol::{Tool, ToolAnnotations};
use crate::tool_defs::output_schemas::*;
use serde_json::json;

pub fn analysis_tools(ro_a: &ToolAnnotations, ro_p: &ToolAnnotations) -> Vec<Tool> {
    vec![
        Tool::new(
            "get_changed_files",
            "[CodeLens:Analysis] Files changed since a git ref with symbol counts. Use for diff review.",
            json!({"type":"object","properties":{"ref":{"type":"string"},"include_untracked":{"type":"boolean"}}}),
        ).with_output_schema(changed_files_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "get_callers",
            "[CodeLens:Analysis] Find functions that call a function. Returns bounded call-graph edges with backend/confidence metadata.",
            json!({"type":"object","required":["function_name"],"properties":{"function_name":{"type":"string"},"file_path":{"type":"string","description":"Optional file scope for caller search"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(get_callers_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "get_callees",
            "[CodeLens:Analysis] Find functions called by a function. Use file_path when duplicate function names exist.",
            json!({"type":"object","required":["function_name"],"properties":{"function_name":{"type":"string"},"file_path":{"type":"string"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(get_callees_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "find_scoped_references",
            "[CodeLens:Analysis] Classify each reference as definition/read/write/import.",
            json!({"type":"object","required":["symbol_name"],"properties":{"symbol_name":{"type":"string","description":"Symbol name to find references for"},"file_path":{"type":"string","description":"Declaration file (for sorting, optional)"},"max_results":{"type":"integer","description":"Max results (default 50)"}}}),
        ).with_output_schema(references_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "get_symbol_importance",
            "[CodeLens:Analysis] PageRank file importance — find the most critical files in the project.",
            json!({"type":"object","properties":{"top_n":{"type":"integer"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "find_circular_dependencies",
            "[CodeLens:Analysis] Detect circular imports using Tarjan SCC algorithm.",
            json!({"type":"object","properties":{"max_results":{"type":"integer"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "get_change_coupling",
            "[CodeLens:Analysis] Files that frequently change together in git history.",
            json!({"type":"object","properties":{"months":{"type":"integer"},"min_strength":{"type":"number"},"min_commits":{"type":"integer"},"max_results":{"type":"integer"}}}),
        ).with_annotations(ro_a.clone()),
    ]
}

pub fn composite_tools(
    mut_w: &ToolAnnotations,
    ro_a: &ToolAnnotations,
    ro_p: &ToolAnnotations,
    ro_w: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "explain_code_flow",
            "[CodeLens:Analysis] Summarize how a function fits in the call graph: callers, callees, and a one-line flow summary. Lighter than trace_request_path.",
            json!({"type":"object","required":["function_name"],"properties":{"function_name":{"type":"string"},"max_depth":{"type":"integer"},"max_results":{"type":"integer"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "onboard_project",
            "[CodeLens:Session] One-shot onboarding: structure, key files, cycles, stats.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(onboard_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "analyze_change_request",
            "[CodeLens:Workflow] Compress a change request into ranked files, key symbols, risk, and next actions.",
            json!({"type":"object","required":["task"],"properties":{"task":{"type":"string"},"changed_files":{"type":"array","items":{"type":"string"}},"profile_hint":{"type":"string","enum":["planner-readonly","builder-minimal","reviewer-graph","refactor-full","ci-audit"]}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "verify_change_readiness",
            "[CodeLens:Workflow] Verifier-first preflight: blockers, readiness, and next evidence before editing.",
            json!({"type":"object","required":["task"],"properties":{"task":{"type":"string"},"changed_files":{"type":"array","items":{"type":"string"}},"profile_hint":{"type":"string","enum":["planner-readonly","builder-minimal","reviewer-graph","refactor-full","ci-audit"]}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "find_minimal_context_for_change",
            "[CodeLens:Workflow] Return the smallest useful file and symbol context needed to start a change.",
            json!({"type":"object","required":["task"],"properties":{"task":{"type":"string"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "summarize_symbol_impact",
            "[CodeLens:Workflow] Summarize callers, references, and affected files for one symbol.",
            json!({"type":"object","required":["symbol"],"properties":{"symbol":{"type":"string"},"file_path":{"type":"string"},"depth":{"type":"integer"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "module_boundary_report",
            "[CodeLens:Workflow] Summarize dependency boundaries, coupling, and cycle risk for a module or path.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "mermaid_module_graph",
            "[CodeLens:Workflow] Render upstream/downstream module dependencies as a Mermaid flowchart ready to embed in GitHub/GitLab Markdown.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string"},"max_nodes":{"type":"integer","description":"Max nodes rendered per side (default 10)"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "safe_rename_report",
            "[CodeLens:Workflow] Assess rename safety, blockers, and preview edits before refactoring.",
            json!({"type":"object","required":["file_path","symbol"],"properties":{"file_path":{"type":"string"},"symbol":{"type":"string"},"new_name":{"type":"string"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "unresolved_reference_check",
            "[CodeLens:Workflow] Lightweight unresolved or ambiguous reference guard before rename or broad edits.",
            json!({"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string"},"symbol":{"type":"string"},"changed_files":{"type":"array","items":{"type":"string"}}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "dead_code_report",
            "[CodeLens:Workflow] Summarize dead-code candidates with bounded evidence and deletion risk.",
            json!({"type":"object","properties":{"scope":{"type":"string"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "impact_report",
            "[CodeLens:Workflow] Summarize changed-file impact, references, and blast radius with a bounded report.",
            json!({"type":"object","properties":{"path":{"type":"string"},"changed_files":{"type":"array","items":{"type":"string"}}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "refactor_safety_report",
            "[CodeLens:Workflow] Combine boundary, symbol impact, and test cues into a preview-first refactor report.",
            json!({"type":"object","properties":{"task":{"type":"string"},"symbol":{"type":"string"},"path":{"type":"string"},"file_path":{"type":"string"}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "diff_aware_references",
            "[CodeLens:Workflow] Compress references for changed files into a bounded reviewer/CI report.",
            json!({"type":"object","properties":{"changed_files":{"type":"array","items":{"type":"string"}}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "semantic_code_review",
            "[CodeLens:Workflow] Semantic code review — analyze changed symbols via references, embedding similarity, and risk assessment.",
            json!({"type":"object","properties":{"changed_files":{"type":"array","items":{"type":"string"}}}}),
        ).with_output_schema(analysis_handle_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(2048),
        Tool::new(
            "start_analysis_job",
            "[CodeLens:Workflow] Start a durable analysis job and return a job handle for polling.",
            json!({"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["impact_report","dead_code_report","refactor_safety_report","semantic_code_review","eval_session_audit"]},"task":{"type":"string"},"symbol":{"type":"string"},"path":{"type":"string"},"file_path":{"type":"string"},"changed_files":{"type":"array","items":{"type":"string"}},"profile_hint":{"type":"string","enum":["planner-readonly","builder-minimal","reviewer-graph","refactor-full","ci-audit"]}}}),
        ).with_output_schema(analysis_job_output_schema()).with_annotations(ro_w.clone()),
        Tool::new(
            "get_analysis_job",
            "[CodeLens:Workflow] Poll a durable analysis job by job_id.",
            json!({"type":"object","required":["job_id"],"properties":{"job_id":{"type":"string"}}}),
        ).with_output_schema(analysis_job_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "cancel_analysis_job",
            "[CodeLens:Workflow] Cancel a queued or running analysis job by job_id.",
            json!({"type":"object","required":["job_id"],"properties":{"job_id":{"type":"string"}}}),
        ).with_output_schema(analysis_job_output_schema()).with_annotations(mut_w.clone()),
        Tool::new(
            "retry_analysis_job",
            "[CodeLens:Workflow] Retry a failed or cancelled analysis job by job_id; reuses the original kind and profile_hint.",
            json!({"type":"object","required":["job_id"],"properties":{"job_id":{"type":"string"}}}),
        ).with_output_schema(analysis_job_output_schema()).with_annotations(mut_w.clone()),
        Tool::new(
            "list_analysis_jobs",
            "[CodeLens:Workflow] List durable analysis jobs with status counts and any attached analysis handles.",
            json!({"type":"object","properties":{"status":{"type":"string","enum":["queued","running","completed","cancelled","error"]}}}),
        ).with_output_schema(analysis_job_list_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "list_analysis_artifacts",
            "[CodeLens:Workflow] List stored analysis artifacts with summary resource handles for reuse.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(analysis_artifact_list_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "get_analysis_section",
            "[CodeLens:Workflow] Expand a stored analysis section by analysis_id.",
            json!({"type":"object","required":["analysis_id","section"],"properties":{"analysis_id":{"type":"string"},"section":{"type":"string"}}}),
        ).with_output_schema(analysis_section_output_schema()).with_annotations(ro_p.clone()),
    ]
}

pub fn editing_tools(
    dest_a: &ToolAnnotations,
    destructive: &ToolAnnotations,
    mut_p: &ToolAnnotations,
    mut_w: &ToolAnnotations,
    mutating: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "rename_symbol",
            "[CodeLens:Edit] Rename across project — safe multi-file refactoring. Use dry_run=true to preview.",
            json!({"type":"object","required":["file_path","new_name"],"properties":{"file_path":{"type":"string","description":"File containing the symbol declaration"},"symbol_name":{"type":"string","description":"Current symbol name"},"name":{"type":"string","description":"Alias for symbol_name"},"new_name":{"type":"string","description":"Desired new name"},"name_path":{"type":"string","description":"Qualified name path (e.g. 'Class/method')"},"scope":{"type":"string","enum":["file","project"],"description":"Rename scope (default: project; tree-sitter backend only)"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"Opt-in precise edit backend. lsp uses inspectable WorkspaceEdit APIs; jetbrains/roslyn are fail-closed adapter boundaries until a local adapter is configured."},"line":{"type":"integer","description":"1-based declaration line for semantic_edit_backend=lsp; derived from symbol index when omitted"},"column":{"type":"integer","description":"1-based declaration column for semantic_edit_backend=lsp; derived from symbol index when omitted"},"command":{"type":"string","description":"Optional LSP server command for semantic_edit_backend=lsp"},"args":{"type":"array","items":{"type":"string"},"description":"Optional LSP server args for semantic_edit_backend=lsp"},"dry_run":{"type":"boolean","description":"Preview changes without modifying files"}}}),
        ).with_output_schema(rename_output_schema()).with_annotations(dest_a.clone()),
        Tool::new(
            "replace_symbol_body",
            "[CodeLens:Edit] Replace function/class body by name — tree-sitter finds boundaries. No line numbers needed.",
            json!({"type":"object","required":["relative_path","symbol_name","new_body"],"properties":{"relative_path":{"type":"string"},"symbol_name":{"type":"string"},"name_path":{"type":"string"},"new_body":{"type":"string"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_w.clone()),
        Tool::new(
            "replace_content",
            "[CodeLens:Edit] Find-and-replace text in a file — literal or regex mode.",
            json!({"type":"object","required":["relative_path","old_text","new_text"],"properties":{"relative_path":{"type":"string"},"old_text":{"type":"string"},"new_text":{"type":"string"},"regex_mode":{"type":"boolean"}}}),
        ).with_output_schema(replace_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "replace_lines",
            "[CodeLens:Edit] Replace a line range (1-indexed). Use when you know exact line numbers.",
            json!({"type":"object","required":["relative_path","start_line","end_line","new_content"],"properties":{"relative_path":{"type":"string"},"start_line":{"type":"integer"},"end_line":{"type":"integer"},"new_content":{"type":"string"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "delete_lines",
            "[CodeLens:Edit] Delete a line range (1-indexed, end exclusive).",
            json!({"type":"object","required":["relative_path","start_line","end_line"],"properties":{"relative_path":{"type":"string"},"start_line":{"type":"integer"},"end_line":{"type":"integer"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(destructive.clone()),
        Tool::new(
            "insert_at_line",
            "[CodeLens:Edit] Insert content at a line number. Use when you know the exact position.",
            json!({"type":"object","required":["relative_path","line","content"],"properties":{"relative_path":{"type":"string"},"line":{"type":"integer"},"content":{"type":"string"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "insert_before_symbol",
            "[CodeLens:Edit] Insert code before a named symbol — tree-sitter finds position.",
            json!({"type":"object","required":["relative_path","symbol_name","content"],"properties":{"relative_path":{"type":"string"},"symbol_name":{"type":"string"},"name_path":{"type":"string"},"content":{"type":"string"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "insert_after_symbol",
            "[CodeLens:Edit] Insert code after a named symbol — tree-sitter finds position.",
            json!({"type":"object","required":["relative_path","symbol_name","content"],"properties":{"relative_path":{"type":"string"},"symbol_name":{"type":"string"},"name_path":{"type":"string"},"content":{"type":"string"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "insert_content",
            "[CodeLens:Edit] Insert code at position='line'|'before_symbol'|'after_symbol'.",
            json!({"type":"object","required":["relative_path","content"],"properties":{"relative_path":{"type":"string"},"content":{"type":"string"},"position":{"type":"string","enum":["line","before_symbol","after_symbol"],"description":"Insertion position type (default: line)"},"line":{"type":"integer","description":"Line number (for position=line)"},"symbol_name":{"type":"string","description":"Symbol name (for position=before_symbol or after_symbol)"},"name_path":{"type":"string","description":"Qualified name path"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "replace",
            "[CodeLens:Edit] Replace text or line range. Set mode='text' (find-replace) or mode='lines' (line range).",
            json!({"type":"object","required":["relative_path"],"properties":{"relative_path":{"type":"string"},"mode":{"type":"string","enum":["text","lines"],"description":"Replace mode (default: text)"},"old_text":{"type":"string","description":"Text to find (mode=text)"},"new_text":{"type":"string","description":"Replacement text (mode=text)"},"regex_mode":{"type":"boolean","description":"Use regex (mode=text)"},"start_line":{"type":"integer","description":"Start line (mode=lines)"},"end_line":{"type":"integer","description":"End line (mode=lines)"},"new_content":{"type":"string","description":"New content (mode=lines)"}}}),
        ).with_output_schema(replace_content_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "create_text_file",
            "[CodeLens:Edit] Create a new file. Fails if exists unless overwrite=true.",
            json!({"type":"object","required":["relative_path","content"],"properties":{"relative_path":{"type":"string"},"content":{"type":"string"},"overwrite":{"type":"boolean"}}}),
        ).with_output_schema(create_text_file_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "analyze_missing_imports",
            "[CodeLens:Edit] Detect unresolved symbols and suggest imports.",
            json!({"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string","description":"File to analyze"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "add_import",
            "[CodeLens:Edit] Insert an import statement at the correct position.",
            json!({"type":"object","required":["file_path","import_statement"],"properties":{"file_path":{"type":"string"},"import_statement":{"type":"string","description":"Import statement to add"}}}),
        ).with_output_schema(add_import_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "refactor_extract_function",
            "[CodeLens:Edit] Extract line range into new function with automatic call-site replacement.",
            json!({"type":"object","required":["file_path","start_line","end_line","new_name"],"properties":{"file_path":{"type":"string"},"start_line":{"type":"integer"},"start_column":{"type":"integer"},"end_line":{"type":"integer"},"end_column":{"type":"integer"},"new_name":{"type":"string","description":"Name for the new function"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"lsp applies only concrete WorkspaceEdit codeAction results; jetbrains/roslyn fail closed until a local adapter exists."},"code_action_kind":{"type":"string","description":"Optional LSP code action kind override"},"code_action_kinds":{"type":"array","items":{"type":"string"},"description":"Optional LSP code action kind list override"},"action_id":{"type":"string","description":"Title, kind, or index to select when multiple code actions match"},"command":{"type":"string","description":"Optional LSP server command"},"args":{"type":"array","items":{"type":"string"},"description":"Optional LSP server args"},"dry_run":{"type":"boolean","description":"Preview without modifying (default true)"}}}),
        ).with_output_schema(semantic_refactor_output_schema()).with_annotations(mut_w.clone()),
        Tool::new(
            "refactor_inline_function",
            "[CodeLens:Edit] Inline a function: replace all call sites with body, remove definition.",
            json!({"type":"object","required":["file_path","function_name"],"properties":{"file_path":{"type":"string","description":"File containing the function definition"},"function_name":{"type":"string","description":"Function to inline"},"name_path":{"type":"string","description":"Qualified name path (e.g. Class/method)"},"line":{"type":"integer","description":"1-based symbol line for semantic_edit_backend=lsp"},"column":{"type":"integer","description":"1-based symbol byte column for semantic_edit_backend=lsp"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"lsp applies only concrete WorkspaceEdit codeAction results; jetbrains/roslyn fail closed until a local adapter exists."},"code_action_kind":{"type":"string"},"code_action_kinds":{"type":"array","items":{"type":"string"}},"action_id":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"dry_run":{"type":"boolean","description":"Preview without modifying (default true)"}}}),
        ).with_output_schema(semantic_refactor_output_schema()).with_annotations(mut_w.clone()),
        Tool::new(
            "refactor_move_to_file",
            "[CodeLens:Edit] Move a symbol to another file, updating imports across the project.",
            json!({"type":"object","required":["file_path","symbol_name","target_file"],"properties":{"file_path":{"type":"string","description":"Source file"},"symbol_name":{"type":"string","description":"Symbol to move"},"target_file":{"type":"string","description":"Destination file"},"name_path":{"type":"string","description":"Qualified name path"},"line":{"type":"integer","description":"1-based symbol line for semantic_edit_backend=lsp"},"column":{"type":"integer","description":"1-based symbol byte column for semantic_edit_backend=lsp"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"lsp applies only concrete WorkspaceEdit codeAction results; jetbrains/roslyn fail closed until a local adapter exists."},"code_action_kind":{"type":"string"},"code_action_kinds":{"type":"array","items":{"type":"string"}},"action_id":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"dry_run":{"type":"boolean","description":"Preview without modifying (default true)"}}}),
        ).with_output_schema(semantic_refactor_output_schema()).with_annotations(dest_a.clone()),
        Tool::new(
            "refactor_change_signature",
            "[CodeLens:Edit] Change function parameters and update all call sites.",
            json!({"type":"object","required":["file_path","function_name","new_parameters"],"properties":{"file_path":{"type":"string","description":"File containing the function"},"function_name":{"type":"string","description":"Function to modify"},"name_path":{"type":"string","description":"Qualified name path"},"new_parameters":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"},"default":{"type":"string"}}},"description":"New parameter list"},"line":{"type":"integer","description":"1-based symbol line for semantic_edit_backend=lsp"},"column":{"type":"integer","description":"1-based symbol byte column for semantic_edit_backend=lsp"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"lsp applies only concrete WorkspaceEdit codeAction results; jetbrains/roslyn fail closed until a local adapter exists."},"code_action_kind":{"type":"string"},"code_action_kinds":{"type":"array","items":{"type":"string"}},"action_id":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"dry_run":{"type":"boolean","description":"Preview without modifying (default true)"}}}),
        ).with_output_schema(semantic_refactor_output_schema()).with_annotations(dest_a.clone()),
        Tool::new(
            "propagate_deletions",
            "[CodeLens:Edit] Analyze what breaks if a symbol is deleted and list affected references/imports for cleanup.",
            json!({"type":"object","required":["file_path","symbol_name"],"properties":{"file_path":{"type":"string","description":"File containing the symbol"},"symbol_name":{"type":"string","description":"Symbol to analyze for deletion"},"semantic_edit_backend":{"type":"string","enum":["tree-sitter","lsp","jetbrains","roslyn"],"description":"Opt-in precise safe-delete check. lsp uses textDocument/references; jetbrains/roslyn fail closed until a local adapter exists."},"line":{"type":"integer","description":"1-based declaration line for semantic_edit_backend=lsp; derived from symbol index when omitted"},"column":{"type":"integer","description":"1-based declaration column for semantic_edit_backend=lsp; derived from symbol index when omitted"},"command":{"type":"string","description":"Optional LSP server command for semantic_edit_backend=lsp"},"args":{"type":"array","items":{"type":"string"},"description":"Optional LSP server args for semantic_edit_backend=lsp"},"max_results":{"type":"integer","description":"Maximum LSP references to inspect (default 200)"},"dry_run":{"type":"boolean","description":"Preview without modifying (default true)"}}}),
        ).with_output_schema(safe_delete_output_schema()).with_annotations(mut_w.clone()),
    ]
}

pub fn file_io_tools(ro_p: &ToolAnnotations) -> Vec<Tool> {
    vec![
        Tool::new(
            "get_current_config",
            "[CodeLens:Session] Project config and index stats. Use to verify project is active.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(get_current_config_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "read_file",
            "[CodeLens:File] Read file contents with optional line range.",
            json!({"type":"object","required":["relative_path"],"properties":{"relative_path":{"type":"string"},"start_line":{"type":"integer"},"end_line":{"type":"integer"}}}),
        ).with_output_schema(file_content_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "list_dir",
            "[CodeLens:File] List directory contents, optionally recursive.",
            json!({"type":"object","required":["relative_path"],"properties":{"relative_path":{"type":"string"},"recursive":{"type":"boolean"}}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "find_file",
            "[CodeLens:File] Find files by wildcard pattern.",
            json!({"type":"object","required":["wildcard_pattern"],"properties":{"wildcard_pattern":{"type":"string"},"relative_dir":{"type":"string"}}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "search_for_pattern",
            "[CodeLens:File] Regex search across files. Use smart=true for enclosing symbol context.",
            json!({"type":"object","properties":{"pattern":{"type":"string"},"substring_pattern":{"type":"string"},"file_glob":{"type":"string"},"max_results":{"type":"integer"},"smart":{"type":"boolean","description":"Include enclosing symbol context for each match"},"context_lines":{"type":"integer","description":"Number of context lines before and after each match (default 0)"},"context_lines_before":{"type":"integer","description":"Context lines before each match (overrides context_lines)"},"context_lines_after":{"type":"integer","description":"Context lines after each match (overrides context_lines)"}}}),
        ).with_output_schema(search_for_pattern_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "find_annotations",
            "[CodeLens:File] Find TODO/FIXME/HACK comments across the project.",
            json!({"type":"object","properties":{"tags":{"type":"string"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(find_annotations_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "find_tests",
            "[CodeLens:File] Find test functions and test modules.",
            json!({"type":"object","properties":{"path":{"type":"string"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(find_tests_output_schema()).with_annotations(ro_p.clone()),
    ]
}

pub fn lsp_tools(ro_a: &ToolAnnotations, ro_p: &ToolAnnotations) -> Vec<Tool> {
    vec![
        Tool::new(
            "find_referencing_symbols",
            "[CodeLens:Symbol] Find all usages of a symbol. use_lsp=true for type-aware precision.",
            json!({"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string","description":"File containing or declaring the symbol"},"symbol_name":{"type":"string","description":"Symbol name (default: tree-sitter search)"},"line":{"type":"integer","description":"Line number (triggers LSP path)"},"column":{"type":"integer","description":"Column number (triggers LSP path)"},"use_lsp":{"type":"boolean","description":"Force LSP lookup (slower but type-aware, requires LSP server)"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"max_results":{"type":"integer"}}}),
        ).with_output_schema(references_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "get_file_diagnostics",
            "[CodeLens:Symbol] Type errors and lint issues via LSP. Use after editing code.",
            json!({"type":"object","required":["file_path"],"properties":{"file_path":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"max_results":{"type":"integer"}}}),
        ).with_output_schema(diagnostics_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "search_workspace_symbols",
            "[CodeLens:Symbol] LSP workspace symbol search. Use when you need type-system-aware results. Requires an LSP server binary via `command` (e.g. rust-analyzer / pyright); the handler returns a structured hint toward `bm25_symbol_search` when omitted.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"max_results":{"type":"integer"}}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "get_type_hierarchy",
            "[CodeLens:Symbol] Inheritance hierarchy — supertypes and subtypes of a class/interface.",
            json!({"type":"object","properties":{"name_path":{"type":"string"},"fully_qualified_name":{"type":"string"},"relative_path":{"type":"string"},"hierarchy_type":{"type":"string","enum":["super","sub","both"]},"depth":{"type":"integer"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}}}}),
        ).with_output_schema(get_type_hierarchy_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "resolve_symbol_target",
            "[CodeLens:Symbol] Resolve declaration/definition/implementation/type target through LSP. Use when edit-grade navigation authority is required.",
            json!({"type":"object","required":["file_path","line","column"],"properties":{"file_path":{"type":"string"},"line":{"type":"integer","description":"1-based source line"},"column":{"type":"integer","description":"1-based byte column; converted to LSP UTF-16 internally"},"target":{"type":"string","enum":["declaration","definition","implementation","type_definition"],"description":"Target kind (default: definition)"},"semantic_backend":{"type":"string","enum":["lsp"],"description":"Only lsp is authoritative for this tool"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"max_results":{"type":"integer"}}}),
        ).with_output_schema(resolve_symbol_target_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "plan_symbol_rename",
            "[CodeLens:Symbol] Preview rename refactoring via LSP — check before applying.",
            json!({"type":"object","required":["file_path","line","column"],"properties":{"file_path":{"type":"string"},"line":{"type":"integer"},"column":{"type":"integer"},"new_name":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "check_lsp_status",
            "[CodeLens:Session] Check installed LSP servers with install commands.",
            json!({"type":"object","properties":{}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "get_lsp_recipe",
            "[CodeLens:Session] Get LSP server install instructions for a file extension.",
            json!({"type":"object","required":["extension"],"properties":{"extension":{"type":"string","description":"File extension (e.g. 'py', 'rs')"}}}),
        ).with_annotations(ro_p.clone()),
    ]
}

pub fn memory_tools(
    destructive: &ToolAnnotations,
    mut_p: &ToolAnnotations,
    mutating: &ToolAnnotations,
    ro_p: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "list_memories",
            "[CodeLens:Memory] List project memory files under .codelens/memories.",
            json!({"type":"object","properties":{"topic":{"type":"string","description":"Optional topic to filter"}}}),
        ).with_output_schema(memory_list_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "read_memory",
            "[CodeLens:Memory] Read a named project memory file.",
            json!({"type":"object","required":["memory_name"],"properties":{"memory_name":{"type":"string"}}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "write_memory",
            "[CodeLens:Memory] Create or overwrite a project memory file.",
            json!({"type":"object","required":["memory_name","content"],"properties":{"memory_name":{"type":"string"},"content":{"type":"string"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "delete_memory",
            "[CodeLens:Memory] Delete a project memory file.",
            json!({"type":"object","required":["memory_name"],"properties":{"memory_name":{"type":"string"}}}),
        ).with_annotations(destructive.clone()),
        Tool::new(
            "rename_memory",
            "[CodeLens:Memory] Rename a project memory file.",
            json!({"type":"object","required":["old_name","new_name"],"properties":{"old_name":{"type":"string"},"new_name":{"type":"string"}}}),
        ).with_annotations(mut_p.clone()),
    ]
}

pub fn rule_corpus_tools(ro_a: &ToolAnnotations) -> Vec<Tool> {
    vec![
        Tool::new(
            "find_relevant_rules",
            "[CodeLens:Workflow] BM25 search over CLAUDE.md + project memory for policy snippets matching a query. Separate corpus from code retrieval — rule text never pollutes semantic_search results.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Natural-language query; identifier tokens are preserved"},"top_k":{"type":"integer","description":"Top-K results (1-20, default 3)"}}}),
        ).with_annotations(ro_a.clone()).with_max_response_tokens(2048),
    ]
}

#[cfg(feature = "semantic")]
pub fn semantic_tools(
    ro: &ToolAnnotations,
    ro_a: &ToolAnnotations,
    ro_p: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "semantic_search",
            "[CodeLens:Symbol] Natural language code search via embeddings — find code by meaning.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Natural language search query"},"max_results":{"type":"integer","description":"Max results (default 20)"}}}),
        ).with_output_schema(semantic_search_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "index_embeddings",
            "[CodeLens:Symbol] Build semantic embedding index and optionally prewarm query embeddings. Required before semantic_search.",
            json!({"type":"object","properties":{"background":{"type":"boolean","description":"Run as a durable background job and poll with get_analysis_job"},"prewarm_queries":{"type":"array","items":{"type":"string"},"description":"Representative semantic_search queries to warm immediately after indexing"},"prewarm_limit":{"type":"integer","description":"Maximum prewarm query count (default 128, max 1024)"}}}),
        ).with_annotations(ro.clone()),
        Tool::new(
            "find_similar_code",
            "[CodeLens:Analysis] Find semantically similar code to a given symbol — clone detection, reuse opportunities.",
            json!({"type":"object","required":["file_path","symbol_name"],"properties":{"file_path":{"type":"string","description":"File containing the symbol"},"symbol_name":{"type":"string","description":"Symbol to find similar code for"},"max_results":{"type":"integer","description":"Max results (default 10)"}}}),
        ).with_output_schema(find_similar_code_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "find_code_duplicates",
            "[CodeLens:Analysis] Find near-duplicate code pairs across the codebase — DRY violations.",
            json!({"type":"object","properties":{"threshold":{"type":"number","description":"Cosine similarity threshold (default 0.85)"},"max_pairs":{"type":"integer","description":"Max pairs to return (default 20)"}}}),
        ).with_output_schema(find_code_duplicates_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "classify_symbol",
            "[CodeLens:Analysis] Zero-shot classify a symbol into categories — e.g. error handling, auth, database.",
            json!({"type":"object","required":["file_path","symbol_name","categories"],"properties":{"file_path":{"type":"string"},"symbol_name":{"type":"string"},"categories":{"type":"array","items":{"type":"string"},"description":"Category labels to classify against"}}}),
        ).with_output_schema(classify_symbol_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "find_misplaced_code",
            "[CodeLens:Analysis] Find symbols that are semantic outliers in their file — possible misplacement.",
            json!({"type":"object","properties":{"max_results":{"type":"integer","description":"Max outliers to return (default 10)"}}}),
        ).with_output_schema(find_misplaced_code_output_schema()).with_annotations(ro.clone()),
    ]
}

pub fn session_tools(
    mut_coord: &ToolAnnotations,
    mut_p: &ToolAnnotations,
    mutating: &ToolAnnotations,
    ro_a: &ToolAnnotations,
    ro_p: &ToolAnnotations,
    ro_w: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "activate_project",
            "[CodeLens:Session] Activate project — auto-detect preset, index, frameworks.",
            json!({"type":"object","properties":{"project":{"type":"string","description":"Optional project name or path"}}}),
        ).with_output_schema(activate_project_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "prepare_harness_session",
            "[CodeLens:Session] Official bootstrap/status entrypoint for harnesses — activate project, summarize surface, capabilities, visible tools, and optionally auto-recover a small stale index in one call.",
            json!({"type":"object","properties":{"project":{"type":"string","description":"Optional project name or path"},"profile":{"type":"string","enum":["planner-readonly","builder-minimal","reviewer-graph","refactor-full","ci-audit"]},"preset":{"type":"string","enum":["minimal","balanced","full"]},"token_budget":{"type":"integer","description":"Optional explicit token budget override after activation"},"file_path":{"type":"string","description":"Optional file path for language-specific capability checks"},"detail":{"type":"string","enum":["compact","full"],"description":"compact returns the harness preflight essentials only; full also includes the heavier config snapshot"},"host_context":{"type":"string","enum":["claude-code","codex","cursor","cline","windsurf","vscode","jetbrains","api-agent"],"description":"Optional host/runtime hint used to compile advisory bootstrap routing without changing the active tool surface"},"task_overlay":{"type":"string","enum":["planning","editing","review","onboarding","batch-analysis","interactive"],"description":"Optional task-mode hint used to compile advisory bootstrap routing without changing the active tool surface"},"preferred_entrypoints":{"type":"array","items":{"type":"string"},"description":"Optional ordered entrypoints so the server can report which are immediately visible"},"auto_refresh_stale":{"type":"boolean","description":"When true (default), bootstrap auto-refreshes a small stale symbol index before reporting capabilities"},"auto_refresh_stale_threshold":{"type":"integer","description":"Maximum stale file count eligible for automatic refresh during bootstrap (default 32)"}}}),
        ).with_output_schema(prepare_harness_session_output_schema()).with_annotations(mutating.clone()),
        Tool::new(
            "register_agent_work",
            "[CodeLens:Session] Register the current agent intent, branch, and worktree for advisory multi-agent coordination.",
            json!({"type":"object","required":["agent_name","branch","worktree","intent"],"properties":{"session_id":{"type":"string","description":"Optional logical session id. Defaults to the active _session_id."},"agent_name":{"type":"string"},"branch":{"type":"string"},"worktree":{"type":"string"},"intent":{"type":"string"},"ttl_secs":{"type":"integer","description":"Optional advisory TTL in seconds (default 300, clamped to 30-3600)."}}}),
        ).with_output_schema(register_agent_work_output_schema()).with_annotations(mut_coord.clone()),
        Tool::new(
            "list_active_agents",
            "[CodeLens:Session] List active agent registrations and their claimed paths for the current project scope.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(list_active_agents_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "claim_files",
            "[CodeLens:Session] Advisory file claim for the active session. Claims downgrade readiness to caution for overlapping sessions but never hard-block writes.",
            json!({"type":"object","required":["paths","reason"],"properties":{"session_id":{"type":"string","description":"Optional logical session id. Defaults to the active _session_id."},"paths":{"type":"array","items":{"type":"string"},"description":"Project-relative paths to claim"},"reason":{"type":"string"},"ttl_secs":{"type":"integer","description":"Optional advisory TTL in seconds (default 300, clamped to 30-3600)."}}}),
        ).with_output_schema(claim_files_output_schema()).with_annotations(mut_coord.clone()),
        Tool::new(
            "release_files",
            "[CodeLens:Session] Release previously claimed files for the active session.",
            json!({"type":"object","required":["paths"],"properties":{"session_id":{"type":"string","description":"Optional logical session id. Defaults to the active _session_id."},"paths":{"type":"array","items":{"type":"string"},"description":"Project-relative paths to release"}}}),
        ).with_output_schema(release_files_output_schema()).with_annotations(mut_coord.clone()),
        Tool::new(
            "prepare_for_new_conversation",
            "[CodeLens:Session] Project context summary for a new conversation.",
            json!({"type":"object","properties":{}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "summarize_changes",
            "[CodeLens:Session] Summarize recent git changes with symbol context.",
            json!({"type":"object","properties":{}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "get_watch_status",
            "[CodeLens:Session] File watcher status: running, events, reindexed files.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(watch_status_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "prune_index_failures",
            "[CodeLens:Session] Remove stale index-failure records for deleted files.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(prune_index_failures_output_schema()).with_annotations(mut_p.clone()),
        Tool::new(
            "add_queryable_project",
            "[CodeLens:Session] Register external project for cross-project queries.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string","description":"Absolute path to the project directory"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "remove_queryable_project",
            "[CodeLens:Session] Unregister an external project.",
            json!({"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Project name to remove"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "query_project",
            "[CodeLens:Session] Search symbols in a registered external project.",
            json!({"type":"object","required":["project_name","symbol_name"],"properties":{"project_name":{"type":"string","description":"Name of the registered project"},"symbol_name":{"type":"string","description":"Symbol name to search for"},"max_results":{"type":"integer","description":"Max results (default 20)"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "list_queryable_projects",
            "[CodeLens:Session] List all registered projects (active + external).",
            json!({"type":"object","properties":{}}),
        ).with_annotations(ro_p.clone()),
        Tool::new(
            "set_preset",
            "[CodeLens:Session] Switch tool preset at runtime. Auto-adjusts token budget.",
            json!({"type":"object","required":["preset"],"properties":{"preset":{"type":"string","enum":["minimal","balanced","full"],"description":"Target preset"},"token_budget":{"type":"integer","description":"Override token budget (default: auto per preset)"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "set_profile",
            "[CodeLens:Session] Switch the active role profile. Preferred for harness-oriented workflows.",
            json!({"type":"object","required":["profile"],"properties":{"profile":{"type":"string","enum":["planner-readonly","builder-minimal","reviewer-graph","refactor-full","ci-audit"]},"token_budget":{"type":"integer","description":"Override token budget for the active profile"}}}),
        ).with_annotations(mutating.clone()),
        Tool::new(
            "get_capabilities",
            "[CodeLens:Session] Check LSP, embeddings, index freshness. Use before advanced tools.",
            json!({"type":"object","properties":{"file_path":{"type":"string","description":"Optional file path to check language-specific capabilities"},"detail":{"type":"string","enum":["compact","full"],"description":"compact returns 12 core fields (~1K); full returns all 38 fields including CoreML runtime, SCIP counts, build_info (~5K). Default: full (backward-compatible)."}}}),
        ).with_output_schema(get_capabilities_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "get_tool_metrics",
            "[CodeLens:Session] Per-tool call counts, latency, errors. Use for self-diagnosis.",
            json!({"type":"object","properties":{"session_id":{"type":"string","description":"Optional logical session id. When present, return only that session's metrics."}}}),
        ).with_output_schema(tool_metrics_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "audit_builder_session",
            "[CodeLens:Session] Audit a builder/refactor session for preflight, diagnostics, and coordination discipline.",
            json!({"type":"object","properties":{"session_id":{"type":"string","description":"Optional logical session id. Defaults to the active _session_id."},"detail":{"type":"string","enum":["compact","full"],"description":"compact returns the ordered audit checks only; full also includes session metrics and coordination snapshot."}}}),
        ).with_output_schema(builder_session_audit_output_schema()).with_annotations(ro_a.clone()).with_max_response_tokens(4096),
        Tool::new(
            "audit_planner_session",
            "[CodeLens:Session] Audit a planner/reviewer session for bootstrap, workflow-first routing, and read-side evidence discipline.",
            json!({"type":"object","properties":{"session_id":{"type":"string","description":"Optional logical session id. Defaults to the active _session_id."},"detail":{"type":"string","enum":["compact","full"],"description":"compact returns the ordered audit checks only; full also includes session metrics."}}}),
        ).with_output_schema(planner_session_audit_output_schema()).with_annotations(ro_a.clone()).with_max_response_tokens(4096),
        Tool::new(
            "export_session_markdown",
            "[CodeLens:Session] Export session telemetry as markdown report.",
            json!({"type":"object","properties":{"name":{"type":"string","description":"Session name for the report header"},"session_id":{"type":"string","description":"Optional logical session id. When present, the markdown includes the role-appropriate builder or planner audit summary."}}}),
        ).with_output_schema(session_markdown_output_schema()).with_annotations(ro_p.clone()).with_max_response_tokens(4096),
        Tool::new(
            "audit_log_query",
            "[CodeLens:Admin] Query the durable mutation audit log (`<project>/.codelens/audit/audit_log.sqlite`). Filter by transaction_id and/or since_ms; default limit 100 rows. Requires Admin role.",
            json!({"type":"object","properties":{"transaction_id":{"type":"string","description":"Stable id from a mutation response (payload.data.transaction_id). Returns the rows for that one call."},"since_ms":{"type":"integer","description":"Earliest timestamp_ms (epoch millis) to include."},"limit":{"type":"integer","description":"Max rows (default 100, capped at 1000)."}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "summarize_file",
            "[CodeLens:Session] Get AI-generated summary of a file's purpose and structure.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string","description":"File path to summarize"}}}),
        ).with_annotations(ro_w.clone()),
    ]
}

pub fn symbol_tools(
    mut_w: &ToolAnnotations,
    ro_a: &ToolAnnotations,
    ro_p: &ToolAnnotations,
) -> Vec<Tool> {
    vec![
        Tool::new(
            "get_symbols_overview",
            "[CodeLens:Symbol] List all symbols in a file — structural map. Use first to understand a file.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string"},"depth":{"type":"integer"}}}),
        ).with_output_schema(symbol_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "find_symbol",
            "[CodeLens:Symbol] Find function/class by exact name. Returns signature + body.",
            json!({"type":"object","properties":{"name":{"type":"string","description":"Symbol name to search for"},"symbol_id":{"type":"string","description":"Stable symbol ID (file#kind:name_path). Overrides name."},"file_path":{"type":"string"},"include_body":{"type":"boolean"},"exact_match":{"type":"boolean"},"max_matches":{"type":"integer"}}}),
        ).with_output_schema(symbol_output_schema()).with_annotations(ro_p.clone()),
        Tool::new(
            "get_ranked_context",
            "[CodeLens:Symbol] Smart context retrieval — best symbols for a query within token budget. For natural-language queries, set expand_query=false to skip n-gram expansion; for partial-identifier search use the default.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string"},"path":{"type":"string"},"max_tokens":{"type":"integer","description":"Token budget for the retrieval payload. Defaults to max(active surface budget, 16384) — raised in v1.10.1 from the surface budget alone to avoid Stage 5 truncation on hybrid retrieval."},"include_body":{"type":"boolean"},"depth":{"type":"integer"},"disable_semantic":{"type":"boolean","description":"Disable semantic/hybrid ranking and use structural signals only"},"expand_query":{"type":"boolean","description":"When true (default), expand the query with snake_case / camelCase / cartesian-token derivatives. Set to false for natural-language queries that don't benefit from expansion."}}}),
        ).with_output_schema(ranked_context_output_schema()).with_annotations(ro_a.clone()).with_max_response_tokens(32768),
        Tool::new(
            "bm25_symbol_search",
            "[CodeLens:Symbol] Sparse BM25-F symbol retrieval — best for identifiers, signatures, path tokens, and short lexical phrases.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string"},"max_results":{"type":"integer","description":"Maximum number of results to return (default 10)"},"include_tests":{"type":"boolean","description":"Include test symbols in the candidate pool"},"include_generated":{"type":"boolean","description":"Include generated symbols in the candidate pool"}}}),
        ).with_output_schema(bm25_symbol_search_output_schema()).with_annotations(ro_a.clone()),
        Tool::new(
            "search_symbols_fuzzy",
            "[CodeLens:Symbol] Fuzzy symbol search — tolerates typos and partial names.",
            json!({"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Symbol name to search for"},"max_results":{"type":"integer","description":"Maximum number of results to return (default 30)"},"fuzzy_threshold":{"type":"number","description":"Minimum jaro_winkler similarity 0.0-1.0 for fuzzy matches (default 0.6)"},"disable_semantic":{"type":"boolean","description":"Disable semantic score blending and use lexical search only"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "get_complexity",
            "[CodeLens:Analysis] Cyclomatic complexity for functions. Use to find code needing refactoring.",
            json!({"type":"object","required":["path"],"properties":{"path":{"type":"string"},"symbol_name":{"type":"string"}}}),
        ).with_annotations(ro_a.clone()),
        Tool::new(
            "refresh_symbol_index",
            "[CodeLens:Symbol] Rebuild the symbol database. Use if index is stale.",
            json!({"type":"object","properties":{}}),
        ).with_annotations(mut_w.clone()),
        Tool::new(
            "get_project_structure",
            "[CodeLens:Symbol] Directory-level overview — file counts and symbol density per directory.",
            json!({"type":"object","properties":{}}),
        ).with_output_schema(get_project_structure_output_schema()).with_annotations(ro_p.clone()),
    ]
}

pub fn workflow_first_tools(ro_w: &ToolAnnotations) -> Vec<Tool> {
    vec![
        Tool::new(
            "explore_codebase",
            "[CodeLens:Workflow] Problem-first entrypoint for codebase exploration. Use query for targeted context, or call without arguments for onboarding.",
            json!({"type":"object","properties":{"query":{"type":"string"},"path":{"type":"string"},"max_tokens":{"type":"integer"},"include_body":{"type":"boolean"},"depth":{"type":"integer"},"disable_semantic":{"type":"boolean"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(16384),
        Tool::new(
            "trace_request_path",
            "[CodeLens:Workflow] Trace a request or execution path from a function, symbol, or entrypoint.",
            json!({"type":"object","properties":{"function_name":{"type":"string"},"symbol":{"type":"string"},"entrypoint":{"type":"string"},"max_depth":{"type":"integer"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
        Tool::new(
            "review_architecture",
            "[CodeLens:Workflow] Review project or module architecture, boundaries, coupling, and optionally render a diagram.",
            json!({"type":"object","properties":{"path":{"type":"string"},"include_diagram":{"type":"boolean"},"max_nodes":{"type":"integer"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
        Tool::new(
            "plan_safe_refactor",
            "[CodeLens:Workflow] Preview a safe refactor plan. Uses rename safety when file_path+symbol are given; otherwise falls back to broader refactor safety analysis.",
            json!({"type":"object","properties":{"task":{"type":"string"},"symbol":{"type":"string"},"path":{"type":"string"},"file_path":{"type":"string"},"new_name":{"type":"string"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
        Tool::new(
            "cleanup_duplicate_logic",
            "[CodeLens:Workflow] Surface duplicate or removable logic before cleanup. Uses semantic duplicate search when available, otherwise bounded dead-code evidence.",
            json!({"type":"object","properties":{"threshold":{"type":"number"},"max_pairs":{"type":"integer"},"scope":{"type":"string"},"max_results":{"type":"integer"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
        Tool::new(
            "review_changes",
            "[CodeLens:Workflow] Pre-merge review: diff-aware references or impact analysis for changed files.",
            json!({"type":"object","properties":{"changed_files":{"type":"array","items":{"type":"string"},"description":"File paths that changed"},"task":{"type":"string","description":"Review focus description"},"path":{"type":"string","description":"Scope path"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
        Tool::new(
            "diagnose_issues",
            "[CodeLens:Workflow] Diagnostics: file-level issues or unresolved reference check.",
            json!({"type":"object","properties":{"file_path":{"type":"string","description":"File to diagnose"},"path":{"type":"string","description":"Directory scope"},"symbol":{"type":"string","description":"Symbol to check references for"}}}),
        ).with_output_schema(workflow_alias_output_schema()).with_annotations(ro_w.clone()).with_max_response_tokens(3072),
    ]
}
