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
- Import - Place text decklists in
collection/ - Hydrate - Run
hydrate.pyto fetch Scryfall data →collection_hydrated/ - Define - Create deck JSON files in
decks/ - Analyze - Run
analyze_decks.pyto find upgrade options - Report - Use
deck_report.pyfor 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
argparsewith 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_identitytype_line,oracle_text,power,toughness,loyaltyscryfall_uri,count
Extension Guide
Adding a New Deck
- Create
decks/<name>.jsonwith required fields - Run
python scripts/update_docs.pyto regenerate documentation
Adding a New Script
- Create
scripts/<name>.pywith argparse CLI - Follow existing patterns:
load_collection(), argparse with --help - Update README template with usage example
- Run
python scripts/update_docs.py
Modifying Deck Analysis
scripts/analyze_decks.py: Core logic for finding upgrades- Color identity matching uses
color_identityfield 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.mdexists with deck table and usage docsAGENTS.mdexists with build commands and project structurescripts/update_docs.pygenerates both files from templates- Pre-commit hook runs and stages updated docs
- Templates are editable without touching generated files