From buildbrain
Reference manual for BuildBrain CLI tools (ifc_extract.py and pdf_extract.py). Shows all commands, flags, output formats, and type shorthands. Use this as a reference when working with IFC or PDF data.
How this skill is triggered — by the user, by Claude, or both
Slash command
/buildbrain:cli-toolsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
This is the reference manual for the two CLI tools that power BuildBrain. Other skills (`/scan`, `/ifc-extract`, `/pdf-extract`, `/cross-validate`, `/report`) use these tools — refer here for command syntax and output formats.
This is the reference manual for the two CLI tools that power BuildBrain. Other skills (/scan, /ifc-extract, /pdf-extract, /cross-validate, /report) use these tools — refer here for command syntax and output formats.
The scripts are bundled with this plugin at scripts/ifc_extract.py and scripts/pdf_extract.py relative to this skill's directory.
The CLI scripts are located in this skill's scripts/ directory. To get the absolute path:
# The scripts directory is relative to this SKILL.md file
# From the plugin root:
ls skills/cli-tools/scripts/
All commands below use python <path-to-script> — replace with the actual path to the scripts directory.
Wraps IfcOpenShell. Queries IFC building models and returns structured JSON.
summary — Scan entire modelpython <scripts>/ifc_extract.py <file.ifc> summary
Returns: element type counts, storeys, schema version, file size, parse time.
list <type> — List all elements of a typepython <scripts>/ifc_extract.py <file.ifc> list <element_type>
Returns: all elements with guid, name, type_name, storey, properties, quantities, material.
props <guid> — Detailed properties for one elementpython <scripts>/ifc_extract.py <file.ifc> props <guid>
Returns: full property sets, quantity sets, material, and metadata for a single element.
query <type> — Filter elements by propertypython <scripts>/ifc_extract.py <file.ifc> query <type> --property <Pset.Property> --value <value>
python <scripts>/ifc_extract.py <file.ifc> query <type> --property <Pset.Property> --not-null
Examples:
query door --property Pset_DoorCommon.FireRating --not-nullquery wall --property Pset_WallCommon.IsExternal --value truequery door --property Pset_DoorCommon.FireRating --value nullquantities <type> — Pre-computed aggregatespython <scripts>/ifc_extract.py <file.ifc> quantities <type>
python <scripts>/ifc_extract.py <file.ifc> quantities <type> --group-by storey
python <scripts>/ifc_extract.py <file.ifc> quantities <type> --group-by type
Returns: totals (count, area, volume), grouped breakdowns, source tracking (Qto_ vs geometry computed).
Use this instead of computing numbers yourself — LLMs never do arithmetic.
validate — Data quality checkpython <scripts>/ifc_extract.py <file.ifc> validate
Returns: issues (missing psets, proxy elements, orphans) and completeness metrics per element type.
export <type> — CSV exportpython <scripts>/ifc_extract.py <file.ifc> export <type> --output <file.csv>
| Flag | Works with | Effect |
|---|---|---|
--save | All commands | Write output to output/ifc_<type>_<timestamp>.json |
--limit N | list, query, export | Max elements to return |
--offset N | list, query, export | Skip first N elements |
--fields f1,f2 | list, query, export | Only include specific fields |
--compact | list, query, export | Return only guid, name, type, storey (no properties) |
| Shorthand | IFC Type | Also accepts |
|---|---|---|
door | IfcDoor | |
window | IfcWindow | |
wall | IfcWall | |
slab | IfcSlab | floor |
roof | IfcRoof | |
column | IfcColumn | |
beam | IfcBeam | |
stair | IfcStair | |
railing | IfcRailing | |
space | IfcSpace | room |
covering | IfcCovering |
Any unrecognised type is passed through as-is (e.g., IfcFurniture, IfcBuildingElementProxy).
| User says | CLI command |
|---|---|
| "fire-rated doors" | query door --property Pset_DoorCommon.FireRating --not-null |
| "doors without fire rating" | query door --property Pset_DoorCommon.FireRating --value null |
| "external doors" | query door --property Pset_DoorCommon.IsExternal --value true |
| "security-rated doors" | query door --property Pset_DoorCommon.SecurityRating --not-null |
| "door count" / "how many doors" | quantities door |
| "doors per level" | quantities door --group-by storey |
| User says | CLI command |
|---|---|
| "external windows" | query window --property Pset_WindowCommon.IsExternal --value true |
| "acoustic-rated windows" | query window --property Pset_WindowCommon.AcousticRating --not-null |
| "total window area" | quantities window |
| "windows per level" | quantities window --group-by storey |
| User says | CLI command |
|---|---|
| "external walls" | query wall --property Pset_WallCommon.IsExternal --value true |
| "internal walls" | query wall --property Pset_WallCommon.IsExternal --value false |
| "load-bearing walls" | query wall --property Pset_WallCommon.LoadBearing --value true |
| "fire-rated walls" | query wall --property Pset_WallCommon.FireRating --not-null |
| "wall areas per level" | quantities wall --group-by storey |
| User says | CLI command |
|---|---|
| "load-bearing slabs" | query slab --property Pset_SlabCommon.LoadBearing --value true |
| "floor areas per level" | quantities slab --group-by storey |
| User says | CLI command |
|---|---|
| "fire-rated roofs" | query roof --property Pset_RoofCommon.FireRating --not-null |
| "total roof area" | quantities roof |
| User says | CLI command |
|---|---|
| "load-bearing columns" | query column --property Pset_ColumnCommon.LoadBearing --value true |
| "columns per level" | quantities column --group-by storey |
| User says | CLI command |
|---|---|
| "load-bearing beams" | query beam --property Pset_BeamCommon.LoadBearing --value true |
| "beam spans" | list beam (check Span in Pset_BeamCommon) |
| User says | CLI command |
|---|---|
| "fire-rated stairs" | query stair --property Pset_StairCommon.FireRating --not-null |
| "stair dimensions" | list stair (check NumberOfRiser, RiserHeight, TreadLength) |
Note: Stair quantities are on child IfcStairFlight via Qto_StairFlightBaseQuantities.
| User says | CLI command |
|---|---|
| "public spaces" | query space --property Pset_SpaceCommon.PubliclyAccessible --value true |
| "room areas" | list space (areas in Qto_SpaceBaseQuantities, not Pset) |
| "gross planned area" | query space --property Pset_SpaceCommon.GrossPlannedArea --not-null |
| User says | CLI command |
|---|---|
| "external railings" | query railing --property Pset_RailingCommon.IsExternal --value true |
| "railing heights" | list railing (check Height in Pset_RailingCommon) |
| User says | CLI command |
|---|---|
| "what's in this model" | summary |
| "data quality" | validate |
| "show element [GUID]" | props <guid> |
| "export to CSV" | export <type> --output output/<type>.csv |
| "proxy elements" | list IfcBuildingElementProxy |
Wraps pdfplumber. Extracts text, tables, and schedules from PDF construction documents.
schedules — Auto-detect schedule tablespython <scripts>/pdf_extract.py <file.pdf> schedules
Scans every page for known schedule column headers (door, window, finish). Best starting point.
search "keyword" — Find pages containing a keywordpython <scripts>/pdf_extract.py <file.pdf> search "door schedule"
python <scripts>/pdf_extract.py <file.pdf> search "fire rating"
Returns matching pages with context snippets. Use this to locate content before extracting.
tables — Extract tables from pagespython <scripts>/pdf_extract.py <file.pdf> tables
python <scripts>/pdf_extract.py <file.pdf> tables --pages 12-15
python <scripts>/pdf_extract.py <file.pdf> tables --pages 3,7,12-14
text — Extract raw text from pagespython <scripts>/pdf_extract.py <file.pdf> text
python <scripts>/pdf_extract.py <file.pdf> text --pages 1-5
| Flag | Works with | Effect |
|---|---|---|
--save | All commands | Write output to output/pdf_<command>_<timestamp>.json |
--pages | text, tables | Page range: 1-5, 12, 1,3,5-8 |
# What schedules are in this PDF?
python <scripts>/pdf_extract.py <file.pdf> schedules --save
# Find the door schedule
python <scripts>/pdf_extract.py <file.pdf> search "door schedule" --save
python <scripts>/pdf_extract.py <file.pdf> tables --pages <matched_pages> --save
# Extract everything from page 5
python <scripts>/pdf_extract.py <file.pdf> text --pages 5 --save
python <scripts>/pdf_extract.py <file.pdf> tables --pages 5 --save
Both tools return structured JSON errors:
{"error": true, "error_type": "file_not_found", "message": "File not found: nonexistent.ifc"}
Exit codes: 0 = success, 1 = failure, 2 = invalid arguments.
quantities for counts, areas, volumes. Never sum values from list output.--save so results persist for /cross-validate and /report.data/ to find files.Guides reception of code review feedback: verify before implementing, avoid performative agreement, push back with technical reasoning when needed.
Design banners for social media, ads, website heroes, and print with multiple art direction options and AI-generated visuals.
npx claudepluginhub thebrownproject/buildbrain