@ifc-lite/cli 0.34.0 → 0.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/anonymize.d.ts.map +1 -1
  3. package/dist/commands/anonymize.js +1 -0
  4. package/dist/commands/anonymize.js.map +1 -1
  5. package/dist/commands/check.d.ts +2 -0
  6. package/dist/commands/check.d.ts.map +1 -0
  7. package/dist/commands/check.js +119 -0
  8. package/dist/commands/check.js.map +1 -0
  9. package/dist/commands/convert.d.ts.map +1 -1
  10. package/dist/commands/convert.js +28 -8
  11. package/dist/commands/convert.js.map +1 -1
  12. package/dist/commands/create.d.ts.map +1 -1
  13. package/dist/commands/create.js +6 -0
  14. package/dist/commands/create.js.map +1 -1
  15. package/dist/commands/delivery-checks-rules.d.ts +37 -0
  16. package/dist/commands/delivery-checks-rules.d.ts.map +1 -0
  17. package/dist/commands/delivery-checks-rules.js +76 -0
  18. package/dist/commands/delivery-checks-rules.js.map +1 -0
  19. package/dist/commands/delivery-checks.d.ts +12 -0
  20. package/dist/commands/delivery-checks.d.ts.map +1 -1
  21. package/dist/commands/delivery-checks.js +16 -5
  22. package/dist/commands/delivery-checks.js.map +1 -1
  23. package/dist/commands/delivery-recipe.d.ts +13 -2
  24. package/dist/commands/delivery-recipe.d.ts.map +1 -1
  25. package/dist/commands/delivery-recipe.js +29 -17
  26. package/dist/commands/delivery-recipe.js.map +1 -1
  27. package/dist/commands/delivery-report.d.ts +2 -2
  28. package/dist/commands/delivery-report.d.ts.map +1 -1
  29. package/dist/commands/delivery-report.js +14 -4
  30. package/dist/commands/delivery-report.js.map +1 -1
  31. package/dist/commands/delivery.d.ts.map +1 -1
  32. package/dist/commands/delivery.js +17 -5
  33. package/dist/commands/delivery.js.map +1 -1
  34. package/dist/commands/diff-engine.js +1 -0
  35. package/dist/commands/diff-engine.js.map +1 -1
  36. package/dist/commands/diff-scope.d.ts.map +1 -1
  37. package/dist/commands/diff-scope.js +2 -0
  38. package/dist/commands/diff-scope.js.map +1 -1
  39. package/dist/commands/diff.d.ts.map +1 -1
  40. package/dist/commands/diff.js +2 -0
  41. package/dist/commands/diff.js.map +1 -1
  42. package/dist/commands/export.d.ts.map +1 -1
  43. package/dist/commands/export.js +13 -0
  44. package/dist/commands/export.js.map +1 -1
  45. package/dist/commands/ext.js +26 -10
  46. package/dist/commands/ext.js.map +1 -1
  47. package/dist/commands/extract-entities.d.ts.map +1 -1
  48. package/dist/commands/extract-entities.js +26 -8
  49. package/dist/commands/extract-entities.js.map +1 -1
  50. package/dist/commands/flow-tracking.d.ts +20 -0
  51. package/dist/commands/flow-tracking.d.ts.map +1 -0
  52. package/dist/commands/flow-tracking.js +86 -0
  53. package/dist/commands/flow-tracking.js.map +1 -0
  54. package/dist/commands/flow.d.ts +2 -0
  55. package/dist/commands/flow.d.ts.map +1 -0
  56. package/dist/commands/flow.js +229 -0
  57. package/dist/commands/flow.js.map +1 -0
  58. package/dist/commands/gym/channels.d.ts.map +1 -1
  59. package/dist/commands/gym/channels.js +10 -2
  60. package/dist/commands/gym/channels.js.map +1 -1
  61. package/dist/commands/gym.d.ts.map +1 -1
  62. package/dist/commands/gym.js +5 -1
  63. package/dist/commands/gym.js.map +1 -1
  64. package/dist/commands/ids.d.ts.map +1 -1
  65. package/dist/commands/ids.js +36 -3
  66. package/dist/commands/ids.js.map +1 -1
  67. package/dist/commands/info.d.ts.map +1 -1
  68. package/dist/commands/info.js +20 -5
  69. package/dist/commands/info.js.map +1 -1
  70. package/dist/commands/layer-publish.d.ts.map +1 -1
  71. package/dist/commands/layer-publish.js +6 -0
  72. package/dist/commands/layer-publish.js.map +1 -1
  73. package/dist/commands/lod.d.ts.map +1 -1
  74. package/dist/commands/lod.js +4 -1
  75. package/dist/commands/lod.js.map +1 -1
  76. package/dist/commands/mutate-step-record.d.ts +25 -1
  77. package/dist/commands/mutate-step-record.d.ts.map +1 -1
  78. package/dist/commands/mutate-step-record.js +17 -22
  79. package/dist/commands/mutate-step-record.js.map +1 -1
  80. package/dist/commands/mutate.d.ts +2 -1
  81. package/dist/commands/mutate.d.ts.map +1 -1
  82. package/dist/commands/mutate.js +27 -2
  83. package/dist/commands/mutate.js.map +1 -1
  84. package/dist/commands/rekey.d.ts.map +1 -1
  85. package/dist/commands/rekey.js +22 -1
  86. package/dist/commands/rekey.js.map +1 -1
  87. package/dist/commands/simplify.d.ts.map +1 -1
  88. package/dist/commands/simplify.js +4 -1
  89. package/dist/commands/simplify.js.map +1 -1
  90. package/dist/commands/validate.d.ts +5 -14
  91. package/dist/commands/validate.d.ts.map +1 -1
  92. package/dist/commands/validate.js +11 -14
  93. package/dist/commands/validate.js.map +1 -1
  94. package/dist/headless-backend-store-authoring.d.ts +28 -0
  95. package/dist/headless-backend-store-authoring.d.ts.map +1 -0
  96. package/dist/headless-backend-store-authoring.js +34 -0
  97. package/dist/headless-backend-store-authoring.js.map +1 -0
  98. package/dist/headless-backend.d.ts +7 -0
  99. package/dist/headless-backend.d.ts.map +1 -1
  100. package/dist/headless-backend.js +59 -55
  101. package/dist/headless-backend.js.map +1 -1
  102. package/dist/help.d.ts +22 -0
  103. package/dist/help.d.ts.map +1 -0
  104. package/dist/help.js +260 -0
  105. package/dist/help.js.map +1 -0
  106. package/dist/index.js +41 -189
  107. package/dist/index.js.map +1 -1
  108. package/dist/loader.d.ts +2 -0
  109. package/dist/loader.d.ts.map +1 -1
  110. package/dist/loader.js +30 -1
  111. package/dist/loader.js.map +1 -1
  112. package/dist/out-flag-commands.d.ts +12 -0
  113. package/dist/out-flag-commands.d.ts.map +1 -0
  114. package/dist/out-flag-commands.js +19 -0
  115. package/dist/out-flag-commands.js.map +1 -0
  116. package/dist/query-overlay-relations.js +1 -1
  117. package/dist/query-overlay-relations.js.map +1 -1
  118. package/dist/query-overlay.d.ts +0 -2
  119. package/dist/query-overlay.d.ts.map +1 -1
  120. package/dist/query-overlay.js +0 -15
  121. package/dist/query-overlay.js.map +1 -1
  122. package/package.json +25 -21
  123. package/dist/version.d.ts +0 -14
  124. package/dist/version.d.ts.map +0 -1
  125. package/dist/version.js +0 -38
  126. package/dist/version.js.map +0 -1
package/dist/help.js ADDED
@@ -0,0 +1,260 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * The CLI's `--help` text. Split out of `index.ts` (module-size ratchet,
6
+ * #5138 PR 7b added the `check` command line and pushed `index.ts` over
7
+ * 400 lines) — pure data, no logic, so it carries no behaviour of its own.
8
+ */
9
+ export function buildHelp(version) {
10
+ return `
11
+ ifc-lite v${version} — BIM toolkit for the terminal
12
+
13
+ Usage: ifc-lite <command> [options]
14
+
15
+ Commands:
16
+ info <file.ifc> Model summary (schema, entities, storeys)
17
+ query <file.ifc> [--type T] [--json] Query entities by type/properties/quantities
18
+ [--select "IfcWall, Pset_WallCommon.FireRating=2HR"] IfcOpenShell-style selector (classes union with --type; properties AND with --where)
19
+ props <file.ifc> --id <N> All properties for a single entity
20
+ export <file.ifc> --format csv|json|ifc|obj|gltf|glb|jsonld|step|ifcx|usd|hbjson|dfjson Export data / geometry / energy model
21
+ schedule <file.ifc> --type T --columns "H=path,..." Tabular schedule of one class (csv/json/md/html)
22
+ [--preset door|window|space|wall|material-takeoff] default type+columns (flags override)
23
+ [--where PsetName.Prop=Value] [--format csv|json|md|html] path = attr | Pset.Prop | Qto.Qty
24
+ [--sort "Header[:asc|desc],..."] multi-key row sort by column HEADER (numbers numeric, nulls last)
25
+ [--group-by "Header,..."] contiguous groups, ordered by group key (asc, or --sort's dir)
26
+ [--subtotals "count|sum:H|avg:H|min:H|max:H,..."] subtotal row per group + grand total
27
+ (without --group-by: grand total only; CSV/md label the group column, JSON marks __row)
28
+ [--spec spec.json] load a saved schedule definition (beats --preset; an explicit flag beats both)
29
+ [--save spec.json] persist this invocation's resolved definition for --spec reuse
30
+ diagnose-geometry <file.ifc> [--json] CSG / opening diagnostics (failures, classification)
31
+ [--product ID|GUID] [--type T] Filter worst-hosts detail to one product/type
32
+ extract-entities <file.ifc> --out F Isolate entities into a small, viewable standalone IFC
33
+ [--product ID|GUID] [--storey S] [--detect] [--view] by GUID/type/storey or auto-triage
34
+ anonymize <file.ifc> --out F Export selected objects + context as an anonymized IFC
35
+ [--id N,...] [--guid G,...] [--type T] [--storey S]
36
+ [--keep-psets] [--keep-names] [--keep-other-names] [--keep-currency]
37
+ [--no-rel-voids-element] [--no-rel-fills-element] [--no-rel-defines-by-type]
38
+ [--no-rel-associates-material] [--no-rel-aggregates] [--no-rel-nests]
39
+ [--connect-depth N] [--guid-map F] [--json]
40
+ ids <file.ifc> <rules.ids> Validate against IDS rules
41
+ bcf <create|list|add-comment> Work with BCF collaboration files
42
+ clash <file.ifc> [--matrix] [--bcf F] Detect geometric clashes between elements
43
+ create <type> [options] --out F Create IFC elements (29 types)
44
+ eval <file.ifc> "<expression>" Evaluate SDK expression
45
+ run <script.js> <file.ifc> Execute a script against model
46
+ schema Dump SDK API schema (for LLM tools)
47
+ merge <f1.ifc> <f2.ifc> --out F Merge multiple IFC files
48
+ convert <file.ifc> --schema VER --out F Convert between IFC schema versions
49
+ diff <f1.ifc> <f2.ifc> Compare two IFC files
50
+ [--by-content] [--identity-out F] [--identity-in F] Match re-GUIDed elements by content; save/replay the identity map
51
+ [--geometry] [--split-merge] [--successors] Wasm mesh pass: world geometry hashes/boxes/volumes; split/merge + successor claims
52
+ [--lineage-out F] [--lineage-in F] [--accept F] [--key-from Tag|Pset.Prop] Lineage for rekeying external data; authored key
53
+ rekey <table.csv|json> --lineage F --out F Carry a table keyed on old element keys across a revision
54
+ validate <file.ifc> Structural validation checks
55
+ bsdd <class|search|psets|qsets> <arg> buildingSMART Data Dictionary lookup
56
+ stats <file.ifc> Auto-calculated model KPIs and health check
57
+ mutate <file.ifc> --id N --set P=V --out F Modify properties/attributes and save
58
+ generate-spaces <file.ifc> --out F Derive IfcSpace from walls (slab/roof-aware height)
59
+ ask <file.ifc> "<question>" Natural language BIM queries
60
+ view <file.ifc> [--port N] Interactive 3D viewer in browser
61
+ analyze <file.ifc> --viewer <port> Query + visualize analysis results
62
+ lod <file.ifc> --level 0|1 Generate lightweight LOD artifacts
63
+ simplify <file.ifc> --out F [--level 1..5] [--ids 1,2,...] [--json] Demesher: simplify meshes, write lighter IFC
64
+ mcp <file.ifc> [--transport stdio|http] Start an MCP server bound to one or more IFC files
65
+ ext validate <path>|init <dir> Manage IFClite extensions (Phase 0 — validate, init)
66
+ layer <publish|diff|merge|log|bake|...> Layered change tracking over a local store (.ifc-lite/)
67
+ ref <list|create|move|protect> Manage named refs in the layer store
68
+ gym --model <file.ifc> | --seed <n> reset/step/reward environment loop (JSONL over stdin/stdout)
69
+ delivery <recipe.json> [--json] [--out F] [--html F] Repeatable delivery check (structural + IDS + rule sets) from a saved recipe
70
+ recipe: {"models":["m.ifc"],"structural":true,"ids":["rules.ids"],"rules":["checks.rules.json"]}, paths relative to the recipe file
71
+ check <model.ifc>... --rules <file.rules.json> Run a .rules.json information-validation rule set (same engine as the viewer)
72
+ [--format json|table] [--fail-on error|warning] exit 0 all pass / 1 any fail / 2 rule error or unreadable input
73
+ flow <run|describe|validate> <graph.flow.json> [<file.ifc>] [--input k=v] [--out F] Evaluate a node graph headlessly
74
+
75
+ Options:
76
+ --help, -h Show help
77
+ --version, -v Show version
78
+ --json Output as JSON (machine-readable)
79
+ --verbose Show parser + geometry diagnostics (stderr)
80
+ --quiet Errors only
81
+ --debug Verbose + stack traces on error
82
+ --log-level <level> error|warn|info|debug (explicit wins over shorthands)
83
+
84
+ Examples:
85
+ ifc-lite info model.ifc
86
+ ifc-lite query model.ifc --type IfcWall --json
87
+ ifc-lite query model.ifc --type IfcDoor --props --limit 5
88
+ ifc-lite query model.ifc --type IfcWall --materials --classifications --json
89
+ ifc-lite query model.ifc --type IfcWall --all --json
90
+ ifc-lite query model.ifc --type IfcWall --quantity-names
91
+ ifc-lite query model.ifc --type IfcWall --sum GrossSideArea
92
+ ifc-lite query model.ifc --type IfcWall --group-by material --json
93
+ ifc-lite query model.ifc --spatial --summary
94
+ ifc-lite query model.ifc --spatial
95
+ ifc-lite props model.ifc --id 42
96
+ ifc-lite export model.ifc --format csv --type IfcWall --columns Name,Type,GlobalId
97
+ ifc-lite export model.ifc --format json --type IfcWall,IfcDoor
98
+ ifc-lite schedule model.ifc --type IfcDoor --columns "Name=Name, Mark=Pset_DoorCommon.Reference"
99
+ ifc-lite schedule model.ifc --type IfcWall --columns "Name,Qto_WallBaseQuantities.NetVolume" --where Pset_WallCommon.IsExternal=true --format json
100
+ ifc-lite schedule model.ifc --type IfcDoor --columns "Name=Name, Fire=Pset_DoorCommon.FireRating, Area=Qto_DoorBaseQuantities.Area" --group-by Fire --sort "Area:desc" --subtotals "count, sum:Area"
101
+ ifc-lite schedule model.ifc --preset door
102
+ ifc-lite schedule model.ifc --preset material-takeoff --format json
103
+ ifc-lite schedule model.ifc --preset door --format md
104
+ ifc-lite schedule model.ifc --preset door --format html > doors.html
105
+ ifc-lite schedule model.ifc --preset door --save door-schedule.json
106
+ ifc-lite schedule model.ifc --spec door-schedule.json --format json
107
+ ifc-lite diagnose-geometry model.ifc --json
108
+ ifc-lite diagnose-geometry model.ifc --type IfcWall
109
+ ifc-lite diagnose-geometry model.ifc --product 0YvCT2_$X3_xJG3rzD8L_8
110
+ ifc-lite ids model.ifc requirements.ids --json
111
+ ifc-lite bcf create --title "Missing door" --out topic.bcf
112
+ ifc-lite clash model.ifc --matrix --json
113
+ ifc-lite clash model.ifc --a "IfcDuct*|IfcPipe*" --b "IfcWall*" --mode clearance --clearance 0.05
114
+ ifc-lite clash model.ifc --matrix --bcf clashes.bcfzip
115
+ ifc-lite create wall --height 3 --thickness 0.2 --start 0,0,0 --end 5,0,0 --out wall.ifc
116
+ ifc-lite create stair --number-of-risers 12 --riser-height 0.175 --width 1.2 --out stair.ifc
117
+ ifc-lite create door --width 0.9 --height 2.1 --position 0,0,0 --out door.ifc
118
+ ifc-lite create i-shape-beam --start 0,0,3 --end 5,0,3 --out beam.ifc
119
+ ifc-lite create wall --from-json --out w.ifc < params.json
120
+ ifc-lite create wall --pset '{"Name":"Pset_WallCommon","Properties":[{"Name":"IsExternal","NominalValue":true}]}' --out w.ifc
121
+ ifc-lite create wall --material '{"Name":"Concrete","Category":"Structural"}' --out w.ifc
122
+ ifc-lite create wall --color 0.8,0.2,0.2 --out w.ifc
123
+ ifc-lite eval model.ifc "bim.query().byType('IfcWall').count()"
124
+ ifc-lite eval model.ifc "bim.storeys().map(s => s.name)"
125
+ ifc-lite run analysis.js model.ifc
126
+ ifc-lite schema
127
+ ifc-lite schema --compact
128
+ ifc-lite merge arch.ifc struct.ifc mep.ifc --out federated.ifc
129
+ ifc-lite convert model.ifc --schema IFC4 --out model-ifc4.ifc
130
+ ifc-lite diff model-v1.ifc model-v2.ifc --json
131
+ ifc-lite diff model-v1.ifc model-v2.ifc --by-entity
132
+ ifc-lite diff model-v1.ifc model-v2.ifc --by-content --identity-out renames.json
133
+ ifc-lite diff model-v1.ifc model-v2.ifc --identity-in renames.json
134
+ ifc-lite diff model-v1.ifc model-v2.ifc --geometry --split-merge --successors --json
135
+ ifc-lite diff model-v1.ifc model-v2.ifc --key-from Pset_Asset.AssetId --lineage-out lineage.json
136
+ ifc-lite rekey costs.csv --lineage lineage.json --key-column GlobalId --out costs-v2.csv
137
+ ifc-lite validate model.ifc --json
138
+ ifc-lite bsdd class IfcWall
139
+ ifc-lite bsdd search "concrete wall"
140
+ ifc-lite bsdd psets IfcWall
141
+ ifc-lite ask model.ifc "how many walls?"
142
+ ifc-lite ask model.ifc "window-wall ratio" --json
143
+ ifc-lite ask model.ifc "list materials" --explain
144
+ ifc-lite view model.ifc
145
+ ifc-lite view model.ifc --port 3456
146
+ curl -X POST http://localhost:3456/api/command -H 'Content-Type: application/json' -d '{"action":"colorize","type":"IfcWall","color":[1,0,0,1]}'
147
+ ifc-lite analyze model.ifc --viewer 3456 --type IfcWall --missing "Pset_WallCommon.FireRating" --color red
148
+ ifc-lite analyze model.ifc --viewer 3456 --type IfcSlab --where "GrossArea>100" --color orange --isolate
149
+ ifc-lite analyze model.ifc --viewer 3456 --type IfcWall --heatmap "Qto_WallBaseQuantities.GrossSideArea"
150
+ ifc-lite analyze model.ifc --viewer 3456 --rules rules.json --json
151
+ ifc-lite lod model.ifc --level 0 --out model.lod0.json
152
+ ifc-lite lod model.ifc --level 1 --out model.glb --meta model.lod1.json
153
+ ifc-lite mcp model.ifc
154
+ ifc-lite mcp model.ifc --read-only
155
+ ifc-lite mcp arch.ifc struct.ifc --federate
156
+ ifc-lite mcp model.ifc --transport http --port 8765 --token abc
157
+ ifc-lite ref create main
158
+ ifc-lite layer publish delta.ifcx --base main --intent "Set fire ratings" --scope "model.mutate:Pset_FireSafety*@IfcWall"
159
+ ifc-lite layer merge blake3:abc123 --into main --preview
160
+ ifc-lite layer log main
161
+ ifc-lite layer bake main -o flat.ifcx
162
+ ifc-lite gym --model model.ifc --checks schema,clash
163
+ ifc-lite gym --model model.ifc --checks schema,clash,ids --ids rules.ids
164
+ ifc-lite gym --seed 42 --checks schema,clash
165
+
166
+ Pipe-friendly:
167
+ ifc-lite query model.ifc --type IfcWall --json | jq '.[].name'
168
+ ifc-lite export model.ifc --format csv --type IfcSlab > slabs.csv
169
+ echo '{"Start":[0,0,0],"End":[10,0,0],"Height":3}' | ifc-lite create wall --from-json --out w.ifc
170
+
171
+ Create element types:
172
+ wall, slab, column, beam, stair, roof, gable-roof, door, window,
173
+ wall-door, wall-window, ramp, railing, plate, member, footing, pile,
174
+ space, curtain-wall, furnishing, proxy, circular-column,
175
+ hollow-circular-column, i-shape-beam, l-shape-member, t-shape-member,
176
+ u-shape-member, rectangle-hollow-beam
177
+
178
+ gym protocol (newline-delimited JSON, one command per stdin line):
179
+ On start: {"type":"reset","observation":{entityCounts,storeyCount,schema,bounds},"channels":{...}}
180
+ -> {"type":"step","ops":[{"op":"setProperty"|"setAttribute"|"deleteProperty", ...}]}
181
+ <- {"type":"reward","channels":{schema:{score,...},clash:{score,...},ids:{score,...}},"done":false}
182
+ -> {"type":"reset"} reloads the pristine model, replies like the initial reset
183
+ -> {"type":"reset","seed":8} episode factory: swaps to a generated World Gym benchmark
184
+ model (optional "family"/"corrupt"/"corruptRate" fields);
185
+ needs the repo checkout (tools/world-gym). Also on start via
186
+ --seed <n> [--family ...] [--corrupt|--no-corrupt|--corrupt-rate p].
187
+ Generated-episode resets add "episode":{seed,family,corrupted}.
188
+ -> {"type":"close"} exits 0
189
+ Malformed input replies {"type":"error","message":"..."} instead of crashing.
190
+ v0 ops: setProperty/setAttribute/deleteProperty only (mirrors bim.mutate's method
191
+ names). Geometry-creating ops are out of scope for v0.
192
+
193
+ Learn more: https://ifclite.com
194
+ `;
195
+ }
196
+ /**
197
+ * The `Commands:` block, as a map from command name to its rows (the command's
198
+ * own line plus any deeper-indented continuation lines).
199
+ *
200
+ * Derived from the same literal `buildHelp` returns rather than a second
201
+ * hand-written table: `scripts/docs/generate-docs-sections.mjs` already parses
202
+ * that block for the docs table, so a per-command help built any other way
203
+ * would be a third place to forget when a flag changes.
204
+ *
205
+ * A command row starts at exactly four spaces then the name; continuation rows
206
+ * are indented deeper. Long names (`diagnose-geometry`, `extract-entities`)
207
+ * leave only ONE space before their `<args>`, so the gap is `\s+`, not `\s{2,}`.
208
+ */
209
+ function parseCommandBlock(help) {
210
+ const block = help.match(/\n {2}Commands:\n([\s\S]*?)\n {2}Options:/);
211
+ const commands = new Map();
212
+ if (!block)
213
+ return commands;
214
+ let current;
215
+ for (const line of block[1].split('\n')) {
216
+ const head = line.match(/^ {4}([a-z][\w-]*)\s+\S/);
217
+ if (head) {
218
+ current = [line];
219
+ commands.set(head[1], current);
220
+ }
221
+ else if (current && /^ {6,}\S/.test(line)) {
222
+ current.push(line);
223
+ }
224
+ else if (line.trim() === '') {
225
+ current = undefined;
226
+ }
227
+ }
228
+ return commands;
229
+ }
230
+ /** Every command name the help text documents. */
231
+ export function helpCommandNames(version = '0.0.0') {
232
+ return [...parseCommandBlock(buildHelp(version)).keys()];
233
+ }
234
+ /**
235
+ * Help for ONE command.
236
+ *
237
+ * `ifc-lite <command> --help` used to print the global help for all 37
238
+ * commands, because `index.ts` tested `args.includes('--help')` before
239
+ * dispatch and `args` still held the command name (#5527). The CLI's own docs
240
+ * tell LLM users to "discover all capabilities by running `ifc-lite --help`";
241
+ * there was no second level to discover.
242
+ *
243
+ * Returns `null` for a name the help text does not document, so the caller can
244
+ * fall back to the global help rather than print an empty section.
245
+ */
246
+ export function buildCommandHelp(version, command) {
247
+ const rows = parseCommandBlock(buildHelp(version)).get(command);
248
+ if (!rows)
249
+ return null;
250
+ return [
251
+ ``,
252
+ ` ifc-lite ${command} — see \`ifc-lite --help\` for every command`,
253
+ ``,
254
+ ...rows,
255
+ ``,
256
+ ` Full reference: https://ifclite.dev/docs/guide/cli/`,
257
+ ``,
258
+ ].join('\n');
259
+ }
260
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;GAIG;AAEH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO;cACK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuLpB,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAE5B,IAAI,OAA6B,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACnD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;YACjB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9B,OAAO,GAAG,SAAS,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAAG,OAAO;IAChD,OAAO,CAAC,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAe;IAC/D,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO;QACL,EAAE;QACF,cAAc,OAAO,8CAA8C;QACnE,EAAE;QACF,GAAG,IAAI;QACP,EAAE;QACF,uDAAuD;QACvD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@
9
9
  * from the command line. Designed for both humans and LLM terminals.
10
10
  */
11
11
  import { logger, parseVerbosity } from './logger.js';
12
+ import { fatal } from './output.js';
13
+ import { COMMANDS_WITH_OUT } from './out-flag-commands.js';
12
14
  import { infoCommand } from './commands/info.js';
13
15
  import { queryCommand } from './commands/query.js';
14
16
  import { scheduleCommand } from './commands/schedule.js';
@@ -44,197 +46,21 @@ import { layerCommand } from './commands/layer.js';
44
46
  import { refCommand } from './commands/ref.js';
45
47
  import { gymCommand } from './commands/gym.js';
46
48
  import { deliveryCommand } from './commands/delivery.js';
49
+ import { checkCommand } from './commands/check.js';
50
+ import { flowCommand } from './commands/flow.js';
47
51
  import { fileURLToPath } from 'node:url';
48
52
  import { dirname, join } from 'node:path';
49
- import { readCliVersion } from './version.js';
50
- const __filename = fileURLToPath(import.meta.url);
51
- const __dirname = dirname(__filename);
53
+ import { readPackageVersion } from '@ifc-lite/data';
54
+ import { buildHelp, buildCommandHelp } from './help.js';
52
55
  // package.json sits one level above both `src/` and `dist/`.
53
- const VERSION = readCliVersion(join(__dirname, '..', 'package.json'));
54
- const HELP = `
55
- ifc-lite v${VERSION} — BIM toolkit for the terminal
56
-
57
- Usage: ifc-lite <command> [options]
58
-
59
- Commands:
60
- info <file.ifc> Model summary (schema, entities, storeys)
61
- query <file.ifc> [--type T] [--json] Query entities by type/properties/quantities
62
- [--select "IfcWall, Pset_WallCommon.FireRating=2HR"] IfcOpenShell-style selector (classes union with --type; properties AND with --where)
63
- props <file.ifc> --id <N> All properties for a single entity
64
- export <file.ifc> --format csv|json|ifc|obj|gltf|glb|jsonld|step|ifcx|usd|hbjson|dfjson Export data / geometry / energy model
65
- schedule <file.ifc> --type T --columns "H=path,..." Tabular schedule of one class (csv/json/md/html)
66
- [--preset door|window|space|wall|material-takeoff] default type+columns (flags override)
67
- [--where PsetName.Prop=Value] [--format csv|json|md|html] path = attr | Pset.Prop | Qto.Qty
68
- [--sort "Header[:asc|desc],..."] multi-key row sort by column HEADER (numbers numeric, nulls last)
69
- [--group-by "Header,..."] contiguous groups, ordered by group key (asc, or --sort's dir)
70
- [--subtotals "count|sum:H|avg:H|min:H|max:H,..."] subtotal row per group + grand total
71
- (without --group-by: grand total only; CSV/md label the group column, JSON marks __row)
72
- [--spec spec.json] load a saved schedule definition (beats --preset; an explicit flag beats both)
73
- [--save spec.json] persist this invocation's resolved definition for --spec reuse
74
- diagnose-geometry <file.ifc> [--json] CSG / opening diagnostics (failures, classification)
75
- [--product ID|GUID] [--type T] Filter worst-hosts detail to one product/type
76
- extract-entities <file.ifc> --out F Isolate entities into a small, viewable standalone IFC
77
- [--product ID|GUID] [--storey S] [--detect] [--view] by GUID/type/storey or auto-triage
78
- anonymize <file.ifc> --out F Export selected objects + context as an anonymized IFC
79
- [--id N,...] [--guid G,...] [--type T] [--storey S]
80
- [--keep-psets] [--keep-names] [--keep-other-names] [--keep-currency]
81
- [--no-rel-voids-element] [--no-rel-fills-element] [--no-rel-defines-by-type]
82
- [--no-rel-associates-material] [--no-rel-aggregates] [--no-rel-nests]
83
- [--connect-depth N] [--guid-map F] [--json]
84
- ids <file.ifc> <rules.ids> Validate against IDS rules
85
- bcf <create|list|add-comment> Work with BCF collaboration files
86
- clash <file.ifc> [--matrix] [--bcf F] Detect geometric clashes between elements
87
- create <type> [options] --out F Create IFC elements (30+ types)
88
- eval <file.ifc> "<expression>" Evaluate SDK expression
89
- run <script.js> <file.ifc> Execute a script against model
90
- schema Dump SDK API schema (for LLM tools)
91
- merge <f1.ifc> <f2.ifc> --out F Merge multiple IFC files
92
- convert <file.ifc> --schema VER --out F Convert between IFC schema versions
93
- diff <f1.ifc> <f2.ifc> Compare two IFC files
94
- [--by-content] [--identity-out F] [--identity-in F] Match re-GUIDed elements by content; save/replay the identity map
95
- [--geometry] [--split-merge] [--successors] Wasm mesh pass: world geometry hashes/boxes/volumes; split/merge + successor claims
96
- [--lineage-out F] [--lineage-in F] [--accept F] [--key-from Tag|Pset.Prop] Lineage for rekeying external data; authored key
97
- rekey <table.csv|json> --lineage F --out F Carry a table keyed on old element keys across a revision
98
- validate <file.ifc> Structural validation checks
99
- bsdd <class|search|psets|qsets> <arg> buildingSMART Data Dictionary lookup
100
- stats <file.ifc> Auto-calculated model KPIs and health check
101
- mutate <file.ifc> --id N --set P=V --out F Modify properties/attributes and save
102
- generate-spaces <file.ifc> --out F Derive IfcSpace from walls (slab/roof-aware height)
103
- ask <file.ifc> "<question>" Natural language BIM queries
104
- view <file.ifc> [--port N] Interactive 3D viewer in browser
105
- analyze <file.ifc> --viewer <port> Query + visualize analysis results
106
- lod <file.ifc> --level 0|1 Generate lightweight LOD artifacts
107
- simplify <file.ifc> --out F [--level 1..5] [--ids 1,2,...] [--json] Demesher: simplify meshes, write lighter IFC
108
- mcp <file.ifc> [--transport stdio|http] Start an MCP server bound to one or more IFC files
109
- ext validate <path>|init <dir> Manage IFClite extensions (Phase 0 — validate, init)
110
- layer <publish|diff|merge|log|bake|...> Layered change tracking over a local store (.ifc-lite/)
111
- ref <list|create|move|protect> Manage named refs in the layer store
112
- gym --model <file.ifc> | --seed <n> reset/step/reward environment loop (JSONL over stdin/stdout)
113
- delivery <recipe.json> [--json] [--out F] [--html F] Repeatable delivery check (structural + IDS) from a saved recipe
114
- recipe: {"models":["m.ifc"],"structural":true,"ids":["rules.ids"]}, paths relative to the recipe file
115
-
116
- Options:
117
- --help, -h Show help
118
- --version, -v Show version
119
- --json Output as JSON (machine-readable)
120
- --out <file> Write output to file instead of stdout
121
- --verbose Show parser + geometry diagnostics (stderr)
122
- --quiet Errors only
123
- --debug Verbose + stack traces on error
124
- --log-level <level> error|warn|info|debug (explicit wins over shorthands)
125
-
126
- Examples:
127
- ifc-lite info model.ifc
128
- ifc-lite query model.ifc --type IfcWall --json
129
- ifc-lite query model.ifc --type IfcDoor --props --limit 5
130
- ifc-lite query model.ifc --type IfcWall --materials --classifications --json
131
- ifc-lite query model.ifc --type IfcWall --all --json
132
- ifc-lite query model.ifc --type IfcWall --quantity-names
133
- ifc-lite query model.ifc --type IfcWall --sum GrossSideArea
134
- ifc-lite query model.ifc --type IfcWall --group-by material --json
135
- ifc-lite query model.ifc --spatial --summary
136
- ifc-lite query model.ifc --spatial
137
- ifc-lite props model.ifc --id 42
138
- ifc-lite export model.ifc --format csv --type IfcWall --columns Name,Type,GlobalId
139
- ifc-lite export model.ifc --format json --type IfcWall,IfcDoor
140
- ifc-lite schedule model.ifc --type IfcDoor --columns "Name=Name, Mark=Pset_DoorCommon.Reference"
141
- ifc-lite schedule model.ifc --type IfcWall --columns "Name,Qto_WallBaseQuantities.NetVolume" --where Pset_WallCommon.IsExternal=true --format json
142
- ifc-lite schedule model.ifc --type IfcDoor --columns "Name=Name, Fire=Pset_DoorCommon.FireRating, Area=Qto_DoorBaseQuantities.Area" --group-by Fire --sort "Area:desc" --subtotals "count, sum:Area"
143
- ifc-lite schedule model.ifc --preset door
144
- ifc-lite schedule model.ifc --preset material-takeoff --format json
145
- ifc-lite schedule model.ifc --preset door --format md
146
- ifc-lite schedule model.ifc --preset door --format html > doors.html
147
- ifc-lite schedule model.ifc --preset door --save door-schedule.json
148
- ifc-lite schedule model.ifc --spec door-schedule.json --format json
149
- ifc-lite diagnose-geometry model.ifc --json
150
- ifc-lite diagnose-geometry model.ifc --type IfcWall
151
- ifc-lite diagnose-geometry model.ifc --product 0YvCT2_$X3_xJG3rzD8L_8
152
- ifc-lite ids model.ifc requirements.ids --json
153
- ifc-lite bcf create --title "Missing door" --out topic.bcf
154
- ifc-lite clash model.ifc --matrix --json
155
- ifc-lite clash model.ifc --a "IfcDuct*|IfcPipe*" --b "IfcWall*" --mode clearance --clearance 0.05
156
- ifc-lite clash model.ifc --matrix --bcf clashes.bcfzip
157
- ifc-lite create wall --height 3 --thickness 0.2 --start 0,0,0 --end 5,0,0 --out wall.ifc
158
- ifc-lite create stair --number-of-risers 12 --riser-height 0.175 --width 1.2 --out stair.ifc
159
- ifc-lite create door --width 0.9 --height 2.1 --position 0,0,0 --out door.ifc
160
- ifc-lite create i-shape-beam --start 0,0,3 --end 5,0,3 --out beam.ifc
161
- ifc-lite create wall --from-json --out w.ifc < params.json
162
- ifc-lite create wall --pset '{"Name":"Pset_WallCommon","Properties":[{"Name":"IsExternal","NominalValue":true}]}' --out w.ifc
163
- ifc-lite create wall --material '{"Name":"Concrete","Category":"Structural"}' --out w.ifc
164
- ifc-lite create wall --color 0.8,0.2,0.2 --out w.ifc
165
- ifc-lite eval model.ifc "bim.query().byType('IfcWall').count()"
166
- ifc-lite eval model.ifc "bim.storeys().map(s => s.name)"
167
- ifc-lite run analysis.js model.ifc
168
- ifc-lite schema
169
- ifc-lite schema --compact
170
- ifc-lite merge arch.ifc struct.ifc mep.ifc --out federated.ifc
171
- ifc-lite convert model.ifc --schema IFC4 --out model-ifc4.ifc
172
- ifc-lite diff model-v1.ifc model-v2.ifc --json
173
- ifc-lite diff model-v1.ifc model-v2.ifc --by-entity
174
- ifc-lite diff model-v1.ifc model-v2.ifc --by-content --identity-out renames.json
175
- ifc-lite diff model-v1.ifc model-v2.ifc --identity-in renames.json
176
- ifc-lite diff model-v1.ifc model-v2.ifc --geometry --split-merge --successors --json
177
- ifc-lite diff model-v1.ifc model-v2.ifc --key-from Pset_Asset.AssetId --lineage-out lineage.json
178
- ifc-lite rekey costs.csv --lineage lineage.json --key-column GlobalId --out costs-v2.csv
179
- ifc-lite validate model.ifc --json
180
- ifc-lite bsdd class IfcWall
181
- ifc-lite bsdd search "concrete wall"
182
- ifc-lite bsdd psets IfcWall
183
- ifc-lite ask model.ifc "how many walls?"
184
- ifc-lite ask model.ifc "window-wall ratio" --json
185
- ifc-lite ask model.ifc "list materials" --explain
186
- ifc-lite view model.ifc
187
- ifc-lite view model.ifc --port 3456
188
- curl -X POST http://localhost:3456/api/command -H 'Content-Type: application/json' -d '{"action":"colorize","type":"IfcWall","color":[1,0,0,1]}'
189
- ifc-lite analyze model.ifc --viewer 3456 --type IfcWall --missing "Pset_WallCommon.FireRating" --color red
190
- ifc-lite analyze model.ifc --viewer 3456 --type IfcSlab --where "GrossArea>100" --color orange --isolate
191
- ifc-lite analyze model.ifc --viewer 3456 --type IfcWall --heatmap "Qto_WallBaseQuantities.GrossSideArea"
192
- ifc-lite analyze model.ifc --viewer 3456 --rules rules.json --json
193
- ifc-lite lod model.ifc --level 0 --out model.lod0.json
194
- ifc-lite lod model.ifc --level 1 --out model.glb --meta model.lod1.json
195
- ifc-lite mcp model.ifc
196
- ifc-lite mcp model.ifc --read-only
197
- ifc-lite mcp arch.ifc struct.ifc --federate
198
- ifc-lite mcp model.ifc --transport http --port 8765 --token abc
199
- ifc-lite ref create main
200
- ifc-lite layer publish delta.ifcx --base main --intent "Set fire ratings" --scope "model.mutate:Pset_FireSafety*@IfcWall"
201
- ifc-lite layer merge blake3:abc123 --into main --preview
202
- ifc-lite layer log main
203
- ifc-lite layer bake main -o flat.ifcx
204
- ifc-lite gym --model model.ifc --checks schema,clash
205
- ifc-lite gym --model model.ifc --checks schema,clash,ids --ids rules.ids
206
- ifc-lite gym --seed 42 --checks schema,clash
207
-
208
- Pipe-friendly:
209
- ifc-lite query model.ifc --type IfcWall --json | jq '.[].name'
210
- ifc-lite export model.ifc --format csv --type IfcSlab > slabs.csv
211
- echo '{"Start":[0,0,0],"End":[10,0,0],"Height":3}' | ifc-lite create wall --from-json --out w.ifc
212
-
213
- Create element types:
214
- wall, slab, column, beam, stair, roof, gable-roof, door, window,
215
- wall-door, wall-window, ramp, railing, plate, member, footing, pile,
216
- space, curtain-wall, furnishing, proxy, circular-column,
217
- hollow-circular-column, i-shape-beam, l-shape-member, t-shape-member,
218
- u-shape-member, rectangle-hollow-beam
219
-
220
- gym protocol (newline-delimited JSON, one command per stdin line):
221
- On start: {"type":"reset","observation":{entityCounts,storeyCount,schema,bounds},"channels":{...}}
222
- -> {"type":"step","ops":[{"op":"setProperty"|"setAttribute"|"deleteProperty", ...}]}
223
- <- {"type":"reward","channels":{schema:{score,...},clash:{score,...},ids:{score,...}},"done":false}
224
- -> {"type":"reset"} reloads the pristine model, replies like the initial reset
225
- -> {"type":"reset","seed":8} episode factory: swaps to a generated World Gym benchmark
226
- model (optional "family"/"corrupt"/"corruptRate" fields);
227
- needs the repo checkout (tools/world-gym). Also on start via
228
- --seed <n> [--family ...] [--corrupt|--no-corrupt|--corrupt-rate p].
229
- Generated-episode resets add "episode":{seed,family,corrupted}.
230
- -> {"type":"close"} exits 0
231
- Malformed input replies {"type":"error","message":"..."} instead of crashing.
232
- v0 ops: setProperty/setAttribute/deleteProperty only (mirrors bim.mutate's method
233
- names). Geometry-creating ops are out of scope for v0.
234
-
235
- Learn more: https://ifclite.com
236
- `;
56
+ const VERSION = readPackageVersion(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'));
237
57
  /** Command being executed, captured for the top-level error handler. */
58
+ /**
59
+ * Commands that handle `--help` themselves, with more detail than the global
60
+ * `Commands:` block carries. Their handlers already tested for it; before
61
+ * #5527 that branch was simply unreachable.
62
+ */
63
+ const HELP_DELEGATING_COMMANDS = new Set(['layer', 'ref', 'ext']);
238
64
  let activeCommand = '';
239
65
  /** True when --debug was passed (stack traces on error). */
240
66
  let debugFlag = false;
@@ -245,10 +71,25 @@ async function main() {
245
71
  logger.configure({ level: verbosity.level });
246
72
  debugFlag = verbosity.debug;
247
73
  const args = verbosity.rest;
248
- if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
249
- process.stdout.write(HELP + '\n');
74
+ const wantsHelp = args.includes('--help') || args.includes('-h');
75
+ if (args.length === 0) {
76
+ process.stdout.write(buildHelp(VERSION) + '\n');
250
77
  return;
251
78
  }
79
+ if (wantsHelp) {
80
+ // `--help` used to be answered globally BEFORE dispatch, with the command
81
+ // still sitting in `args`, so all 37 subcommands printed the same page and
82
+ // the real help written in `layer`/`ref`/`ext` was unreachable (#5527).
83
+ const requested = args[0];
84
+ if (HELP_DELEGATING_COMMANDS.has(requested)) {
85
+ // These three write richer help of their own; let them answer.
86
+ }
87
+ else {
88
+ const commandHelp = buildCommandHelp(VERSION, requested);
89
+ process.stdout.write((commandHelp ?? buildHelp(VERSION)) + '\n');
90
+ return;
91
+ }
92
+ }
252
93
  if (args.includes('--version') || args.includes('-v')) {
253
94
  process.stdout.write(`ifc-lite ${VERSION}\n`);
254
95
  return;
@@ -256,6 +97,11 @@ async function main() {
256
97
  const command = args[0];
257
98
  activeCommand = command;
258
99
  const commandArgs = args.slice(1);
100
+ if (commandArgs.includes('--out') && !COMMANDS_WITH_OUT.has(command)) {
101
+ fatal(`\`${command}\` does not write to a file: it has no --out. ` +
102
+ `Redirect its output instead, e.g. \`ifc-lite ${command} ... > out.json\`. ` +
103
+ `Commands that do take --out: ${[...COMMANDS_WITH_OUT].sort().join(', ')}.`);
104
+ }
259
105
  switch (command) {
260
106
  case 'info':
261
107
  await infoCommand(commandArgs);
@@ -362,6 +208,12 @@ async function main() {
362
208
  case 'delivery':
363
209
  await deliveryCommand(commandArgs);
364
210
  break;
211
+ case 'check':
212
+ await checkCommand(commandArgs);
213
+ break;
214
+ case 'flow':
215
+ await flowCommand(commandArgs);
216
+ break;
365
217
  default:
366
218
  process.stderr.write(`Unknown command: ${command}\n`);
367
219
  process.stderr.write(`Run 'ifc-lite --help' for usage.\n`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;+DAE+D;AAE/D;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAExD,6DAA6D;AAC7D,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;AAExG,wEAAwE;AACxE;;;;GAIG;AACH,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAElE,IAAI,aAAa,GAAG,EAAE,CAAC;AACvB,4DAA4D;AAC5D,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,KAAK,UAAU,IAAI;IACjB,sEAAsE;IACtE,0EAA0E;IAC1E,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7C,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC;IAC5B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,wBAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,+DAA+D;QACjE,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,aAAa,GAAG,OAAO,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAElC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACrE,KAAK,CACH,KAAK,OAAO,gDAAgD;YAC1D,gDAAgD,OAAO,qBAAqB;YAC5E,gCAAgC,CAAC,GAAG,iBAAiB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC9E,CAAC;IACJ,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,mBAAmB;YACtB,MAAM,uBAAuB,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM;QACR,KAAK,kBAAkB;YACrB,MAAM,sBAAsB,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM;QACR,KAAK,WAAW;YACd,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACpC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,iBAAiB;YACpB,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,KAAK;YACR,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9B,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,OAAO;YACV,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM;QACR;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,IAAI,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,UAAU,aAAa,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACnD,uEAAuE;IACvE,wCAAwC;IACxC,IAAI,SAAS,IAAI,MAAM,CAAC,KAAK,EAAE,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8DAA8D,aAAa,IAAI,WAAW,wBAAwB,CACnH,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/loader.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type IfcDataStore } from '@ifc-lite/parser';
2
2
  import { type BimContext } from '@ifc-lite/sdk';
3
+ import { HeadlessBackend } from './headless-backend.js';
3
4
  /**
4
5
  * Parse an IFC file from disk into an IfcDataStore.
5
6
  * Suppresses parser console output for clean CLI experience.
@@ -19,6 +20,7 @@ export declare function loadIfcBytes(bytes: Uint8Array, label?: string): Promise
19
20
  export declare function createHeadlessContext(filePath: string): Promise<{
20
21
  bim: BimContext;
21
22
  store: IfcDataStore;
23
+ backend: HeadlessBackend;
22
24
  }>;
23
25
  /**
24
26
  * Create a BimContext that streams viewer commands to a running `ifc-lite view` server.
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAWA,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAoB,KAAK,UAAU,EAA4D,MAAM,eAAe,CAAC;AAI5H;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAGzE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,KAAK,SAAU,GACd,OAAO,CAAC,YAAY,CAAC,CA6DvB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,CAK/G;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,CAUnD"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAWA,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAoB,KAAK,UAAU,EAA4D,MAAM,eAAe,CAAC;AAC5H,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAGzE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,KAAK,SAAU,GACd,OAAO,CAAC,YAAY,CAAC,CAkGvB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC,CAKzI;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,CAUnD"}
package/dist/loader.js CHANGED
@@ -50,6 +50,35 @@ export async function loadIfcBytes(bytes, label = 'input') {
50
50
  process.stderr.write(`Error: ${label} is not a valid IFC/STEP file\n`);
51
51
  process.exit(1);
52
52
  }
53
+ // A STEP file ends with `END-ISO-10303-21;`. Its absence means the bytes are
54
+ // truncated -- a half-finished download, a killed export, a partial upload --
55
+ // and a truncated file does not fail to parse: it parses to a PREFIX. The
56
+ // scan stops wherever the bytes stop and reports whatever it got, so
57
+ // `ifc-lite info` answered "Entities: 59" and exited 0 for the first 4 KB of a
58
+ // real model, and "Schema: IFC4" for a 22-byte stub with no FILE_SCHEMA at
59
+ // all (#5532). A confidently wrong answer is worse than an error, because
60
+ // nothing downstream can tell it apart from a small model.
61
+ //
62
+ // Only the tail is decoded: these files reach hundreds of MB.
63
+ const tailStart = Math.max(0, bytes.byteLength - 256);
64
+ const tailSnippet = new TextDecoder('latin1').decode(bytes.subarray(tailStart));
65
+ if (!tailSnippet.includes('END-ISO-10303-21;')) {
66
+ process.stderr.write(`Error: ${label} is truncated: it starts like a STEP file but has no ` +
67
+ `END-ISO-10303-21; terminator, so any entity count or schema read from it ` +
68
+ `would describe only the part that arrived.\n`);
69
+ process.exit(1);
70
+ }
71
+ // A file with a header and no DATA section carries no entities at all. It is
72
+ // well-formed STEP, so the terminator check above passes; it is still not a
73
+ // model, and reporting a schema for it asserts something the file never said.
74
+ // Bounded, like the header scan: `DATA;` follows the header, and these files
75
+ // reach hundreds of MB -- decoding one whole would also risk V8's max string
76
+ // length. 64 KB is far more header than any exporter writes.
77
+ const headText = new TextDecoder('latin1').decode(bytes.subarray(0, Math.min(bytes.byteLength, 64 * 1024)));
78
+ if (!/^\s*DATA\s*;/m.test(headText)) {
79
+ process.stderr.write(`Error: ${label} has no DATA section, so it contains no IFC entities.\n`);
80
+ process.exit(1);
81
+ }
53
82
  const parser = new IfcParser();
54
83
  // Capture the parser's internal console.log/warn during parsing and route
55
84
  // them to logger.debug: silent by default (stdout stays clean for payloads),
@@ -88,7 +117,7 @@ export async function createHeadlessContext(filePath) {
88
117
  const store = await loadIfcFile(filePath);
89
118
  const backend = new HeadlessBackend(store, basename(filePath));
90
119
  const bim = createBimContext({ backend });
91
- return { bim, store };
120
+ return { bim, store, backend };
92
121
  }
93
122
  /**
94
123
  * Create a BimContext that streams viewer commands to a running `ifc-lite view` server.