$npx -y skills add dleerdefi/claude-code-construction --skill spec-splitterSplit a bound project manual PDF into individual spec section PDFs and extract searchable text. Triggers: 'split specs', 'break up the project manual', 'separate spec sections', 'extract spec text'. Prerequisite for /submittal-log-generator.
| 1 | # Spec Splitter |
| 2 | |
| 3 | Two functions for specification processing: |
| 4 | |
| 5 | 1. **Split**: Break a bound project manual PDF into individual spec section PDFs — navigable files the project team can use directly |
| 6 | 2. **Extract**: Pull searchable text from each section PDF into persistent `.txt` files — enables downstream skills (submittal-log-generator, spec-parser) to work from text without re-extracting from PDFs |
| 7 | |
| 8 | ## Pipeline Position |
| 9 | Run after `/project-setup` identifies bound spec manuals. Produces split PDFs, `spec_index.yaml`, and extracted text consumed by `/submittal-log-generator` and `/code-researcher`. |
| 10 | |
| 11 | Either function can run independently. For example, specs may already be split but text has not yet been extracted. |
| 12 | |
| 13 | ## Workflow |
| 14 | |
| 15 | ``` |
| 16 | Spec Split Progress: |
| 17 | - [ ] Step 1: Check current state (split? text extracted?) |
| 18 | - [ ] Step 2: Discover Specifications directory |
| 19 | - [ ] Step 3: Find ALL spec PDFs (bound manuals) |
| 20 | - [ ] Step 4-5: Split PDF into individual section files |
| 21 | - [ ] Step 6: Write spec index |
| 22 | - [ ] Step 7: Extract text from all sections |
| 23 | - [ ] Step 8: Repair degraded/poor text quality |
| 24 | - [ ] Step 9: Write graph entry (AgentCM only) |
| 25 | ``` |
| 26 | |
| 27 | ### Step 1: Check Current State |
| 28 | |
| 29 | Check what already exists: |
| 30 | |
| 31 | **Split PDFs present?** |
| 32 | - Look for individual spec section PDFs with CSI section numbers in filenames (e.g., `03 30 00 - Cast-in-Place Concrete.pdf`) |
| 33 | - Check for `spec_index.yaml` |
| 34 | - If found, report count and skip to Step 7 (text extraction) |
| 35 | |
| 36 | **Text already extracted?** |
| 37 | - Check `.construction/spec_text/manifest.json` |
| 38 | - If manifest exists and covers all sections, report and skip Step 7 |
| 39 | |
| 40 | ### Step 2: Discover Specifications Directory |
| 41 | |
| 42 | Determine where split spec PDFs should go. Search for an existing Specifications directory (case-insensitive): |
| 43 | 1. `02 - Specifications/` (numbered project folder convention) |
| 44 | 2. `Specifications/` |
| 45 | 3. Any folder with "specification" in the name |
| 46 | |
| 47 | **Output directory resolution:** |
| 48 | - If Specifications directory found → output to `{specs_dir}/Specification Sections/` |
| 49 | - If not found → output to `Specification Sections/` in project root |
| 50 | |
| 51 | ### Step 3: Find ALL Spec PDFs |
| 52 | |
| 53 | Search the project directory for ALL PDFs that are specifications. Many projects have multiple spec PDFs: |
| 54 | - **Multi-volume**: Volume 1.pdf, Volume 2.pdf (split by CSI division range) |
| 55 | - **Single bound manual**: one large PDF with all sections |
| 56 | - **Attachment-based**: Attachment-E-Specs.pdf (government projects) |
| 57 | |
| 58 | Search in: |
| 59 | - The Specifications directory discovered in Step 2 |
| 60 | - The project root (some projects have no folder structure) |
| 61 | - Look for PDFs > 1MB with keywords: "spec", "manual", "volume", "attachment" + spec-related terms |
| 62 | |
| 63 | Process EACH PDF found. All split sections go to the same output directory. |
| 64 | |
| 65 | If the user specifies a single file (`/spec-splitter path/to/specific-volume.pdf`), process only that file. |
| 66 | |
| 67 | ### Steps 4-6: Split and Index |
| 68 | |
| 69 | Run the split script with the resolved output directory: |
| 70 | |
| 71 | ```bash |
| 72 | ${CLAUDE_SKILL_DIR}/../../bin/construction-python ${CLAUDE_SKILL_DIR}/scripts/split_spec_manual.py \ |
| 73 | "{project_manual.pdf}" \ |
| 74 | --output-dir "{resolved_spec_sections_dir}" |
| 75 | ``` |
| 76 | |
| 77 | The script: |
| 78 | 1. Scans ALL pages for `SECTION XX XX XX` headers to find exact page boundaries — this is the primary method and does NOT depend on a Table of Contents |
| 79 | 2. Scans all pages for Table of Contents entries to enrich section titles (optional, best-effort) |
| 80 | 3. For sections without ToC titles, extracts titles directly from the section header page |
| 81 | 4. Splits into individual PDFs named `{section_number} - {SECTION TITLE}.pdf` |
| 82 | 5. Writes `spec_index.yaml` with section metadata |
| 83 | |
| 84 | **ToC edge cases handled:** |
| 85 | - **ToC located deep in the document** (e.g., page 60+): Common when front matter (transmittals, addenda) precedes the project manual. The script scans all pages, not just the first few. |
| 86 | - **No ToC at all**: Section boundaries are found by scanning every page for `SECTION` headers. Titles are extracted directly from each section's title page. The split still succeeds — titles may be slightly less polished than ToC-enriched versions. |
| 87 | |
| 88 | ### Step 7: Extract Text |
| 89 | |
| 90 | After splitting (or if specs are already split), extract searchable text from every section: |
| 91 | |
| 92 | ```bash |
| 93 | ${CLAUDE_SKILL_DIR}/../../bin/construction-python ${CLAUDE_SKILL_DIR}/scripts/extract_spec_text.py \ |
| 94 | --specs-dir "{resolved_spec_sections_dir}" \ |
| 95 | --output-dir ".construction/spec_text" |
| 96 | ``` |
| 97 | |
| 98 | The script: |
| 99 | - Extracts text from each section PDF via pdfplumber |
| 100 | - Assesses extraction quality (GOOD / DEGRADED / POOR) |
| 101 | - Writes one `.txt` file per section to `.construction/spec_text/` |
| 102 | - Writes `manifest.json` with quality metadata per sec |