ASCII Diagram Validator Validate and fix alignment issues in ASCII box-drawing diagrams commonly used in architecture documentation, README files, and code comments. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Overview ASCII diagrams using box-drawing characters (─│┌┐└┘├┤┬┴┼ and double-line variants ═║╔╗╚╝╠╣╦╩╬) require precise column alignment. This skill provides: 1. Validation script - Detects misaligned characters with fi…

); do\n if [ -f \"$file\" ]; then\n uv run skills/check_ascii_alignment.py \"$file\" --quiet\n if [ $? -eq 1 ]; then\n echo \"❌ Alignment issues in $file\"\n uv run skills/check_ascii_alignment.py \"$file\" --fix-suggestions\n FAILED=1\n fi\n fi\ndone\n\nif [ $FAILED -eq 1 ]; then\n echo \"\"\n echo \"Fix alignment issues before committing.\"\n exit 1\nfi\n\necho \"✓ All ASCII art properly aligned\"\nexit 0\nPREFLIGHT_EOF\n```\n\n### Shell Script Batch Processing\n\n```bash\n/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF_2'\n#!/bin/bash\n# check_all_docs.sh\n\nSCRIPT_PATH=\"skills/check_ascii_alignment.py\"\nDOCS_DIR=\"docs\"\nREPORT_DIR=\"alignment-reports\"\n\nmkdir -p \"$REPORT_DIR\"\n\necho \"Scanning markdown files in $DOCS_DIR...\"\n\nfind \"$DOCS_DIR\" -name \"*.md\" | while read -r file; do\n echo \"Checking $file...\"\n\n report_file=\"$REPORT_DIR/$(basename \"$file\" .md).json\"\n uv run \"$SCRIPT_PATH\" \"$file\" --json > \"$report_file\"\n\n if [ $? -eq 1 ]; then\n echo \" ❌ Issues found (see $report_file)\"\n else\n echo \" ✓ Clean\"\n rm \"$report_file\" # Remove empty reports\n fi\ndone\n\necho \"\"\necho \"Summary:\"\nissue_count=$(ls \"$REPORT_DIR\"/*.json 2>/dev/null | wc -l)\nif [ \"$issue_count\" -gt 0 ]; then\n echo \"Files with issues: $issue_count\"\n echo \"Reports saved in: $REPORT_DIR/\"\n exit 1\nelse\n echo \"All files clean!\"\n rmdir \"$REPORT_DIR\" 2>/dev/null\n exit 0\nfi\nPREFLIGHT_EOF_2\n```\n\n## Output Format Examples\n\n### Human-Readable Output\n\n```\n================================================================================\nAlignment Check Report: docs/ARCHITECTURE.md\n================================================================================\nTotal lines scanned: 150\nIssues found: 2 (1 errors, 1 warnings)\n================================================================================\n\ndocs/ARCHITECTURE.md:15:42: warning: vertical bar '│' misaligned\n Expected column 41\n Suggestion: Move character 1 position left\n\ndocs/ARCHITECTURE.md:23:1: error: box corner '┌' has no connecting horizontal\n Suggestion: Missing '─' or '═' to the right\n\n================================================================================\nSummary: 1 errors, 1 warnings\n================================================================================\n```\n\n### JSON Output\n\n```json\n{\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"total_lines\": 150,\n \"summary\": {\n \"total_issues\": 2,\n \"errors\": 1,\n \"warnings\": 1\n },\n \"issues\": [\n {\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"line_number\": 15,\n \"column\": 42,\n \"severity\": \"warning\",\n \"message\": \"vertical bar '│' misaligned\",\n \"character\": \"│\",\n \"expected_column\": 41,\n \"fix_suggestion\": \"Move character 1 position left\"\n },\n {\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"line_number\": 23,\n \"column\": 1,\n \"severity\": \"error\",\n \"message\": \"box corner '┌' has no connecting horizontal\",\n \"character\": \"┌\",\n \"expected_column\": null,\n \"fix_suggestion\": \"Missing '─' or '═' to the right\"\n }\n ]\n}\n```\n\n## Algorithm Implementation Checklist\n\nWhen implementing the alignment algorithm, consider:\n\n### Vertical Alignment\n\n- [ ] Track column positions of vertical bars (│, ║, ┃)\n- [ ] Detect drift across consecutive lines\n- [ ] Handle multiple vertical columns in same diagram\n- [ ] Calculate expected position based on context\n- [ ] Generate fix suggestions (move left/right)\n\n### Horizontal Connection\n\n- [ ] Verify corners have adjacent horizontal lines\n- [ ] Check T-junctions connect properly on both sides\n- [ ] Validate cross junctions (┼) have 4-way connections\n- [ ] Detect incomplete boxes\n- [ ] Suggest missing characters\n\n### Style Consistency\n\n- [ ] Detect mixing of single/double/heavy line styles\n- [ ] Flag style transitions within same box\n- [ ] Suggest style normalization\n- [ ] Allow intentional style mixing (nested boxes)\n\n### Box Structure\n\n- [ ] Match opening corners with closing corners\n- [ ] Verify complete rectangles\n- [ ] Check nested box alignment\n- [ ] Validate box dimensions (width/height consistency)\n\n## Performance Considerations\n\n### Memory\n\n- File is loaded entirely into memory (`self.lines`)\n- Suitable for typical documentation files (\u003c 10MB)\n- For very large files, consider streaming line-by-line\n\n### Speed\n\n- Single-pass scanning per validation run\n- O(n) time complexity (n = total characters)\n- Character detection uses set lookup (O(1))\n\n### Scalability\n\n```bash\n# Benchmark on large file\ntime uv run check_ascii_alignment.py large_doc.md\n\n# Profile memory usage\n/usr/bin/time -l uv run check_ascii_alignment.py large_doc.md\n```\n\n## Debugging Tips\n\n### Add Debug Output\n\n```python\n# In validate_alignment()\ndef validate_alignment(self) -> ValidationReport:\n import sys\n\n for line_num, line in enumerate(self.lines, start=1):\n box_chars = self.find_box_chars_in_line(line)\n\n # Debug output\n if box_chars:\n print(f\"DEBUG: Line {line_num}: {box_chars}\", file=sys.stderr)\n\n # ... rest of algorithm\n```\n\n### Test Individual Lines\n\n```python\n# Test character detection\nchecker = AlignmentChecker('/tmp/test.md')\ntest_line = \"┌─────────┐\"\nchars = checker.find_box_chars_in_line(test_line)\nprint(f\"Found: {chars}\")\n# Expected: [(0, '┌'), (1, '─'), (2, '─'), ..., (10, '┐')]\n```\n\n### Validate Data Structures\n\n```python\n# Check box character sets\nfrom check_ascii_alignment import BOX_CHARS, ALL_BOX_CHARS\n\nprint(f\"Total box characters: {len(ALL_BOX_CHARS)}\")\nprint(f\"Vertical chars: {BOX_CHARS['vertical']}\")\nprint(f\"Corner chars: {BOX_CHARS['corners']['top_left']}\")\n```\n\n## Next Steps\n\n1. **Implement Algorithm**: Add validation logic to `validate_alignment()`\n2. **Test Thoroughly**: Use provided test files and edge cases\n3. **Optimize**: Profile and improve performance if needed\n4. **Document**: Add algorithm-specific documentation\n5. **Integrate**: Add to Claude Code skills workflow\n\n## Resources\n\n- **Script**: `scripts/check_ascii_alignment.py`\n- **Design Report**: `references/SCRIPT_DESIGN_REPORT.md`\n- **This Guide**: `references/INTEGRATION_GUIDE.md`\n\n## Support\n\nFor issues or questions:\n\n1. Review the design report for architecture details\n2. Check test files for expected behavior\n3. Examine JSON output for debugging\n4. Add debug output to trace algorithm behavior\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":16714,"content_sha256":"96e29e7548843250a32a183f8567082dc4f4d03bfc52d8d2ec4f8782790708ef"},{"filename":"references/SCRIPT_DESIGN_REPORT.md","content":"**Skill**: [ASCII Diagram Validator](../SKILL.md)\n\n# ASCII Alignment Checker - Script Design Report\n\n## Table of Contents\n\n- [Executive Summary](#executive-summary)\n- [Design Overview](#design-overview)\n - [Architecture Components](#architecture-components)\n- [PEP 723 Header](#pep-723-header)\n- [CLI Interface](#cli-interface)\n - [Command Syntax](#command-syntax)\n - [Available Options](#available-options)\n - [Exit Codes](#exit-codes)\n- [Usage Examples](#usage-examples)\n - [Basic Check (Human-Readable)](#basic-check-human-readable)\n - [JSON Output (Machine-Parseable)](#json-output-machine-parseable)\n - [With Fix Suggestions](#with-fix-suggestions)\n - [Quiet Mode (CI/CD)](#quiet-mode-cicd)\n- [Data Models](#data-models)\n - [AlignmentIssue](#alignmentissue)\n - [ValidationReport](#validationreport)\n - [IssueSeverity](#issueseverity)\n- [Box-Drawing Character Sets](#box-drawing-character-sets)\n- [Integration Points for Alignment Algorithm](#integration-points-for-alignment-algorithm)\n - [Helper Methods Available](#helper-methods-available)\n- [Output Formatting System](#output-formatting-system)\n - [1. Human-Readable Format](#1-human-readable-format)\n - [2. JSON Format](#2-json-format)\n - [3. Quiet Format](#3-quiet-format)\n- [Testing the Script](#testing-the-script)\n - [Manual Testing](#manual-testing)\n - [Integration with CI/CD](#integration-with-cicd)\n - [Pre-commit Hook](#pre-commit-hook)\n- [Algorithm Implementation Checklist](#algorithm-implementation-checklist)\n- [Key Design Decisions](#key-design-decisions)\n - [Why Zero Dependencies?](#why-zero-dependencies)\n - [Why Three Output Formats?](#why-three-output-formats)\n - [Why Dataclasses?](#why-dataclasses)\n - [Why Enum for Severity?](#why-enum-for-severity)\n- [Next Steps](#next-steps)\n- [File Locations](#file-locations)\n- [Example Integration with Claude Code](#example-integration-with-claude-code)\n- [Conclusion](#conclusion)\n\n## Executive Summary\n\nComplete Python script skeleton designed for ASCII art alignment validation in Markdown documentation. Follows PEP 723 inline dependencies pattern and provides Claude Code-friendly output formatting.\n\n**Script Location**: `scripts/check_ascii_alignment.py`\n\n## Design Overview\n\n### Architecture Components\n\n```\n┌─────────────────────────────────────────────────────────┐\n│ CLI Interface │\n│ (argparse with --json, --quiet, --fix-suggestions) │\n└─────────────────┬───────────────────────────────────────┘\n │\n┌─────────────────▼───────────────────────────────────────┐\n│ AlignmentChecker │\n│ • load_file() - Read markdown file │\n│ • validate_alignment() - Core validation engine │\n│ • find_box_chars() - Character detection │\n│ • add_issue() - Issue tracking │\n└─────────────────┬───────────────────────────────────────┘\n │\n┌─────────────────▼───────────────────────────────────────┐\n│ Data Models │\n│ • AlignmentIssue - Single issue representation │\n│ • ValidationReport - Complete report structure │\n│ • IssueSeverity - ERROR/WARNING/INFO levels │\n└─────────────────┬───────────────────────────────────────┘\n │\n┌─────────────────▼───────────────────────────────────────┐\n│ Output Formatters │\n│ • format_human_readable() - Pretty text output │\n│ • format_json() - Machine-parseable │\n│ • format_quiet() - Exit code only │\n└─────────────────────────────────────────────────────────┘\n```\n\n## PEP 723 Header\n\nThe script uses PEP 723 inline dependencies with zero external dependencies:\n\n```python\n#!/usr/bin/env python3\n# /// script\n# dependencies = []\n# ///\n```\n\n**Key Features**:\n\n- ✅ No external dependencies (pure Python 3.12+)\n- ✅ Self-contained execution via `uv run`\n- ✅ No pip install required\n- ✅ Follows workspace PEP 723 standard\n\n## CLI Interface\n\n### Command Syntax\n\n```bash\nuv run check_ascii_alignment.py \u003cfile> [options]\n```\n\n### Available Options\n\n| Option | Description | Mutually Exclusive With |\n| ------------------- | --------------------------------- | ----------------------- |\n| `--json` | Output in JSON format | `--quiet` |\n| `--quiet` | Quiet mode (exit code only) | `--json` |\n| `--fix-suggestions` | Include fix suggestions in output | - |\n\n### Exit Codes\n\n| Code | Meaning |\n| ---- | ----------------------------------- |\n| 0 | No alignment issues found |\n| 1 | Alignment issues detected |\n| 2 | File not found or invalid arguments |\n\n## Usage Examples\n\n### Basic Check (Human-Readable)\n\n```bash\nuv run check_ascii_alignment.py docs/ARCHITECTURE.md\n```\n\n**Output**:\n\n```\n================================================================================\nAlignment Check Report: docs/ARCHITECTURE.md\n================================================================================\nTotal lines scanned: 150\nIssues found: 2 (1 errors, 1 warnings)\n================================================================================\n\ndocs/ARCHITECTURE.md:15:42: warning: vertical bar '│' misaligned\n Expected column 41\n\ndocs/ARCHITECTURE.md:23:1: error: box corner '┌' has no connecting horizontal\n Suggestion: Missing '─' or '═' to the right\n\n================================================================================\nSummary: 1 errors, 1 warnings\n================================================================================\n```\n\n### JSON Output (Machine-Parseable)\n\n```bash\nuv run check_ascii_alignment.py docs/ARCHITECTURE.md --json > report.json\n```\n\n**Output**:\n\n```json\n{\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"total_lines\": 150,\n \"summary\": {\n \"total_issues\": 2,\n \"errors\": 1,\n \"warnings\": 1\n },\n \"issues\": [\n {\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"line_number\": 15,\n \"column\": 42,\n \"severity\": \"warning\",\n \"message\": \"vertical bar '│' misaligned\",\n \"character\": \"│\",\n \"expected_column\": 41,\n \"fix_suggestion\": null\n },\n {\n \"file_path\": \"docs/ARCHITECTURE.md\",\n \"line_number\": 23,\n \"column\": 1,\n \"severity\": \"error\",\n \"message\": \"box corner '┌' has no connecting horizontal\",\n \"character\": \"┌\",\n \"expected_column\": null,\n \"fix_suggestion\": \"Missing '─' or '═' to the right\"\n }\n ]\n}\n```\n\n### With Fix Suggestions\n\n```bash\nuv run check_ascii_alignment.py docs/ARCHITECTURE.md --fix-suggestions\n```\n\n**Output**:\n\n```\ndocs/ARCHITECTURE.md:15:42: warning: vertical bar '│' misaligned\n Expected column 41\n Suggestion: Move character 1 position left\n\ndocs/ARCHITECTURE.md:23:1: error: box corner '┌' has no connecting horizontal\n Suggestion: Missing '─' or '═' to the right\n```\n\n### Quiet Mode (CI/CD)\n\n```bash\nuv run check_ascii_alignment.py docs/ARCHITECTURE.md --quiet\necho $? # Exit code: 0 = clean, 1 = issues, 2 = error\n```\n\n**Output**:\n\n```\n2 issues found\n```\n\n## Data Models\n\n### AlignmentIssue\n\nRepresents a single alignment issue.\n\n```python\n@dataclass\nclass AlignmentIssue:\n file_path: str # File containing the issue\n line_number: int # Line number (1-based)\n column: int # Column number (0-based)\n severity: IssueSeverity # ERROR/WARNING/INFO\n message: str # Human-readable description\n character: str # The problematic character\n expected_column: Optional[int] # Expected alignment column\n fix_suggestion: Optional[str] # How to fix the issue\n```\n\n**Methods**:\n\n- `to_dict()` - Convert to dictionary (for JSON)\n- `format_human_readable(show_suggestions: bool)` - Format for console output\n\n### ValidationReport\n\nComplete validation report for a file.\n\n```python\n@dataclass\nclass ValidationReport:\n file_path: str # File that was validated\n total_lines: int # Total lines scanned\n issues: List[AlignmentIssue] # All detected issues\n```\n\n**Properties**:\n\n- `has_errors: bool` - Check if report contains errors\n- `has_warnings: bool` - Check if report contains warnings\n- `error_count: int` - Count error-level issues\n- `warning_count: int` - Count warning-level issues\n\n**Methods**:\n\n- `to_dict()` - Convert to dictionary (for JSON)\n\n### IssueSeverity\n\n```python\nclass IssueSeverity(Enum):\n ERROR = \"error\" # Critical misalignment (breaks visual structure)\n WARNING = \"warning\" # Minor misalignment (visual inconsistency)\n INFO = \"info\" # Informational (style suggestions)\n```\n\n## Box-Drawing Character Sets\n\nThe script includes comprehensive box-drawing character definitions:\n\n```python\nBOX_CHARS = {\n # Corners\n 'corners': {\n 'top_left': ['┌', '╔', '┏'],\n 'top_right': ['┐', '╗', '┓'],\n 'bottom_left': ['└', '╚', '┗'],\n 'bottom_right': ['┘', '╝', '┛'],\n },\n # T-junctions\n 't_junctions': {\n 'top': ['┬', '╦', '┳'],\n 'bottom': ['┴', '╩', '┻'],\n 'left': ['├', '╠', '┣'],\n 'right': ['┤', '╣', '┫'],\n },\n # Cross\n 'cross': ['┼', '╬', '╋'],\n # Lines\n 'horizontal': ['─', '═', '━'],\n 'vertical': ['│', '║', '┃'],\n}\n```\n\n**Styles Supported**:\n\n- Single-line: `┌─┐│└┘`\n- Double-line: `╔═╗║╚╝`\n- Heavy-line: `┏━┓┃┗┛`\n\n## Integration Points for Alignment Algorithm\n\nThe script provides a clear integration point for the alignment algorithm:\n\n```python\nclass AlignmentChecker:\n def validate_alignment(self) -> ValidationReport:\n \"\"\"\n Perform alignment validation.\n\n This is the main entry point for validation logic.\n The actual validation algorithm will be implemented separately.\n \"\"\"\n # TODO: Implement validation algorithm\n\n for line_num, line in enumerate(self.lines, start=1):\n box_chars = self.find_box_chars_in_line(line)\n\n # Your algorithm implementation goes here\n # Use self.add_issue() to report problems\n\n return ValidationReport(\n file_path=self.file_path,\n total_lines=len(self.lines),\n issues=self.issues\n )\n```\n\n### Helper Methods Available\n\n```python\n# Find all box-drawing characters in a line\nbox_chars = self.find_box_chars_in_line(line)\n# Returns: List[Tuple[int, str]] - [(column, character), ...]\n\n# Add an issue to the report\nself.add_issue(\n line_num=15,\n col=42,\n severity=IssueSeverity.WARNING,\n message=\"vertical bar '│' misaligned\",\n character='│',\n expected_col=41,\n fix_suggestion=\"Move character 1 position left\"\n)\n```\n\n## Output Formatting System\n\nThe script includes three output formatters:\n\n### 1. Human-Readable Format\n\n```python\nOutputFormatter.format_human_readable(report, show_suggestions=False)\n```\n\n**Features**:\n\n- Clear section headers\n- Line:column references\n- Severity indicators\n- Optional fix suggestions\n- Summary statistics\n\n**Best For**: Manual review, debugging, IDE integration\n\n### 2. JSON Format\n\n```python\nOutputFormatter.format_json(report)\n```\n\n**Features**:\n\n- Structured data (machine-parseable)\n- Complete issue metadata\n- Summary statistics\n- Compatible with jq, Python, etc.\n\n**Best For**: CI/CD pipelines, automated tooling, data analysis\n\n### 3. Quiet Format\n\n```python\nOutputFormatter.format_quiet(report)\n```\n\n**Features**:\n\n- Minimal output (single line summary)\n- Primary communication via exit code\n- Silent on success\n\n**Best For**: Shell scripts, pre-commit hooks, automation\n\n## Testing the Script\n\n### Manual Testing\n\n```bash\n# Create a test file with intentional misalignment\ncat > /tmp/test_alignment.md \u003c\u003c 'EOF'\n# Test Document\n\n┌─────────┐\n│ Column 1│\n│ Column 2 │ # Misaligned vertical bar\n└─────────┘\n\n┌────── # Missing closing horizontal\nEOF\n\n# Test basic check\nuv run check_ascii_alignment.py /tmp/test_alignment.md\n\n# Test JSON output\nuv run check_ascii_alignment.py /tmp/test_alignment.md --json\n\n# Test with suggestions\nuv run check_ascii_alignment.py /tmp/test_alignment.md --fix-suggestions\n\n# Test quiet mode\nuv run check_ascii_alignment.py /tmp/test_alignment.md --quiet\necho \"Exit code: $?\"\n```\n\n### Integration with CI/CD\n\n```yaml\n# GitHub Actions example\n- name: Check ASCII alignment\n run: |\n uv run check_ascii_alignment.py docs/**/*.md --json > alignment-report.json\n\n if [ $? -eq 1 ]; then\n echo \"Alignment issues detected\"\n cat alignment-report.json\n exit 1\n fi\n```\n\n### Pre-commit Hook\n\n```bash\n/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF'\n#!/bin/bash\n# .git/hooks/pre-commit\n\nfor file in $(git diff --cached --name-only | grep '\\.md

ASCII Diagram Validator Validate and fix alignment issues in ASCII box-drawing diagrams commonly used in architecture documentation, README files, and code comments. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Overview ASCII diagrams using box-drawing characters (─│┌┐└┘├┤┬┴┼ and double-line variants ═║╔╗╚╝╠╣╦╩╬) require precise column alignment. This skill provides: 1. Validation script - Detects misaligned characters with fi…

); do\n if [ -f \"$file\" ]; then\n uv run check_ascii_alignment.py \"$file\" --quiet\n if [ $? -eq 1 ]; then\n echo \"Alignment issues in $file\"\n uv run check_ascii_alignment.py \"$file\" --fix-suggestions\n exit 1\n fi\n fi\ndone\nPREFLIGHT_EOF\n```\n\n## Algorithm Implementation Checklist\n\nThe script skeleton is complete. To add the alignment algorithm:\n\n- [ ] **Vertical Alignment Detection**\n - Track column positions of vertical bars across consecutive lines\n - Detect drift/misalignment\n - Use `self.add_issue()` for deviations\n\n- [ ] **Horizontal Connection Validation**\n - Check corners have adjacent horizontal lines\n - Verify T-junctions connect properly\n - Validate box continuity\n\n- [ ] **Style Consistency Check**\n - Detect mixed single/double/heavy line styles\n - Flag style transitions (if desired)\n - Provide style normalization suggestions\n\n- [ ] **Box Structure Validation**\n - Match opening/closing corners\n - Verify complete rectangles\n - Check nested box alignment\n\n## Key Design Decisions\n\n### Why Zero Dependencies?\n\n- **Simplicity**: No external dependency management\n- **Portability**: Works everywhere Python 3.12+ is available\n- **Speed**: No dependency resolution overhead\n- **Reliability**: No external API changes to track\n\n### Why Three Output Formats?\n\n- **Human-Readable**: For manual debugging and IDE integration\n- **JSON**: For automation, CI/CD, and tooling integration\n- **Quiet**: For shell scripts and exit-code-based workflows\n\n### Why Dataclasses?\n\n- **Clarity**: Self-documenting data structures\n- **Type Safety**: Built-in type hints\n- **Serialization**: Easy conversion to dict/JSON\n- **Immutability**: Safer concurrent access (frozen=True available)\n\n### Why Enum for Severity?\n\n- **Type Safety**: Prevent invalid severity values\n- **Autocomplete**: IDE support for valid values\n- **Extensibility**: Easy to add new severity levels\n- **Serialization**: Clean JSON representation\n\n## Next Steps\n\n1. **Algorithm Implementation** (Next Agent Task)\n - Implement vertical alignment tracking\n - Add horizontal connection validation\n - Implement style consistency checks\n\n2. **Testing** (After Algorithm)\n - Unit tests for edge cases\n - Integration tests with real markdown files\n - Performance testing on large files\n\n3. **Documentation** (After Testing)\n - Add algorithm documentation\n - Create troubleshooting guide\n - Document common patterns/anti-patterns\n\n## File Locations\n\n- **Script**: `scripts/check_ascii_alignment.py`\n- **Design Report**: `references/SCRIPT_DESIGN_REPORT.md`\n\n## Example Integration with Claude Code\n\nWhen Claude Code encounters an alignment issue:\n\n```\n$ uv run check_ascii_alignment.py docs/ARCHITECTURE.md\n\ndocs/ARCHITECTURE.md:15:42: warning: vertical bar '│' misaligned\n Expected column 41\n Suggestion: Move character 1 position left\n```\n\nClaude Code can:\n\n1. Parse the `file:line:column` format\n2. Navigate directly to the issue\n3. Read the fix suggestion\n4. Apply the fix automatically (if desired)\n\n## Conclusion\n\nThe script skeleton is production-ready and follows all workspace standards:\n\n✅ PEP 723 inline dependencies\n✅ `uv run` execution pattern\n✅ Claude Code-friendly output\n✅ Machine-parseable JSON format\n✅ Clear integration points\n✅ Comprehensive data models\n✅ Exit code semantics\n✅ Zero external dependencies\n\nReady for algorithm implementation (next DCTL agent task).\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":17456,"content_sha256":"f041d346407643faa050f89717a2f4fa35d5160618afac5ac916b0657b4714fe"},{"filename":"scripts/check_ascii_alignment.py","content":"#!/usr/bin/env python3\n# /// script\n# dependencies = []\n# ///\n\"\"\"\nASCII Diagram Alignment Validator\n\nValidates alignment of box-drawing characters in enclosed box diagrams.\nSkips file tree structures (├── patterns) and handles arrow characters.\nOutputs issues in compiler-like format: file:line:column: severity: message\n\nUsage:\n uv run check_ascii_alignment.py \u003cfile_or_directory> [--warn-only] [--verbose]\n\nExamples:\n uv run check_ascii_alignment.py docs/ARCHITECTURE.md\n uv run check_ascii_alignment.py docs/*.md\n uv run check_ascii_alignment.py docs/ --verbose\n\"\"\"\nimport argparse\nimport re\nimport sys\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom pathlib import Path\n\n# Box-drawing character sets\n# Light (single) lines\nSINGLE_HORIZONTAL = set('─')\nSINGLE_VERTICAL = set('│')\n# Double lines\nDOUBLE_HORIZONTAL = set('═')\nDOUBLE_VERTICAL = set('║')\n# Heavy (bold) lines - used by graph-easy boxart\nHEAVY_HORIZONTAL = set('━')\nHEAVY_VERTICAL = set('┃')\n\nHORIZONTAL = SINGLE_HORIZONTAL | DOUBLE_HORIZONTAL | HEAVY_HORIZONTAL\nVERTICAL = SINGLE_VERTICAL | DOUBLE_VERTICAL | HEAVY_VERTICAL\n\n# Corners - Light\nCORNER_TL_LIGHT = set('┌')\nCORNER_TR_LIGHT = set('┐')\nCORNER_BL_LIGHT = set('└')\nCORNER_BR_LIGHT = set('┘')\n# Corners - Double\nCORNER_TL_DOUBLE = set('╔')\nCORNER_TR_DOUBLE = set('╗')\nCORNER_BL_DOUBLE = set('╚')\nCORNER_BR_DOUBLE = set('╝')\n# Corners - Heavy (bold) - used by graph-easy boxart\nCORNER_TL_HEAVY = set('┏')\nCORNER_TR_HEAVY = set('┓')\nCORNER_BL_HEAVY = set('┗')\nCORNER_BR_HEAVY = set('┛')\n# Corners - Rounded (arc) - used by graph-easy shape: rounded\nCORNER_TL_ROUNDED = set('╭')\nCORNER_TR_ROUNDED = set('╮')\nCORNER_BL_ROUNDED = set('╰')\nCORNER_BR_ROUNDED = set('╯')\n\nCORNER_TL = CORNER_TL_LIGHT | CORNER_TL_DOUBLE | CORNER_TL_HEAVY | CORNER_TL_ROUNDED\nCORNER_TR = CORNER_TR_LIGHT | CORNER_TR_DOUBLE | CORNER_TR_HEAVY | CORNER_TR_ROUNDED\nCORNER_BL = CORNER_BL_LIGHT | CORNER_BL_DOUBLE | CORNER_BL_HEAVY | CORNER_BL_ROUNDED\nCORNER_BR = CORNER_BR_LIGHT | CORNER_BR_DOUBLE | CORNER_BR_HEAVY | CORNER_BR_ROUNDED\nCORNERS = CORNER_TL | CORNER_TR | CORNER_BL | CORNER_BR\n\n# T-junctions - Light\nT_LEFT_LIGHT = set('├')\nT_RIGHT_LIGHT = set('┤')\nT_TOP_LIGHT = set('┬')\nT_BOTTOM_LIGHT = set('┴')\n# T-junctions - Double\nT_LEFT_DOUBLE = set('╠╞╟')\nT_RIGHT_DOUBLE = set('╣╡╢')\nT_TOP_DOUBLE = set('╦╤╥')\nT_BOTTOM_DOUBLE = set('╩╧╨')\n# T-junctions - Heavy (bold) - used by graph-easy boxart\nT_LEFT_HEAVY = set('┣┡┢┝┞┟┠')\nT_RIGHT_HEAVY = set('┫┥┦┧┨┩┪')\nT_TOP_HEAVY = set('┳┭┮┯┰┱┲')\nT_BOTTOM_HEAVY = set('┻┵┶┷┸┹┺')\n\nT_LEFT = T_LEFT_LIGHT | T_LEFT_DOUBLE | T_LEFT_HEAVY\nT_RIGHT = T_RIGHT_LIGHT | T_RIGHT_DOUBLE | T_RIGHT_HEAVY\nT_TOP = T_TOP_LIGHT | T_TOP_DOUBLE | T_TOP_HEAVY\nT_BOTTOM = T_BOTTOM_LIGHT | T_BOTTOM_DOUBLE | T_BOTTOM_HEAVY\nT_JUNCTIONS = T_LEFT | T_RIGHT | T_TOP | T_BOTTOM\n\n# Crosses - Light, Double, Heavy\nCROSSES = set('┼╬╪╫╋')\n\n# Arrow characters (valid terminators for lines)\n# Includes graph-easy arrows: ∨∧ (mathematical symbols used as arrows)\nARROWS = set('▶▷►▻▸▹→⟶⟹▼▽▾▿↓⇓◀◁◄◅◂◃←⟵⟸▲△▴▵↑⇑∨∧\u003c>')\n\n# Block elements - used by graph-easy as decorative borders (valid terminators)\n# ▐ (right half block), ▌ (left half block), ▀ (upper half), ▄ (lower half)\nBLOCK_ELEMENTS = set('▐▌▀▄█░▒▓')\n\n# Ellipsis characters - used by graph-easy for truncation (valid terminators)\n# ⋮ (vertical ellipsis), ⋯ (horizontal ellipsis), … (horizontal ellipsis)\nELLIPSIS_CHARS = set('⋮⋯…')\n\n# Valid line terminators (arrows + block elements + ellipsis)\nVALID_TERMINATORS = ARROWS | BLOCK_ELEMENTS | ELLIPSIS_CHARS\n\n# All box-drawing characters\nALL_BOX_CHARS = HORIZONTAL | VERTICAL | CORNERS | T_JUNCTIONS | CROSSES\n\n# Characters that connect upward\nCONNECTS_UP = VERTICAL | CORNER_BL | CORNER_BR | T_LEFT | T_RIGHT | T_BOTTOM | CROSSES\n# Characters that connect downward\nCONNECTS_DOWN = VERTICAL | CORNER_TL | CORNER_TR | T_LEFT | T_RIGHT | T_TOP | CROSSES\n# Characters that connect left\nCONNECTS_LEFT = HORIZONTAL | CORNER_TR | CORNER_BR | T_TOP | T_BOTTOM | T_RIGHT | CROSSES\n# Characters that connect right\nCONNECTS_RIGHT = HORIZONTAL | CORNER_TL | CORNER_BL | T_TOP | T_BOTTOM | T_LEFT | CROSSES\n\n# File tree patterns to skip (require space after dashes for actual tree patterns)\nFILE_TREE_PATTERN = re.compile(r'[├└]── ')\n\n\nclass Severity(Enum):\n ERROR = \"error\"\n WARNING = \"warning\"\n INFO = \"info\"\n\n\n@dataclass\nclass Issue:\n file: str\n line: int\n column: int\n severity: Severity\n message: str\n suggestion: str | None = None\n\n def __str__(self) -> str:\n base = f\"{self.file}:{self.line}:{self.column}: {self.severity.value}: {self.message}\"\n if self.suggestion:\n base += f\"\\n → Suggestion: {self.suggestion}\"\n return base\n\n\ndef is_file_tree_block(lines: list[str]) -> bool:\n \"\"\"Detect if a code block is a file tree structure.\"\"\"\n tree_line_count = 0\n for line in lines:\n if FILE_TREE_PATTERN.search(line):\n tree_line_count += 1\n # If more than 20% of lines have tree patterns, it's a file tree\n return tree_line_count > len(lines) * 0.2\n\n\ndef is_enclosed_box_diagram(lines: list[str]) -> bool:\n \"\"\"Detect if a code block contains an enclosed box diagram (with corner characters).\"\"\"\n has_tl = any(any(c in CORNER_TL for c in line) for line in lines)\n has_tr = any(any(c in CORNER_TR for c in line) for line in lines)\n has_bl = any(any(c in CORNER_BL for c in line) for line in lines)\n has_br = any(any(c in CORNER_BR for c in line) for line in lines)\n\n # For a proper enclosed box, we need at least top-left + bottom-right or top-right + bottom-left\n return (has_tl and has_br) or (has_tr and has_bl) or (has_tl and has_tr and has_bl and has_br)\n\n\ndef get_char_at(lines: list[str], row: int, col: int) -> str | None:\n \"\"\"Get character at position, handling bounds.\"\"\"\n if row \u003c 0 or row >= len(lines):\n return None\n line = lines[row]\n if col \u003c 0 or col >= len(line):\n return None\n return line[col]\n\n\ndef find_box_chars_in_line(line: str) -> list[tuple[int, str]]:\n \"\"\"Find all box-drawing characters in a line with their column positions.\"\"\"\n results = []\n for col, char in enumerate(line):\n if char in ALL_BOX_CHARS:\n results.append((col, char))\n return results\n\n\ndef check_vertical_alignment(\n lines: list[str], row: int, col: int, char: str, file: str\n) -> list[Issue]:\n \"\"\"Check vertical alignment for a character that connects up or down.\"\"\"\n issues = []\n\n # Check if character should connect upward\n if char in CONNECTS_UP:\n above = get_char_at(lines, row - 1, col)\n # Valid connections: box chars that connect down, arrows, terminators,\n # or horizontal lines (graph-easy arrow stem pattern: │ below ─)\n if above is not None and above not in CONNECTS_DOWN and above not in ' \\t' and above not in VALID_TERMINATORS and above not in HORIZONTAL:\n issues.append(Issue(\n file=file,\n line=row + 1, # 1-indexed\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"vertical connector '{char}' at column {col + 1} has no matching character above (found '{above}')\",\n suggestion=f\"Add '│', '├', '┤', '┬', or '┼' at line {row}, column {col + 1}, or check if '{char}' should be a different character\"\n ))\n\n # Check if character should connect downward\n if char in CONNECTS_DOWN:\n below = get_char_at(lines, row + 1, col)\n # Valid connections: box chars that connect up, arrows, terminators,\n # or horizontal lines (graph-easy arrow stem pattern: │ above ─)\n if below is not None and below not in CONNECTS_UP and below not in ' \\t' and below not in VALID_TERMINATORS and below not in HORIZONTAL:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"vertical connector '{char}' at column {col + 1} has no matching character below (found '{below}')\",\n suggestion=f\"Add '│', '├', '┤', '┴', or '┼' at line {row + 2}, column {col + 1}, or check if '{char}' should be a different character\"\n ))\n\n return issues\n\n\ndef check_horizontal_alignment(\n lines: list[str], row: int, col: int, char: str, file: str\n) -> list[Issue]:\n \"\"\"Check horizontal alignment for a character that connects left or right.\"\"\"\n issues = []\n line = lines[row]\n\n # Check if character should connect left\n if char in CONNECTS_LEFT:\n left = get_char_at(lines, row, col - 1)\n if col > 0 and left is not None and left not in CONNECTS_RIGHT and left not in ' \\t' and left not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"horizontal connector '{char}' has no matching character to the left (found '{left}')\",\n suggestion=f\"Add '─', '┌', '└', '┬', '┴', or '┼' at column {col}\"\n ))\n\n # Check if character should connect right\n if char in CONNECTS_RIGHT:\n right = get_char_at(lines, row, col + 1)\n if col \u003c len(line) - 1 and right is not None and right not in CONNECTS_LEFT and right not in ' \\t' and right not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"horizontal connector '{char}' has no matching character to the right (found '{right}')\",\n suggestion=f\"Add '─', '┐', '┘', '┬', '┴', or '┼' at column {col + 2}\"\n ))\n\n return issues\n\n\ndef check_corner_connections(\n lines: list[str], row: int, col: int, char: str, file: str\n) -> list[Issue]:\n \"\"\"Validate corner characters have proper connections.\"\"\"\n issues = []\n\n # Top-left corner: should connect right and down\n if char in CORNER_TL:\n right = get_char_at(lines, row, col + 1)\n below = get_char_at(lines, row + 1, col)\n\n if right is not None and right not in CONNECTS_LEFT and right not in ' \\t\\n' and right not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"top-left corner '{char}' not connected to the right\",\n suggestion=\"Add horizontal line '─' or '═' after the corner\"\n ))\n\n if below is not None and below not in CONNECTS_UP and below not in ' \\t\\n' and below not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"top-left corner '{char}' not connected below\",\n suggestion=f\"Add vertical line '│' or '║' at line {row + 2}, column {col + 1}\"\n ))\n\n # Top-right corner: should connect left and down\n if char in CORNER_TR:\n left = get_char_at(lines, row, col - 1)\n below = get_char_at(lines, row + 1, col)\n\n if left is not None and left not in CONNECTS_RIGHT and left not in ' \\t\\n' and left not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"top-right corner '{char}' not connected to the left\",\n suggestion=\"Add horizontal line '─' or '═' before the corner\"\n ))\n\n if below is not None and below not in CONNECTS_UP and below not in ' \\t\\n' and below not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"top-right corner '{char}' not connected below\",\n suggestion=f\"Add vertical line '│' or '║' at line {row + 2}, column {col + 1}\"\n ))\n\n # Bottom-left corner: should connect right and up\n if char in CORNER_BL:\n right = get_char_at(lines, row, col + 1)\n above = get_char_at(lines, row - 1, col)\n\n if right is not None and right not in CONNECTS_LEFT and right not in ' \\t\\n' and right not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"bottom-left corner '{char}' not connected to the right\",\n suggestion=\"Add horizontal line '─' or '═' after the corner\"\n ))\n\n if above is not None and above not in CONNECTS_DOWN and above not in ' \\t\\n' and above not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"bottom-left corner '{char}' not connected above\",\n suggestion=f\"Add vertical line '│' or '║' at line {row}, column {col + 1}\"\n ))\n\n # Bottom-right corner: should connect left and up\n if char in CORNER_BR:\n left = get_char_at(lines, row, col - 1)\n above = get_char_at(lines, row - 1, col)\n\n if left is not None and left not in CONNECTS_RIGHT and left not in ' \\t\\n' and left not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"bottom-right corner '{char}' not connected to the left\",\n suggestion=\"Add horizontal line '─' or '═' before the corner\"\n ))\n\n if above is not None and above not in CONNECTS_DOWN and above not in ' \\t\\n' and above not in VALID_TERMINATORS:\n issues.append(Issue(\n file=file,\n line=row + 1,\n column=col + 1,\n severity=Severity.ERROR,\n message=f\"bottom-right corner '{char}' not connected above\",\n suggestion=f\"Add vertical line '│' or '║' at line {row}, column {col + 1}\"\n ))\n\n return issues\n\n\ndef extract_code_blocks(content: str) -> list[tuple[int, list[str]]]:\n \"\"\"Extract code blocks from markdown, returning (start_line, lines) tuples.\"\"\"\n blocks = []\n lines = content.split('\\n')\n in_block = False\n block_start = 0\n block_lines = []\n\n for i, line in enumerate(lines):\n stripped = line.strip()\n if stripped.startswith('```'):\n if in_block:\n # End of block\n blocks.append((block_start, block_lines))\n block_lines = []\n in_block = False\n else:\n # Start of block\n in_block = True\n block_start = i + 1 # Next line is start of content\n elif in_block:\n block_lines.append(line)\n\n return blocks\n\n\ndef validate_block(block_lines: list[str], block_start: int, file_path: str, verbose: bool) -> list[Issue]:\n \"\"\"Validate a single code block for ASCII diagram alignment issues.\"\"\"\n issues = []\n\n # Check if this block contains any box-drawing characters\n has_box_chars = any(\n any(c in ALL_BOX_CHARS for c in line)\n for line in block_lines\n )\n\n if not has_box_chars:\n return issues\n\n # Skip file tree structures\n if is_file_tree_block(block_lines):\n if verbose:\n print(f\" Skipping file tree structure at line {block_start + 1}\")\n return issues\n\n # Only validate enclosed box diagrams\n if not is_enclosed_box_diagram(block_lines):\n if verbose:\n print(f\" Skipping non-enclosed diagram at line {block_start + 1}\")\n return issues\n\n if verbose:\n print(f\" Checking enclosed box diagram at line {block_start + 1}\")\n\n # Validate each line in the block\n for rel_row, line in enumerate(block_lines):\n box_chars = find_box_chars_in_line(line)\n\n for col, char in box_chars:\n # Check vertical alignment\n vert_issues = check_vertical_alignment(\n block_lines, rel_row, col, char, file_path\n )\n # Adjust line numbers to absolute file positions\n for issue in vert_issues:\n issues.append(Issue(\n file=issue.file,\n line=block_start + issue.line,\n column=issue.column,\n severity=issue.severity,\n message=issue.message,\n suggestion=issue.suggestion\n ))\n\n # Check horizontal alignment\n horiz_issues = check_horizontal_alignment(\n block_lines, rel_row, col, char, file_path\n )\n for issue in horiz_issues:\n issues.append(Issue(\n file=issue.file,\n line=block_start + issue.line,\n column=issue.column,\n severity=issue.severity,\n message=issue.message,\n suggestion=issue.suggestion\n ))\n\n # Check corner connections\n if char in CORNERS:\n corner_issues = check_corner_connections(\n block_lines, rel_row, col, char, file_path\n )\n for issue in corner_issues:\n issues.append(Issue(\n file=issue.file,\n line=block_start + issue.line,\n column=issue.column,\n severity=issue.severity,\n message=issue.message,\n suggestion=issue.suggestion\n ))\n\n return issues\n\n\ndef validate_file(file_path: Path, verbose: bool = False) -> list[Issue]:\n \"\"\"Validate a single file for ASCII diagram alignment issues.\"\"\"\n issues = []\n\n try:\n content = file_path.read_text(encoding='utf-8')\n except (OSError, UnicodeDecodeError) as e:\n issues.append(Issue(\n file=str(file_path),\n line=0,\n column=0,\n severity=Severity.ERROR,\n message=f\"Could not read file: {e}\"\n ))\n return issues\n\n # Extract code blocks from markdown\n code_blocks = extract_code_blocks(content)\n\n if verbose:\n print(f\" Found {len(code_blocks)} code block(s) in {file_path}\")\n\n for block_start, block_lines in code_blocks:\n block_issues = validate_block(block_lines, block_start, str(file_path), verbose)\n issues.extend(block_issues)\n\n return issues\n\n\ndef validate_path(path: Path, verbose: bool = False) -> list[Issue]:\n \"\"\"Validate a file or directory.\"\"\"\n issues = []\n\n if path.is_file():\n if verbose:\n print(f\"Validating: {path}\")\n issues.extend(validate_file(path, verbose))\n elif path.is_dir():\n # Find all markdown files\n for md_file in sorted(path.rglob('*.md')):\n if verbose:\n print(f\"Validating: {md_file}\")\n issues.extend(validate_file(md_file, verbose))\n else:\n issues.append(Issue(\n file=str(path),\n line=0,\n column=0,\n severity=Severity.ERROR,\n message=f\"Path does not exist: {path}\"\n ))\n\n return issues\n\n\ndef main():\n parser = argparse.ArgumentParser(\n description='Validate ASCII box-drawing diagram alignment in markdown files'\n )\n parser.add_argument(\n 'paths',\n nargs='+',\n type=Path,\n help='Files or directories to validate'\n )\n parser.add_argument(\n '--warn-only',\n action='store_true',\n help='Exit 0 even if warnings found (still exit 1 on errors)'\n )\n parser.add_argument(\n '--verbose', '-v',\n action='store_true',\n help='Print verbose progress information'\n )\n\n args = parser.parse_args()\n\n all_issues: list[Issue] = []\n\n for path in args.paths:\n all_issues.extend(validate_path(path, args.verbose))\n\n # Deduplicate issues (same file:line:column:message)\n seen = set()\n unique_issues = []\n for issue in all_issues:\n key = (issue.file, issue.line, issue.column, issue.message)\n if key not in seen:\n seen.add(key)\n unique_issues.append(issue)\n\n # Sort by file, then line, then column\n unique_issues.sort(key=lambda i: (i.file, i.line, i.column))\n\n # Print issues\n for issue in unique_issues:\n print(issue)\n\n # Summary\n error_count = sum(1 for i in unique_issues if i.severity == Severity.ERROR)\n warning_count = sum(1 for i in unique_issues if i.severity == Severity.WARNING)\n info_count = sum(1 for i in unique_issues if i.severity == Severity.INFO)\n\n if unique_issues:\n print(f\"\\n{'─' * 60}\")\n print(f\"Summary: {error_count} error(s), {warning_count} warning(s), {info_count} info\")\n\n # Exit code\n if error_count > 0:\n sys.exit(1)\n elif warning_count > 0 and not args.warn_only:\n sys.exit(2)\n else:\n if not unique_issues:\n print(\"✓ No alignment issues found\")\n sys.exit(0)\n\n\nif __name__ == '__main__':\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":21871,"content_sha256":"3f9ae7fb9fd312ad761292a579485ee7bf7986f0482d22d8b0bf8eaf44fcb09c"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"ASCII Diagram Validator","type":"text"}]},{"type":"paragraph","content":[{"text":"Validate and fix alignment issues in ASCII box-drawing diagrams commonly used in architecture documentation, README files, and code comments.","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Self-Evolving Skill","type":"text","marks":[{"type":"strong"}]},{"text":": This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"ASCII diagrams using box-drawing characters (─│┌┐└┘├┤┬┴┼ and double-line variants ═║╔╗╚╝╠╣╦╩╬) require precise column alignment. This skill provides:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validation script","type":"text","marks":[{"type":"strong"}]},{"text":" - Detects misaligned characters with file:line:column locations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Actionable fixes","type":"text","marks":[{"type":"strong"}]},{"text":" - Specific suggestions for correcting each issue","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Multi-file support","type":"text","marks":[{"type":"strong"}]},{"text":" - Validate individual files or entire directories","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"Invoke when:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating or editing ASCII architecture diagrams in markdown","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reviewing documentation with box-drawing diagrams","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fixing \"diagram looks wrong\" complaints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before committing docs/ARCHITECTURE.md or similar files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When user mentions \"ASCII alignment\", \"diagram alignment\", or \"box drawing\"","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Supported Characters","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Single-Line Box Drawing","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Corners: ┌ ┐ └ ┘\nLines: ─ │\nT-joins: ├ ┤ ┬ ┴\nCross: ┼","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Double-Line Box Drawing","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Corners: ╔ ╗ ╚ ╝\nLines: ═ ║\nT-joins: ╠ ╣ ╦ ╩\nCross: ╬","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Mixed (Double-Single)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"╞ ╟ ╤ ╧ ╪ ╫","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Validate a Single File","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF'\nuv run ${CLAUDE_PLUGIN_ROOT}/skills/ascii-diagram-validator/scripts/check_ascii_alignment.py docs/ARCHITECTURE.md\nPREFLIGHT_EOF","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Validate Multiple Files","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF_2'\nuv run ${CLAUDE_PLUGIN_ROOT}/skills/ascii-diagram-validator/scripts/check_ascii_alignment.py docs/*.md\nPREFLIGHT_EOF_2","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Validate Directory","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF_3'\nuv run ${CLAUDE_PLUGIN_ROOT}/skills/ascii-diagram-validator/scripts/check_ascii_alignment.py docs/\nPREFLIGHT_EOF_3","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"paragraph","content":[{"text":"The script outputs issues in a compiler-like format for easy navigation:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"docs/ARCHITECTURE.md:45:12: error: vertical connector '│' at column 12 has no matching character above\n → Suggestion: Add '│', '├', '┤', '┬', or '┼' at line 44, column 12\n\ndocs/ARCHITECTURE.md:67:8: warning: horizontal line '─' at column 8 has no terminator\n → Suggestion: Add '┐', '┘', '┤', '┴', or '┼' to close the line","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Severity Levels","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Level","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"error","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Broken connections, misaligned verticals","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unterminated lines, potential issues","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"info","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Style suggestions (optional cleanup)","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Validation Rules","type":"text"}]},{"type":"paragraph","content":[{"text":"The script checks for:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Vertical Alignment","type":"text","marks":[{"type":"strong"}]},{"text":" - Vertical connectors (│║) must align with characters above/below","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Corner Connections","type":"text","marks":[{"type":"strong"}]},{"text":" - Corners (┌┐└┘╔╗╚╝) must connect properly to adjacent lines","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Junction Validity","type":"text","marks":[{"type":"strong"}]},{"text":" - T-joins and crosses must have correct incoming/outgoing connections","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Line Continuity","type":"text","marks":[{"type":"strong"}]},{"text":" - Horizontal lines (─═) should terminate at valid endpoints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Box Closure","type":"text","marks":[{"type":"strong"}]},{"text":" - Boxes should be properly closed (no dangling edges)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Exit Codes","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Code","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Meaning","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No issues found","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Errors detected","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warnings only (errors ignored with --warn-only)","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration with Claude Code","type":"text"}]},{"type":"paragraph","content":[{"text":"When Claude Code creates or edits ASCII diagrams:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run the validator script on the file","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review any errors in the output","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Apply suggested fixes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Re-run until clean","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Example Workflow","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"/usr/bin/env bash \u003c\u003c 'PREFLIGHT_EOF_4'\n# After editing docs/ARCHITECTURE.md\nuv run ${CLAUDE_PLUGIN_ROOT}/skills/ascii-diagram-validator/scripts/check_ascii_alignment.py docs/ARCHITECTURE.md\n\n# If errors found, Claude Code can read the output and fix:\n# docs/ARCHITECTURE.md:45:12: error: vertical connector '│' at column 12 has no matching character above\n# → Edit line 44, column 12 to add the missing connector\nPREFLIGHT_EOF_4","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Limitations","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects structural alignment issues, not aesthetic spacing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Requires consistent use of box-drawing characters (no mixed ASCII like +---+)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tab characters may cause false positives (convert to spaces first)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unicode normalization not performed (use pre-composed characters)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Bundled Scripts","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Script","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/check_ascii_alignment.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Main validation script","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ARCHITECTURE.md best practices","type":"text","marks":[{"type":"link","attrs":{"href":"https://github.com/joelparkerhenderson/architecture-decision-record","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unicode Box Drawing block","type":"text","marks":[{"type":"link","attrs":{"href":"https://www.unicode.org/charts/PDF/U2500.pdf","title":null}}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Troubleshooting","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cause","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Solution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Script not found","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Plugin not installed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verify plugin installed with ","type":"text"},{"text":"claude plugin list","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"False positives with tabs","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tab characters misalign","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Convert tabs to spaces before validation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mixed ASCII not detected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using ","type":"text"},{"text":"+---+","type":"text","marks":[{"type":"code_inline"}]},{"text":" style","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Script only validates Unicode box-drawing chars","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Column numbers off","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unicode width calculation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use pre-composed characters, avoid combining marks","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No issues but looks wrong","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Aesthetic spacing not checked","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Validator checks structure, not visual spacing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Exit code 2 unexpected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"warnings only mode","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use --warn-only flag to treat warnings as success","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Can't find validation error","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Complex nested diagram","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check line numbers in output, validate section only","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unicode chars not rendering","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Terminal font missing glyphs","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use font with full Unicode box-drawing support","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Post-Execution Reflection","type":"text"}]},{"type":"paragraph","content":[{"text":"After this skill completes, check before closing:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Did the command succeed?","type":"text","marks":[{"type":"strong"}]},{"text":" — If not, fix the instruction or error table that caused the failure.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Did parameters or output change?","type":"text","marks":[{"type":"strong"}]},{"text":" — If the underlying tool's interface drifted, update Usage examples and Parameters table to match.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Was a workaround needed?","type":"text","marks":[{"type":"strong"}]},{"text":" — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Only update if the issue is real and reproducible — not speculative.","type":"text"}]}]},"metadata":{"date":"2026-06-05","name":"ascii-diagram-validator","author":"@skillopedia","source":{"stars":49,"repo_name":"cc-skills","origin_url":"https://github.com/terrylica/cc-skills/blob/HEAD/plugins/doc-tools/skills/ascii-diagram-validator/SKILL.md","repo_owner":"terrylica","body_sha256":"c35f05c3b4a07ebfde2cf74c16a5ce7e4f5cdd649bae424b7be533ef0afeee41","cluster_key":"453ee280b3bc55aec3e6ad453dff87cf93798a3561736bedf9cbbca09182c5d2","clean_bundle":{"format":"clean-skill-bundle-v1","source":"terrylica/cc-skills/plugins/doc-tools/skills/ascii-diagram-validator/SKILL.md","attachments":[{"id":"23516a16-e715-57a3-a0ad-500a68bcbb56","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/23516a16-e715-57a3-a0ad-500a68bcbb56/attachment.md","path":"references/DELIVERABLES_SUMMARY.md","size":11265,"sha256":"3d313962d5a3aba9e59deec81446d3e861b7b3f992ecebeb6a630ed6e030c510","contentType":"text/markdown; charset=utf-8"},{"id":"0dcc1cf1-48e4-58ee-8abf-bda8495fa3ae","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0dcc1cf1-48e4-58ee-8abf-bda8495fa3ae/attachment.md","path":"references/INTEGRATION_GUIDE.md","size":16714,"sha256":"96e29e7548843250a32a183f8567082dc4f4d03bfc52d8d2ec4f8782790708ef","contentType":"text/markdown; charset=utf-8"},{"id":"e97366eb-3ec2-57ed-80a4-c4909ba1102b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e97366eb-3ec2-57ed-80a4-c4909ba1102b/attachment.md","path":"references/SCRIPT_DESIGN_REPORT.md","size":17456,"sha256":"f041d346407643faa050f89717a2f4fa35d5160618afac5ac916b0657b4714fe","contentType":"text/markdown; charset=utf-8"},{"id":"887d4c3e-a1a0-5852-b606-7c7d229dd04c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/887d4c3e-a1a0-5852-b606-7c7d229dd04c/attachment.md","path":"references/evolution-log.md","size":683,"sha256":"4a865878655dfafc636da83a1f852faf836e85ad559722aa96c2db72623153b4","contentType":"text/markdown; charset=utf-8"},{"id":"400e6f0a-cba7-5556-bc91-81b00c772825","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/400e6f0a-cba7-5556-bc91-81b00c772825/attachment.py","path":"scripts/check_ascii_alignment.py","size":21871,"sha256":"3f9ae7fb9fd312ad761292a579485ee7bf7986f0482d22d8b0bf8eaf44fcb09c","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"e8a5e9e9cd471576fea7fd8bef0c396e41a185c75455136a277af8516c9c55bd","attachment_count":5,"text_attachments":5,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"plugins/doc-tools/skills/ascii-diagram-validator/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"clean-skills-v1","description":"Validate ASCII diagram alignment in markdown. TRIGGERS - diagram alignment, ASCII art, box-drawing diagrams.","allowed-tools":"Bash, Read, Glob"}},"renderedAt":1782981639968}

ASCII Diagram Validator Validate and fix alignment issues in ASCII box-drawing diagrams commonly used in architecture documentation, README files, and code comments. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Overview ASCII diagrams using box-drawing characters (─│┌┐└┘├┤┬┴┼ and double-line variants ═║╔╗╚╝╠╣╦╩╬) require precise column alignment. This skill provides: 1. Validation script - Detects misaligned characters with fi…