"""
Skill Forge — a Gradio app + MCP server for authoring Agent Skills.

Tabs: validate a SKILL.md, score its `description` for trigger reliability, and
scaffold a new skill. The same three functions are exposed as MCP tools
(`skill_validate`, `skill_lint_description`, `skill_scaffold`) so an agent can
call them while it writes skills for itself.

Run locally:  python app.py   (UI on :7860, MCP at /gradio_api/mcp/sse)
"""

import gradio as gr

from skillforge import validate_skill, lint_description, scaffold_skill, package_skill

EXAMPLE = """---
name: changelog-writer
description: Drafts a release changelog from merged PRs. Use when the user asks to \
"write the changelog", "summarize what shipped", or prep release notes for a tag.
---

# Changelog Writer

## When to use this skill
- The user is cutting a release and wants notes grouped by type.

## Instructions
1. Collect merged PRs since the last tag.
2. Group as Features / Fixes / Internal and write one line each.
"""


def skill_validate(skill_md: str) -> str:
    """Validate a SKILL.md against the Agent Skill format.

    Args:
        skill_md: Full text of a SKILL.md file (YAML frontmatter + Markdown body).

    Returns:
        A Markdown report listing errors, warnings, and info.
    """
    return validate_skill(skill_md).as_markdown()


def skill_lint_description(description: str) -> str:
    """Score a skill `description` for how reliably an agent will trigger on it.

    Args:
        description: The frontmatter `description` string on its own.

    Returns:
        A Markdown report ending with 'Trigger score: N/100'.
    """
    return lint_description(description).as_markdown()


def skill_scaffold(name: str, description: str, when_to_use: str = "") -> str:
    """Generate a ready-to-edit SKILL.md for a new Agent Skill.

    Args:
        name: kebab-case skill name, e.g. 'pdf-form-filler'.
        description: What the skill does and when to use it.
        when_to_use: Optional extra trigger examples.

    Returns:
        The full text of a SKILL.md file.
    """
    return scaffold_skill(name, description, when_to_use)


def _package(skill_md: str):
    data = package_skill(skill_md)
    path = "skill.zip"
    with open(path, "wb") as f:
        f.write(data)
    return path


with gr.Blocks(title="Skill Forge") as demo:
    gr.Markdown(
        "# 🛠️ Skill Forge\n"
        "Validate, lint, and scaffold **Agent Skills** (`SKILL.md`). "
        "Also an MCP server — point your agent at `/gradio_api/mcp/sse`."
    )

    with gr.Tab("Validate"):
        md_in = gr.Code(value=EXAMPLE, language="yaml", label="SKILL.md", lines=20)
        with gr.Row():
            v_btn = gr.Button("Validate", variant="primary")
            z_btn = gr.Button("Package as .zip")
        v_out = gr.Markdown()
        z_out = gr.File(label="Packaged skill", visible=True)
        v_btn.click(skill_validate, md_in, v_out, api_name="skill_validate")
        z_btn.click(_package, md_in, z_out)

    with gr.Tab("Lint description"):
        d_in = gr.Textbox(
            label="Frontmatter `description`", lines=4,
            value=('Drafts a release changelog from merged PRs. Use when the user '
                   'asks to "write the changelog" or prep release notes.'))
        d_btn = gr.Button("Score it", variant="primary")
        d_out = gr.Markdown()
        d_btn.click(skill_lint_description, d_in, d_out,
                    api_name="skill_lint_description")

    with gr.Tab("Scaffold"):
        s_name = gr.Textbox(label="name (kebab-case)", value="terraform-plan-reviewer")
        s_desc = gr.Textbox(label="description", lines=3,
                            value="Reviews a Terraform plan and summarizes drift and risk.")
        s_when = gr.Textbox(label="when to use (optional)",
                            value='the user runs "terraform plan" and wants a risk summary')
        s_btn = gr.Button("Generate SKILL.md", variant="primary")
        s_out = gr.Code(language="yaml", label="SKILL.md")
        s_btn.click(skill_scaffold, [s_name, s_desc, s_when], s_out,
                    api_name="skill_scaffold")

    gr.Markdown(
        "---\nRules checked: frontmatter parses as YAML · `name` kebab-case ≤64 · "
        "`description` present ≤1024 with a trigger cue · non-empty structured body · "
        "relative bundled-file links. MIT licensed."
    )

if __name__ == "__main__":
    demo.launch(mcp_server=True)
