Extract data from subcontractor bid PDFs and produce a comparison spreadsheet. Feeds into /bid-evaluator. Triggers: 'tabulate bids', 'bid comparison', 'compare bids', 'buyout analysis', 'bid tab'.
Processes multiple subcontractor bid PDFs for a scope of work and produces an Excel comparison workbook. Extracts each bid's data as-submitted — the engineer handles normalization and alignment after reviewing discrepancies and contacting subcontractors as needed.
[MATH ERROR: line items sum to $X, bid states $Y].Ask the user for:
If project context is available (.construction/ directory), read project.yaml for project name/number to include in the workbook header.
THIS SKILL → /bid-evaluator → user confirms → /subcontract-writer
This skill is the entry point of the bid pipeline. It produces the tabulated data that /bid-evaluator consumes for analysis.
Bid Tabulation Progress:
- [ ] Step 1: Gather inputs (bid PDFs, scope)
- [ ] Step 2: Read first bid to discover structure
- [ ] Step 3: Process all bids
- [ ] Step 4: Generate comparison Excel
- [ ] Step 5: Present summary to engineer
- [ ] Step 6: Write graph entry
Open the first bid PDF to understand what data is available:
Try pdfplumber first. If text extraction returns meaningful content (>50 chars per page), use text mode. Otherwise fall back to vision.
Vision fallback for scanned bids:
${CLAUDE_SKILL_DIR}/../../bin/construction-python ${CLAUDE_SKILL_DIR}/../../scripts/pdf/rasterize_page.py BID.pdf 1 --dpi 200 --output bid_page.png
From the first bid, identify what data fields are present. Common bid data:
# Bidder info
company_name: ""
contact_name: ""
contact_phone: ""
contact_email: ""
bid_date: ""
bid_validity_period: ""
# Financial
base_bid_amount: ""
line_items: # Every line item as an object:
- spec_section: "" # CSI section if shown (e.g., "09 65 19")
description: "" # Original description verbatim
qty: null # Quantity (numeric or null if lump sum)
unit: "" # Unit as written (SF, LF, EA, LS, etc.)
unit_price: null # Per-unit cost (numeric — extract or calculate)
extended_price: null # Line total (qty × unit_price, or lump sum amount)
notes: "" # Flags, clarifications
Edit PDFs with natural-language instructions using the nano-pdf CLI.