#!/usr/bin/env python3 """ Add BLOCKED dependency tree reference to all sprint files. """ import os import re from pathlib import Path DOCS_DIR = Path(__file__).parent.parent / "docs" IMPLPLAN_DIR = DOCS_DIR / "implplan" ROUTER_DIR = DOCS_DIR / "router" # Reference lines with correct relative paths REFERENCE_LINE_IMPLPLAN = "\n> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.\n" REFERENCE_LINE_ROUTER = "\n> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [../implplan/BLOCKED_DEPENDENCY_TREE.md](../implplan/BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.\n" def add_reference_to_sprint(filepath: Path, reference_line: str) -> bool: """Add BLOCKED reference to a sprint file. Returns True if modified.""" content = filepath.read_text(encoding="utf-8") # Skip if reference already exists if "BLOCKED_DEPENDENCY_TREE.md" in content: return False # Find the best insertion point # Priority 1: After "## Documentation Prerequisites" section (before next ##) # Priority 2: After "## Dependencies & Concurrency" section # Priority 3: After the first line (title) lines = content.split("\n") insert_index = None # Look for Documentation Prerequisites section for i, line in enumerate(lines): if line.strip().startswith("## Documentation Prerequisites"): # Find the next section header or end of list for j in range(i + 1, len(lines)): if lines[j].strip().startswith("## "): insert_index = j break elif lines[j].strip() == "" and j + 1 < len(lines) and lines[j + 1].strip().startswith("## "): insert_index = j + 1 break if insert_index is None: # No next section found, insert after last non-empty line in prerequisites for j in range(i + 1, len(lines)): if lines[j].strip().startswith("## "): insert_index = j break break # Fallback: after Dependencies & Concurrency if insert_index is None: for i, line in enumerate(lines): if line.strip().startswith("## Dependencies"): for j in range(i + 1, len(lines)): if lines[j].strip().startswith("## "): insert_index = j break break # Fallback: after first heading if insert_index is None: for i, line in enumerate(lines): if line.strip().startswith("# "): insert_index = i + 2 # After title and blank line break # Final fallback: beginning of file if insert_index is None: insert_index = 1 # Insert the reference new_lines = lines[:insert_index] + [reference_line.strip(), ""] + lines[insert_index:] new_content = "\n".join(new_lines) filepath.write_text(new_content, encoding="utf-8") return True def main(): modified = 0 skipped = 0 # Process implplan directory print("Processing docs/implplan...") for filepath in sorted(IMPLPLAN_DIR.glob("SPRINT_*.md")): if add_reference_to_sprint(filepath, REFERENCE_LINE_IMPLPLAN): print(f"Modified: {filepath.name}") modified += 1 else: print(f"Skipped: {filepath.name}") skipped += 1 # Process router directory print("\nProcessing docs/router...") for filepath in sorted(ROUTER_DIR.glob("SPRINT_*.md")): if add_reference_to_sprint(filepath, REFERENCE_LINE_ROUTER): print(f"Modified: {filepath.name}") modified += 1 else: print(f"Skipped: {filepath.name}") skipped += 1 print(f"\nSummary: {modified} files modified, {skipped} files skipped") if __name__ == "__main__": main()