$npx -y skills add AlpacaLabsLLC/skills-for-architects --skill product-spec-pdf-parserExtract structured FF&E product specs from PDF files — price books, fact sheets, and spec sheets — into a standardized schedule. Use when the user shares a product PDF and asks to "parse this price book", extract specs, or import items from a spec sheet.
| 1 | # /product-spec-pdf-parser — PDF Product Spec Parser |
| 2 | |
| 3 | Extract structured FF&E data from product PDF files — price books, fact sheets, configurator sheets, and spec sheets. Uses PyMuPDF for text extraction and Claude's reasoning to parse wildly varying PDF layouts into a standardized schedule. |
| 4 | |
| 5 | ## Input |
| 6 | |
| 7 | The user provides PDFs in one of these ways: |
| 8 | |
| 9 | 1. **File paths** — one or more PDF file paths |
| 10 | 2. **Folder path** — a directory containing PDFs (will process all `.pdf` files) |
| 11 | 3. **Just invoked** — ask the user for file paths or a folder |
| 12 | |
| 13 | Also ask (or use defaults): |
| 14 | |
| 15 | - **Output destination** — Google Sheet, local CSV, or markdown (default: ask) |
| 16 | - **Variant depth** — `expand` (one row per variant/SKU, default) or `summarize` (comma-separated variants in one row) |
| 17 | |
| 18 | ## Output Schema |
| 19 | |
| 20 | Products are written to the **master Google Sheet** — the same 33-column schema used by all product skills, plus PDF-specific extra columns. When writing to CSV, use the same column order. |
| 21 | |
| 22 | Read `../../schema/product-schema.md` (relative to this SKILL.md) for the full column reference, field formats, and category vocabulary. Read `../../schema/sheet-conventions.md` for CRUD patterns with MCP tools. |
| 23 | |
| 24 | Skill-specific column values: |
| 25 | - **AG (Source):** `pdf-parser` |
| 26 | - **AF (Status):** `saved` |
| 27 | - **J (Link):** Blank (no URL for PDFs) |
| 28 | - **D (Thumbnail):** Blank (no image URL typically) |
| 29 | - **C (Vendor):** Blank (source is PDF, not a retailer) |
| 30 | - **V (Sale Price):** Blank (PDFs don't have sale prices) |
| 31 | - **AC (Image URL):** Blank (no image from PDF) |
| 32 | |
| 33 | ### PDF-specific data in Notes (col AE) |
| 34 | |
| 35 | PDFs contain fields that don't have dedicated master columns. Append these to Notes using `|` as delimiter: |
| 36 | |
| 37 | - **Variant**: `Variant: Diamond, Black` |
| 38 | - **Price Adder**: `Price adder: +$130 (PostureFit SL)` |
| 39 | - **Country of Origin**: `Origin: Sweden` |
| 40 | - **Source File**: `Source: alphabeta-fact-sheet.pdf` |
| 41 | |
| 42 | Example Notes cell: `Variant: Diamond, Black | Origin: Sweden | Source: alphabeta-fact-sheet.pdf` |
| 43 | |
| 44 | ## Variant Handling |
| 45 | |
| 46 | Different PDF types require different approaches: |
| 47 | |
| 48 | ### Fact sheets with SKUs (e.g., Alphabeta lamp) |
| 49 | - **One row per SKU.** Each shade shape × color = one row. |
| 50 | - Product Name stays the same across rows. Variant describes the distinguishing attributes. |
| 51 | - Example: "Alphabeta Floor Lamp" / Variant: "Diamond, Black" / SKU: "..." |
| 52 | |
| 53 | ### Fact sheets with upholstery/finish combos (e.g., Puffy lounge chair) |
| 54 | - **One row per upholstery option.** Frame finish goes in Colors/Finishes. |
| 55 | - Distinct products (chair + ottoman) each get their own set of rows. |
| 56 | - Example: "Puffy Lounge Chair" / Variant: "Traffic Red" / Colors/Finishes: "Chrome frame" |
| 57 | |
| 58 | ### Price books / configurators (e.g., Aeron price book) |
| 59 | - **One row per distinct product type** (e.g., Work Chair, Stool, Side Chair). |
| 60 | - Base configuration in main fields. Summarize configuration options — do NOT explode every permutation. |
| 61 | - Use Price Adder for incremental costs of add-ons or upgrades. |
| 62 | - Example: "Aeron Chair" / Variant: "Size B, Graphite" / List Price: 1395.00 / Price Adder: 130.00 (PostureFit SL) |
| 63 | |
| 64 | ### `expand` vs `summarize` mode |
| 65 | - **expand** (default): One row per variant, SKU, or distinct option. Best for procurement and ordering. |
| 66 | - **summarize**: One row per product. Colors/Finishes and Variant are comma-separated lists. Best for quick reference. |
| 67 | |
| 68 | ## Workflow |
| 69 | |
| 70 | ### Step 1: Get input |
| 71 | |
| 72 | Parse the user's input to identify PDF file(s) and output preferences. |
| 73 | |
| 74 | - If given a folder, list all `.pdf` files and report count |
| 75 | - If no PDFs found or path is invalid, ask the user |
| 76 | - Confirm variant depth — default to `expand` unless the user says otherwise |
| 77 | - Report: "Found N PDF(s) to process." |
| 78 | |
| 79 | ### Step 2: Extract text from PDF |
| 80 | |
| 81 | Use PyMuPDF (fitz) to extract text from each PDF. Run this Python script via Bash: |
| 82 | |
| 83 | ```python |
| 84 | import fitz |
| 85 | import sys |
| 86 | import json |
| 87 | |
| 88 | pdf_path = sys.argv[1] |
| 89 | doc = fitz.open(pdf_path) |
| 90 | pages = [] |
| 91 | for i, page in enumerate(doc): |
| 92 | text = page.get_text() |
| 93 | pages.append({"page": i + 1, "text": text}) |
| 94 | doc.close() |
| 95 | |
| 96 | print(json.dumps({"filename": pdf_path.split("/")[-1], "total_pages": len(pages), "pages": pages})) |
| 97 | ``` |
| 98 | |
| 99 | For each PDF, extract all pages and save the JSON output. |
| 100 | |
| 101 | ### Step 3: Parse products with Claude |
| 102 | |
| 103 | Read the extracted text and identify all products, variants, and specifications. This is the core intelligence step — Claude reasons over the text to structure it. |
| 104 | |
| 105 | **For small PDFs (≤20 pages):** Process all pages at once. |
| 106 | |
| 107 | **For large PDFs (>20 pages):** Process in chunks of 10 pages at a |