"""MCP Tool schemas for all active-claude-github tools.

Extracted from `build_server.list_tools` in Phase 2b so the dispatch
router (build.py) stays focused on wiring rather than schema
definitions.
"""
from __future__ import annotations

from mcp.types import Tool


def all_tool_schemas() -> list[Tool]:
    return [
        Tool(
            name="open_session",
            description=(
                "Start a new Claude session. Posts session-opened comment "
                "to Session Lock Discussion. Returns all IDs needed for the "
                "session. Call once at session start."
            ),
            inputSchema={"type": "object", "properties": {}, "required": []},
        ),
        Tool(
            name="recover_context",
            description=(
                "Bundled read for §Context Recovery (#58). Returns the "
                "current SessionState (from the cached open_session if "
                "available, else opens one), the current Project "
                "Discussion TOC body, open Issues, recent Discussions, "
                "and open Milestones with completion %. One tool call "
                "replaces the five sequential reads in the skill's "
                "Context Recovery section."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "days": {
                        "type": "integer",
                        "description": "Recency window for Discussions in days",
                        "default": 7,
                        "minimum": 1,
                    },
                },
                "required": [],
            },
        ),
        Tool(
            name="scaffold_project",
            description=(
                "Scaffold a new managed project end-to-end: create "
                "<org>/<name> (public) and <org>/<name>-dev (private), "
                "seed the standard label set, enable Discussions on the "
                "dev repo, create a ProjectV2 board (linked to both "
                "repos) with the canonical Status field, and — once "
                "the five Discussion categories are present — seed "
                "the Project + Session-Lock Discussions and write "
                ".claude/github-config.json. Idempotent: inspects live "
                "state and no-ops any step already satisfied, so the "
                "tool can be re-run after the one manual pause for "
                "Discussion category creation (GitHub exposes no API "
                "for it). — #81 (v2 full bootstrap; v1 under #44)."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "org": {
                        "type": "string",
                        "description": "Existing GitHub org login.",
                    },
                    "project_name": {
                        "type": "string",
                        "description": "Base name; public repo is <org>/<name>, dev repo is <org>/<name>-dev.",
                    },
                    "description": {
                        "type": "string",
                        "description": "Short description used for both repos.",
                        "default": "",
                    },
                },
                "required": ["org", "project_name"],
            },
        ),
        Tool(
            name="classify_and_create",
            description=(
                "Classify a turn and, if the classifier's confidence "
                "meets the threshold, auto-create the suggested thread "
                "(Discussion or Issue) and optionally post the turn "
                "onto it — one roundtrip instead of classify→inspect→"
                "create (#61). Below threshold, returns the "
                "classification only; caller decides."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {"type": "string"},
                    "auto_create_threshold": {
                        "type": "string",
                        "enum": ["low", "medium", "high"],
                        "default": "high",
                        "description": "Auto-create when classifier confidence >= this level.",
                    },
                    "also_post_turn": {
                        "type": "boolean",
                        "default": True,
                        "description": "If auto-creating, also post `text` as user turn on the new thread.",
                    },
                    "opening_body": {
                        "type": "string",
                        "default": "",
                        "description": "Optional body for the new thread. Defaults to `text`.",
                    },
                },
                "required": ["text"],
            },
        ),
        Tool(
            name="check_skill_version",
            description=(
                "Parse local .claude/skills/active-claude-github.md "
                "and the upstream copy at config.repos.public/main/"
                "active-claude-github.md; report installed vs latest "
                "version and any changelog entries between them (#60)."
            ),
            inputSchema={"type": "object", "properties": {}, "required": []},
        ),
        Tool(
            name="replay_pending",
            description=(
                "Replay every buffered operation in .claude/pending-"
                "posts.md. Clears the buffer up-front; individual "
                "failures re-buffer via the normal error path, so "
                "the resulting buffer contains only still-unresolved "
                "entries (#57)."
            ),
            inputSchema={"type": "object", "properties": {}, "required": []},
        ),
        Tool(
            name="close_issue_with_comment",
            description=(
                "Post a comment on an Issue and then close it with a "
                "state reason (#59). Comment posts first so it appears "
                "on the Issue timeline ahead of the close event. "
                "Identify the Issue with either `issue_id` or `number`."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "issue_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Issue",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped Issue number; alternative to issue_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "comment": {
                        "type": "string",
                        "description": "Body of the closing comment",
                    },
                    "state_reason": {
                        "type": "string",
                        "enum": ["completed", "not_planned"],
                        "default": "completed",
                        "description": "Close reason passed to GitHub's stateReason field",
                    },
                },
                "required": ["comment"],
            },
        ),
        Tool(
            name="get_thread_comments",
            description=(
                "Return comments on a Discussion or Issue with author "
                "info, ordered oldest → newest (#57)."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "thread_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Discussion or Issue",
                    },
                    "thread_type": {
                        "type": "string",
                        "enum": ["discussion", "issue"],
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Max comments to return (1-100)",
                        "default": 20,
                        "minimum": 1,
                        "maximum": 100,
                    },
                },
                "required": ["thread_id", "thread_type"],
            },
        ),
        Tool(
            name="close_session",
            description=(
                "Close the current session. Posts session-closed "
                "comment to the Session Lock Discussion. If `summary` "
                "is omitted or empty, the server composes one from "
                "the session's activity log (turns, threads created, "
                "forks, decided discussions, caveats) — #62."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "summary": {
                        "type": "string",
                        "description": "Optional summary. Omit or pass empty string to use the server-composed default.",
                    },
                    "skill_update_candidates": {
                        "type": "integer",
                        "description": "Number of skill update candidates noted",
                        "default": 0,
                    },
                },
                "required": [],
            },
        ),
        Tool(
            name="post_turn",
            description=(
                "Post a single conversation turn (Claude or user) to a "
                "GitHub Discussion or Issue thread. Identify the thread "
                "with EITHER `thread_id` (node ID) OR `number` (repo-"
                "scoped, server resolves against the configured dev "
                "repo unless owner/repo are supplied)."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "thread_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Discussion or Issue",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped number; alternative to thread_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "thread_type": {
                        "type": "string",
                        "enum": ["discussion", "issue"],
                    },
                    "speaker": {
                        "type": "string",
                        "enum": ["claude", "user"],
                    },
                    "body": {
                        "type": "string",
                        "description": "Clean text of the turn (no tool call noise)",
                    },
                },
                "required": ["thread_type", "speaker", "body"],
            },
        ),
        Tool(
            name="create_thread",
            description="Create a new Discussion or Issue thread.",
            inputSchema={
                "type": "object",
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": ["discussion", "issue"],
                    },
                    "category_or_label": {
                        "type": "string",
                        "description": (
                            "Discussion category name ('Architecture', 'UX / UI', "
                            "'Ideas') or Issue label ('bug', 'rfc', 'feature', "
                            "'refactor', 'chore')"
                        ),
                    },
                    "title": {"type": "string"},
                    "opening_body": {
                        "type": "string",
                        "description": "Opening post content",
                    },
                    "discussion_origin_id": {
                        "type": "string",
                        "description": "Node ID of the Discussion this Issue originated from (Issues only)",
                        "default": "",
                    },
                },
                "required": ["type", "category_or_label", "title", "opening_body"],
            },
        ),
        Tool(
            name="classify_turn",
            description=(
                "Classify a user message to determine if it belongs in a "
                "Discussion or Issue, and suggest a title and category."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "The user message to classify",
                    }
                },
                "required": ["text"],
            },
        ),
        Tool(
            name="detect_theme_change",
            description=(
                "Analyze whether a new message represents a theme change "
                "from the existing Discussion thread."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "thread_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Discussion",
                    },
                    "new_turn_text": {
                        "type": "string",
                        "description": "The new message to evaluate",
                    },
                },
                "required": ["thread_id", "new_turn_text"],
            },
        ),
        Tool(
            name="fork_discussion",
            description=(
                "Fork a Discussion at a detected theme change point. "
                "Creates new Discussion, edits original opening post, "
                "posts inline fork comment. Atomic — reports partial "
                "failures if any step fails."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "original_id": {
                        "type": "string",
                        "description": "Node ID of the Discussion to fork from",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped Discussion number; alternative to original_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "fork_point_comment_id": {
                        "type": "string",
                        "description": "Node ID of the comment where theme changed",
                    },
                    "new_title": {"type": "string"},
                    "category_name": {
                        "type": "string",
                        "enum": ["Architecture", "UX / UI", "Ideas"],
                    },
                    "summary": {
                        "type": "string",
                        "description": "Summary of forked content for new Discussion opening post",
                    },
                    "original_discussion_url": {
                        "type": "string",
                        "description": "Web URL of the original Discussion",
                    },
                    "fork_point_url": {
                        "type": "string",
                        "description": "Web URL of the fork-point comment",
                    },
                },
                "required": [
                    "fork_point_comment_id",
                    "new_title",
                    "category_name",
                    "summary",
                    "original_discussion_url",
                    "fork_point_url",
                ],
            },
        ),
        Tool(
            name="create_issue",
            description=(
                "Create a GitHub Issue, add it to the project board in "
                "Backlog, and cross-link to origin Discussion if provided. "
                "Pass `labels` as a list covering both the required type "
                "label (bug/rfc/feature/refactor/chore) and any area "
                "labels (area:mcp, area:skill, etc.). `label` is a "
                "deprecated single-value alias kept for backward compat."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "title": {"type": "string"},
                    "body": {
                        "type": "string",
                        "description": "Pre-formatted Issue body following template",
                    },
                    "labels": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": (
                            "Label names. Must include exactly one type "
                            "label from {bug, rfc, feature, refactor, "
                            "chore}. Area labels (area:*) recommended."
                        ),
                    },
                    "label": {
                        "type": "string",
                        "enum": ["bug", "rfc", "feature", "refactor", "chore"],
                        "description": "Deprecated: use `labels` instead.",
                    },
                    "discussion_origin_id": {
                        "type": "string",
                        "description": "Node ID of origin Discussion (empty if none)",
                        "default": "",
                    },
                },
                "required": ["title", "body"],
            },
        ),
        Tool(
            name="update_issue_toc",
            description="Update the subtasks table in an Issue's opening post.",
            inputSchema={
                "type": "object",
                "properties": {
                    "issue_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Issue",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped Issue number; alternative to issue_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "new_body": {
                        "type": "string",
                        "description": "Complete new body for the Issue opening post",
                    },
                    "force": {
                        "type": "boolean",
                        "description": "Skip the size-guardrail check. Set true only for legitimate large shrinks.",
                        "default": False,
                    },
                },
                "required": ["new_body"],
            },
        ),
        Tool(
            name="move_project_item",
            description="Move an Issue to a different project board column.",
            inputSchema={
                "type": "object",
                "properties": {
                    "issue_id": {
                        "type": "string",
                        "description": "GitHub node ID of the Issue",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped Issue number; alternative to issue_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "column_name": {
                        "type": "string",
                        "enum": ["Backlog", "In Progress", "In Review", "Done", "Parked"],
                    },
                },
                "required": ["column_name"],
            },
        ),
        Tool(
            name="update_project_toc",
            description=(
                "Update the Project Discussion opening post with the "
                "latest Discussions and Issues tables."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "new_body": {
                        "type": "string",
                        "description": "Complete new body for the Project Discussion",
                    },
                    "force": {
                        "type": "boolean",
                        "description": "Skip the size-guardrail check. Set true only for legitimate large shrinks.",
                        "default": False,
                    },
                },
                "required": ["new_body"],
            },
        ),
        Tool(
            name="generate_changelog",
            description=(
                "Regenerate CHANGELOG.md from the skill's ## Changelog "
                "section (#108). Preview by default; pass write=true "
                "to actually overwrite the file. release_project's "
                "auto-populate path uses the same generator, so this "
                "tool is only needed when the operator wants to refresh "
                "the file mid-cycle without running a release."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "write": {
                        "type": "boolean",
                        "default": False,
                        "description": "Overwrite CHANGELOG.md instead of just previewing.",
                    },
                },
                "required": [],
            },
        ),
        Tool(
            name="release_project",
            description=(
                "Orchestrate a release: validate (#107) → dev_tag → "
                "mirror_sync → mirror_tag → release_notes. Hard-gated on "
                "validate_release; no force override. Defaults to dry-run "
                "— call with dry_run=False after the dry-run output looks "
                "right. `stop_after` lets the operator cut just the dev "
                "tag (stop_after='dev_tag') and defer mirror sync. If "
                "validate fails only on version-line checks, the tool "
                "returns awaiting_version_bump_approval with proposed "
                "edits; re-call with approve_version_bump=true to apply "
                "them and continue. Auto-populates CHANGELOG.md if absent. "
                "(#106)"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "version": {
                        "type": "string",
                        "description": "Target release version, e.g. '1.3.0'.",
                    },
                    "dry_run": {
                        "type": "boolean",
                        "default": True,
                        "description": "Preview every step without mutating.",
                    },
                    "stop_after": {
                        "type": "string",
                        "enum": ["validate", "dev_tag", "mirror_sync", "release_notes"],
                        "default": "release_notes",
                        "description": "Last step to run.",
                    },
                    "approve_version_bump": {
                        "type": "boolean",
                        "default": False,
                        "description": "If validate fails only on version-line checks, apply the proposed bump, commit, push.",
                    },
                    "skip_bazel": {
                        "type": "boolean",
                        "default": False,
                        "description": "Downgrade the bazel test check from fail to warn (forwarded to validate_release).",
                    },
                },
                "required": ["version"],
            },
        ),
        Tool(
            name="validate_release",
            description=(
                "Pre-flight checker for a release target version (#107). "
                "Read-only. Repo-role-aware: applies the skill-repo or "
                "mcp-repo checklist based on files present in project_dir. "
                "Returns `ready: bool` plus per-check status so the operator "
                "(and `release_project`) can see exactly which check blocks. "
                "`skip_bazel=true` downgrades the `bazel test //...` check "
                "from fail to warn — use only for fast iteration; real "
                "releases must run with skip_bazel=false."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "version": {
                        "type": "string",
                        "description": "Target release version, e.g. '1.3.0'.",
                    },
                    "skip_bazel": {
                        "type": "boolean",
                        "description": "Downgrade the bazel test check from fail to warn.",
                        "default": False,
                    },
                },
                "required": ["version"],
            },
        ),
        Tool(
            name="mark_discussion_decided",
            description=(
                "Mark a Discussion as decided: mark answer comment if "
                "category supports it, update status in Project TOC."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "discussion_id": {
                        "type": "string",
                        "description": "Node ID of the Discussion",
                    },
                    "number": {
                        "type": "integer",
                        "description": "Repo-scoped Discussion number; alternative to discussion_id",
                    },
                    "owner": {
                        "type": "string",
                        "description": "Repo owner (default: project's dev-repo owner)",
                    },
                    "repo": {
                        "type": "string",
                        "description": "Repo name (default: project's dev repo)",
                    },
                    "decision_comment_id": {
                        "type": "string",
                        "description": "Node ID of the comment summarizing the decision",
                    },
                    "category_name": {
                        "type": "string",
                        "description": "Category name to check answerability",
                    },
                },
                "required": ["decision_comment_id", "category_name"],
            },
        ),
    ]
