Files
mtg-builder/docs/plans/2026-02-19-auto-docs.md
2026-02-20 00:22:14 +01:00

11 KiB

Auto-updating Documentation Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Create README.md and AGENTS.md that auto-update via git pre-commit hook when files change.

Architecture: Template files with placeholders + Python generator script that reads deck/collection data + pre-commit hook that runs on every commit.

Tech Stack: Python 3 stdlib (json, pathlib, argparse)


Task 1: Create Template Files

Files:

  • Create: docs/templates/README.template.md
  • Create: docs/templates/AGENTS.template.md

Step 1: Create docs/templates directory

mkdir -p docs/templates

Step 2: Create README template

Create docs/templates/README.template.md:

# MTG EDH Deck Manager

Command-line toolkit for managing Magic: The Gathering Commander (EDH) decks using the Scryfall API.

## Installation

```bash
git clone <repo-url>
cd Decks

No dependencies required - pure Python 3 standard library.

Usage

Hydrate a Collection

Fetch card data from Scryfall for a decklist:

python hydrate.py hydrate collection/decklist.txt -o collection_hydrated/ -c card_cache.json

Create a New Deck

python hydrate.py new my_deck

Analyze Decks

Find upgrade options from your collection:

python scripts/analyze_decks.py --collection collection_hydrated/deck.json --deck-dir decks/

Find Synergies

Search for cards by keywords, colors, and type:

# Find landfall cards in Simic colors
python scripts/find_synergies.py --collection collection_hydrated/deck.json --colors U G --keywords landfall

# Find Bird creatures in Bant colors
python scripts/find_synergies.py --collection collection_hydrated/deck.json --colors U G W --creature-type Bird

# Find instants with CMC 2 or less
python scripts/find_synergies.py --collection collection_hydrated/deck.json --type instant --cmc-max 2

Generate Reports

python scripts/deck_report.py --collection collection_hydrated/deck.json --decks-dir decks/ --output report.md

Decks

{{DECK_TABLE}}

Workflow

  1. Import - Place text decklists in collection/
  2. Hydrate - Run hydrate.py to fetch Scryfall data → collection_hydrated/
  3. Define - Create deck JSON files in decks/
  4. Analyze - Run analyze_decks.py to find upgrade options
  5. Report - Use deck_report.py for markdown summaries

Collection Stats

{{COLLECTION_STATS}}


This file is auto-generated. Edit docs/templates/README.template.md instead.


**Step 3: Create AGENTS template**

Create `docs/templates/AGENTS.template.md`:

```markdown
# AGENTS.md

Guide for AI assistants working on this codebase.

## Build/Verify Commands

This project has no external dependencies or test framework.

```bash
# No lint/typecheck commands currently
# Verify scripts work by running them:
python hydrate.py --help
python scripts/analyze_decks.py --help

Code Style

  • Language: Python 3 (stdlib only, no external packages)
  • Formatting: 4-space indent, max line length ~100
  • Imports: Standard library only (argparse, json, pathlib, urllib, re, sys, os, time)
  • CLI: Use argparse with subparsers for multi-command tools
  • Error handling: Print to stderr, use sys.exit(1) for failures
  • Docstrings: Triple-quoted at module and function level with usage examples
  • Type hints: Optional but encouraged for complex functions

Project Structure

├── hydrate.py              # Main CLI - fetches card data from Scryfall
├── card_cache.json         # Local cache of Scryfall card data
├── deck_analysis.json      # Analysis output
├── collection/             # Raw decklist text files
├── collection_hydrated/    # Enriched card data by type
│   ├── deck.json           # All cards combined
│   ├── commander.json
│   ├── creatures.json
│   ├── instants.json
│   ├── sorceries.json
│   ├── artifacts.json
│   ├── enchantments.json
│   ├── lands.json
│   └── planeswalkers.json
├── decks/                  # Deck definitions (JSON)
│   └── <deck_name>.json    # name, commander, colors, archetype, cards
├── scripts/
│   ├── analyze_decks.py    # Find upgrade options for decks
│   ├── find_synergies.py   # Search for synergistic cards
│   ├── parse_deck.py       # Parse text decklists to JSON
│   └── deck_report.py      # Generate markdown reports
└── docs/
    └── templates/          # Documentation templates

Data Formats

Deck JSON (decks/*.json)

{
  "name": "Deck Name",
  "commander": "Commander Name",
  "colors": ["U", "G", "W"],
  "archetype": "Theme Description",
  "cards": {
    "Card Name": count,
    ...
  }
}

Card Data (collection_hydrated/*.json)

Array of card objects with Scryfall fields:

  • name, mana_cost, cmc, colors, color_identity
  • type_line, oracle_text, power, toughness, loyalty
  • scryfall_uri, count

Extension Guide

Adding a New Deck

  1. Create decks/<name>.json with required fields
  2. Run python scripts/update_docs.py to regenerate documentation

Adding a New Script

  1. Create scripts/<name>.py with argparse CLI
  2. Follow existing patterns: load_collection(), argparse with --help
  3. Update README template with usage example
  4. Run python scripts/update_docs.py

Modifying Deck Analysis

  • scripts/analyze_decks.py: Core logic for finding upgrades
  • Color identity matching uses color_identity field from Scryfall
  • Cards are categorized by type_line

Current Decks

{{DECK_TABLE}}


**Step 4: Commit templates**

```bash
git add docs/templates/
git commit -m "Add documentation templates"

Task 2: Create update_docs.py Script

Files:

  • Create: scripts/update_docs.py

Step 1: Create the generator script

Create scripts/update_docs.py:

#!/usr/bin/env python3
"""
Generate README.md and AGENTS.md from templates.
Usage:
    python scripts/update_docs.py
"""

import json
import os
from pathlib import Path


SCRIPT_DIR = Path(__file__).parent
PROJECT_ROOT = SCRIPT_DIR.parent
TEMPLATES_DIR = PROJECT_ROOT / "docs" / "templates"
DECKS_DIR = PROJECT_ROOT / "decks"
COLLECTION_DIR = PROJECT_ROOT / "collection_hydrated"


def load_decks() -> list[dict]:
    """Load all deck JSON files."""
    decks = []
    if DECKS_DIR.exists():
        for path in sorted(DECKS_DIR.glob("*.json")):
            with open(path, "r", encoding="utf-8") as f:
                data = json.load(f)
                data["filename"] = path.stem
                decks.append(data)
    return decks


def load_collection_stats() -> dict:
    """Get collection statistics."""
    stats = {
        "total_cards": 0,
        "unique_cards": 0,
        "by_type": {}
    }
    deck_file = COLLECTION_DIR / "deck.json"
    if deck_file.exists():
        with open(deck_file, "r", encoding="utf-8") as f:
            cards = json.load(f)
            stats["unique_cards"] = len(cards)
            stats["total_cards"] = sum(c.get("count", 1) for c in cards)
    for category in ["creatures", "instants", "sorceries", "artifacts", "enchantments", "lands", "planeswalkers"]:
        cat_file = COLLECTION_DIR / f"{category}.json"
        if cat_file.exists():
            with open(cat_file, "r", encoding="utf-8") as f:
                cards = json.load(f)
                stats["by_type"][category] = len(cards)
    return stats


def generate_deck_table(decks: list[dict]) -> str:
    """Generate markdown table of decks."""
    if not decks:
        return "*No decks defined yet.*"
    lines = ["| Deck | Colors | Commander | Archetype |", "|------|--------|-----------|-----------|"]
    color_map = {"W": "White", "U": "Blue", "B": "Black", "R": "Red", "G": "Green"}
    for deck in decks:
        name = deck.get("name", deck.get("filename", "Unknown"))
        colors = deck.get("colors", [])
        color_str = "".join(colors) if colors else "Colorless"
        commander = deck.get("commander", "Unknown")
        archetype = deck.get("archetype", "-")
        lines.append(f"| {name} | {color_str} | {commander} | {archetype} |")
    return "\n".join(lines)


def generate_collection_stats(stats: dict) -> str:
    """Generate collection statistics section."""
    lines = [f"- **Total cards:** {stats['total_cards']}", f"- **Unique cards:** {stats['unique_cards']}"]
    if stats["by_type"]:
        lines.append("- **By type:**")
        for category, count in sorted(stats["by_type"].items()):
            lines.append(f"  - {category.title()}: {count}")
    return "\n".join(lines)


def generate_docs() -> None:
    """Generate README.md and AGENTS.md from templates."""
    decks = load_decks()
    stats = load_collection_stats()
    deck_table = generate_deck_table(decks)
    collection_stats = generate_collection_stats(stats)
    
    for template_name in ["README.template.md", "AGENTS.template.md"]:
        template_path = TEMPLATES_DIR / template_name
        if not template_path.exists():
            print(f"Template not found: {template_path}")
            continue
        with open(template_path, "r", encoding="utf-8") as f:
            content = f.read()
        content = content.replace("{{DECK_TABLE}}", deck_table)
        content = content.replace("{{COLLECTION_STATS}}", collection_stats)
        output_name = template_name.replace(".template", "")
        output_path = PROJECT_ROOT / output_name
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(content)
        print(f"Generated: {output_path}")


if __name__ == "__main__":
    generate_docs()

Step 2: Test the script

python scripts/update_docs.py

Expected: Creates README.md and AGENTS.md in project root

Step 3: Verify generated files

ls -la README.md AGENTS.md
head -20 README.md

Step 4: Commit the script

git add scripts/update_docs.py README.md AGENTS.md
git commit -m "Add update_docs.py and generate initial documentation"

Task 3: Create Pre-commit Hook

Files:

  • Create: .git/hooks/pre-commit

Step 1: Create the hook

cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Auto-update documentation on commit

python scripts/update_docs.py

if [ -f README.md ]; then
    git add README.md
fi

if [ -f AGENTS.md ]; then
    git add AGENTS.md
fi
EOF
chmod +x .git/hooks/pre-commit

Step 2: Test the hook

# Make a small change to trigger the hook
echo "# test" >> hydrate.py
git add hydrate.py
git commit -m "Test pre-commit hook"

Expected: Hook runs, updates docs if needed, includes them in commit

Step 3: Verify hook worked

git log -1 --stat

Expected: README.md and AGENTS.md may appear in commit if changed


Task 4: Cleanup and Final Commit

Step 1: Remove test change if added

# If you added the test line, revert it:
git checkout hydrate.py

Step 2: Make a clean commit documenting the hook

git add .git/hooks/pre-commit
git commit -m "Add pre-commit hook for auto-updating documentation"

Success Criteria

  • README.md exists with deck table and usage docs
  • AGENTS.md exists with build commands and project structure
  • scripts/update_docs.py generates both files from templates
  • Pre-commit hook runs and stages updated docs
  • Templates are editable without touching generated files