@ifc-lite/mcp 0.9.2 → 0.11.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 (64) hide show
  1. package/README.md +32 -1
  2. package/dist/auth/scope.d.ts.map +1 -1
  3. package/dist/auth/scope.js +6 -2
  4. package/dist/auth/scope.js.map +1 -1
  5. package/dist/backend-query.d.ts +41 -0
  6. package/dist/backend-query.d.ts.map +1 -0
  7. package/dist/backend-query.js +486 -0
  8. package/dist/backend-query.js.map +1 -0
  9. package/dist/headless-backend.d.ts +4 -3
  10. package/dist/headless-backend.d.ts.map +1 -1
  11. package/dist/headless-backend.js +26 -212
  12. package/dist/headless-backend.js.map +1 -1
  13. package/dist/overlay.d.ts +171 -0
  14. package/dist/overlay.d.ts.map +1 -0
  15. package/dist/overlay.js +300 -0
  16. package/dist/overlay.js.map +1 -0
  17. package/dist/resources/providers.d.ts.map +1 -1
  18. package/dist/resources/providers.js +28 -27
  19. package/dist/resources/providers.js.map +1 -1
  20. package/dist/schema-tables.d.ts +42 -0
  21. package/dist/schema-tables.d.ts.map +1 -0
  22. package/dist/schema-tables.js +75 -0
  23. package/dist/schema-tables.js.map +1 -0
  24. package/dist/spatial-tree.d.ts +40 -0
  25. package/dist/spatial-tree.d.ts.map +1 -0
  26. package/dist/spatial-tree.js +70 -0
  27. package/dist/spatial-tree.js.map +1 -0
  28. package/dist/tools/bsdd.d.ts.map +1 -1
  29. package/dist/tools/bsdd.js +5 -16
  30. package/dist/tools/bsdd.js.map +1 -1
  31. package/dist/tools/clash.d.ts.map +1 -1
  32. package/dist/tools/clash.js +36 -23
  33. package/dist/tools/clash.js.map +1 -1
  34. package/dist/tools/diff-fingerprints.d.ts +110 -0
  35. package/dist/tools/diff-fingerprints.d.ts.map +1 -0
  36. package/dist/tools/diff-fingerprints.js +410 -0
  37. package/dist/tools/diff-fingerprints.js.map +1 -0
  38. package/dist/tools/diff.d.ts.map +1 -1
  39. package/dist/tools/diff.js +199 -26
  40. package/dist/tools/diff.js.map +1 -1
  41. package/dist/tools/discovery.d.ts.map +1 -1
  42. package/dist/tools/discovery.js +124 -36
  43. package/dist/tools/discovery.js.map +1 -1
  44. package/dist/tools/export.d.ts.map +1 -1
  45. package/dist/tools/export.js +136 -68
  46. package/dist/tools/export.js.map +1 -1
  47. package/dist/tools/mutate.d.ts.map +1 -1
  48. package/dist/tools/mutate.js +74 -11
  49. package/dist/tools/mutate.js.map +1 -1
  50. package/dist/tools/query.d.ts.map +1 -1
  51. package/dist/tools/query.js +129 -69
  52. package/dist/tools/query.js.map +1 -1
  53. package/dist/tools/util.d.ts +36 -7
  54. package/dist/tools/util.d.ts.map +1 -1
  55. package/dist/tools/util.js +90 -0
  56. package/dist/tools/util.js.map +1 -1
  57. package/dist/tools/validation.d.ts.map +1 -1
  58. package/dist/tools/validation.js +82 -26
  59. package/dist/tools/validation.js.map +1 -1
  60. package/dist/viewer-manager.d.ts +9 -0
  61. package/dist/viewer-manager.d.ts.map +1 -1
  62. package/dist/viewer-manager.js +37 -2
  63. package/dist/viewer-manager.js.map +1 -1
  64. package/package.json +19 -18
package/README.md CHANGED
@@ -96,10 +96,41 @@ The same `npx` command works as a stdio server in any MCP-aware client.
96
96
  | Mutation | `entity_set_property`, `entity_delete_property`, `entity_set_attribute`, `entity_create`, `entity_delete`, `mutation_batch`, `mutation_undo`, `mutation_diff`, `model_save` |
97
97
  | BCF | `bcf_topic_list`, `bcf_topic_create`, `bcf_topic_update`, `bcf_topic_close`, `bcf_viewpoint_create`, `bcf_export` |
98
98
  | bSDD | `bsdd_search`, `bsdd_class`, `bsdd_property_sets`, `bsdd_match` |
99
- | Diff | `model_diff`, `quantity_diff` |
99
+ | Diff | `model_diff` (`by_content` for content-keyed matching), `quantity_diff` |
100
100
  | Export | `export_ifc`, `export_csv`, `export_json`, `export_glb`, `export_obj`, `export_ifcx`, `export_pdf_report` |
101
101
  | Viewer | `viewer_ask`, `viewer_open`, `viewer_close`, `viewer_status`, `viewer_colorize`, `viewer_isolate`, `viewer_hide`, `viewer_show`, `viewer_reset`, `viewer_fly_to`, `viewer_set_section`, `viewer_clear_section`, `viewer_color_by_storey`, `viewer_color_by_property`, `viewer_get_selection`, `viewer_wait_for_selection`, `viewer_describe_selection` |
102
102
 
103
+ `model_diff` compares by GlobalId, which reads a from-scratch re-export as the
104
+ whole model deleted and re-added. Pass `by_content: true` to run the
105
+ `@ifc-lite/diff` engine's content-keyed matching instead; it is data-scope only
106
+ (the server has no geometry pipeline) and reports unresolved `duplicated` /
107
+ `deduplicated` / `ambiguous` matches as groups rather than guessing a pairing —
108
+ capped by `max_matches` and `max_group_members`, both of which report the whole
109
+ totals they cut. A `model_id` names a session rather than a file, so all three
110
+ passes fold in mutations queued by `entity_create` / `entity_delete` /
111
+ `entity_set_*` and report the count in `contentDiff.pendingMutations`.
112
+
113
+ The rest of the read surface folds the same overlay: `get_entity`,
114
+ `get_entities_bulk`, `query_entities` (property filters and `in_storey` alike),
115
+ `count_entities`, `model_info`, `model_list`, `properties_unique`,
116
+ `materials_list`, `classifications_list`, `spatial_hierarchy`,
117
+ `containment_chain` and `model_audit`, plus the model manifest, entity and
118
+ spatial-tree resources. Containment folds too: a wall you create and place with
119
+ a queued `IfcRelContainedInSpatialStructure` is found by `in_storey`, and
120
+ deleting a relationship record stops it relating anything. Those payloads carry
121
+ `pendingMutations` whenever edits are queued and omit the field entirely when
122
+ none are, which is the line between "in this session" and "on disk" — nothing is
123
+ written until `export_ifc` or `model_save`.
124
+
125
+ `relationships` (voids/fills/groups/connections), `units`, `georeferencing` and
126
+ the geometry, clash and viewer tools answer from the parsed model and say so by
127
+ never carrying `pendingMutations`.
128
+
129
+ One GlobalId resolves to one entity everywhere: an entity the session created
130
+ wins over a same-GlobalId entity in the file, and a deleted one never resolves.
131
+ `get_entities_bulk` keys its map by that same rule and lists any key that named
132
+ more than one live entity in `ambiguousGlobalIds`.
133
+
103
134
  Resources expose live model state under the `ifc-lite://` URI scheme:
104
135
 
105
136
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/auth/scope.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,EAAE,SAEzB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAEvB,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,CAG3E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAGvE;AAED,wBAAgB,aAAa,IAAI,SAAS,CAEzC;AAED,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/auth/scope.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,EAAE,SAEzB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAEvB,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,CAG3E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAGvE;AAMD,wBAAgB,aAAa,IAAI,SAAS,CAEzC;AAED,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
@@ -17,10 +17,14 @@ export function modelAllowed(scope, modelId) {
17
17
  return true;
18
18
  return scope.modelIds.includes(modelId);
19
19
  }
20
+ /* The `scopes` array is copied too, not just the wrapper object: a spread
21
+ * alone hands every caller the SAME array instance as the exported constant,
22
+ * so `readOnlyScope().scopes.push('mutate')` widens `READ_ONLY` itself and
23
+ * every token minted afterwards in the process gets the extra scope. */
20
24
  export function readOnlyScope() {
21
- return { ...READ_ONLY };
25
+ return { ...READ_ONLY, scopes: [...READ_ONLY.scopes] };
22
26
  }
23
27
  export function fullScope() {
24
- return { ...FULL_ACCESS };
28
+ return { ...FULL_ACCESS, scopes: [...FULL_ACCESS.scopes] };
25
29
  }
26
30
  //# sourceMappingURL=scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/auth/scope.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAsB/D,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;CAC1D,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;CACvC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,KAAgB,EAAE,QAAoB;IAChE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAgB,EAAE,OAAe;IAC5D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/auth/scope.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAsB/D,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;CAC1D,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC;CACvC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,KAAgB,EAAE,QAAoB;IAChE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAgB,EAAE,OAAe;IAC5D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;;wEAGwE;AACxE,MAAM,UAAU,aAAa;IAC3B,OAAO,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The read half of `HeadlessLikeBackend`, with the session's pending mutations
3
+ * folded in (#2004).
4
+ *
5
+ * `MutablePropertyView` is an overlay: the parsed store's buffer and index are
6
+ * never touched, and the edits only materialise in `StepExporter`. Every read
7
+ * that went straight to the store therefore answered about the file *as parsed*,
8
+ * so an agent that edited and then read back to confirm was told its edit had
9
+ * not happened — and the natural recovery from that is to edit again.
10
+ *
11
+ * The fold lives here rather than in the tools because this is the one
12
+ * chokepoint they all pass through: `get_entity`, `query_entities`,
13
+ * `get_entities_bulk`, `count_entities` and `properties_unique` all go through
14
+ * `bim.*`, which is this adapter. Folding at tool level would mean each tool
15
+ * re-implementing it — and `query_entities`' property filters would have to
16
+ * re-implement the *filter*, which is exactly where a half-fold does the most
17
+ * damage: a query for the value just written must find it.
18
+ *
19
+ * `related` folds too (#2014), and with it every containment answer the SDK
20
+ * builds on top of it — `bim.storey`, `bim.path`, `bim.contains`,
21
+ * `bim.decomposes`. A queued `IfcRelContainedInSpatialStructure` is how an agent
22
+ * places something over MCP, so ignoring it was ignoring a write.
23
+ *
24
+ * What is deliberately not folded: `relationships`, whose voids / fills / groups
25
+ * / connections come from a parser-side extractor with no overlay seam, and the
26
+ * geometry the clash and viewer tools read. Those are rebuilt on the next
27
+ * `model_load` after a save.
28
+ */
29
+ import type { QueryBackendMethods } from '@ifc-lite/sdk';
30
+ import type { IfcDataStore } from '@ifc-lite/parser';
31
+ import { type PendingOverlay } from './overlay.js';
32
+ export declare function expandTypes(types: string[]): string[];
33
+ export declare function isProductType(type: string): boolean;
34
+ /**
35
+ * Build the query adapter over a store, folding whatever `overlay()` returns at
36
+ * call time. `overlay` is a getter, not a value: the backend creates its
37
+ * `MutablePropertyView` lazily on the first mutation, so a session that is only
38
+ * ever read gets `null` on every call and keeps the original store-only path.
39
+ */
40
+ export declare function createQueryAdapter(store: IfcDataStore, modelId: string, overlay: () => PendingOverlay | null): QueryBackendMethods;
41
+ //# sourceMappingURL=backend-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-query.d.ts","sourceRoot":"","sources":["../src/backend-query.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAWV,mBAAmB,EAEpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAYrD,OAAO,EAAgC,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAsBjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASrD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUnD;AAqED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,cAAc,GAAG,IAAI,GACnC,mBAAmB,CAyUrB"}
@@ -0,0 +1,486 @@
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
+ import { extractAllEntityAttributes, extractClassificationsOnDemand, extractDocumentsOnDemand, extractMaterialsOnDemand, extractRelationshipsOnDemand, extractTypePropertiesOnDemand, } from '@ifc-lite/parser';
5
+ import { attributeNamesForSchema } from './schema-tables.js';
6
+ import { EntityNode } from '@ifc-lite/query';
7
+ import { RelationshipType, IfcTypeEnum, IfcTypeEnumFromString } from '@ifc-lite/data';
8
+ const REL_TYPE_MAP = {
9
+ IfcRelContainedInSpatialStructure: RelationshipType.ContainsElements,
10
+ IfcRelAggregates: RelationshipType.Aggregates,
11
+ IfcRelDefinesByType: RelationshipType.DefinesByType,
12
+ IfcRelVoidsElement: RelationshipType.VoidsElement,
13
+ IfcRelFillsElement: RelationshipType.FillsElement,
14
+ };
15
+ const IFC_SUBTYPES = {
16
+ IFCWALL: ['IFCWALLSTANDARDCASE', 'IFCWALLELEMENTEDCASE'],
17
+ IFCBEAM: ['IFCBEAMSTANDARDCASE'],
18
+ IFCCOLUMN: ['IFCCOLUMNSTANDARDCASE'],
19
+ IFCDOOR: ['IFCDOORSTANDARDCASE'],
20
+ IFCWINDOW: ['IFCWINDOWSTANDARDCASE'],
21
+ IFCSLAB: ['IFCSLABSTANDARDCASE', 'IFCSLABELEMENTEDCASE'],
22
+ IFCMEMBER: ['IFCMEMBERSTANDARDCASE'],
23
+ IFCPLATE: ['IFCPLATESTANDARDCASE'],
24
+ IFCOPENINGELEMENT: ['IFCOPENINGSTANDARDCASE'],
25
+ };
26
+ export function expandTypes(types) {
27
+ const result = [];
28
+ for (const type of types) {
29
+ const upper = type.toUpperCase();
30
+ result.push(upper);
31
+ const subtypes = IFC_SUBTYPES[upper];
32
+ if (subtypes)
33
+ for (const sub of subtypes)
34
+ result.push(sub);
35
+ }
36
+ return result;
37
+ }
38
+ export function isProductType(type) {
39
+ const enumVal = IfcTypeEnumFromString(type);
40
+ if (enumVal === IfcTypeEnum.Unknown)
41
+ return false;
42
+ const upper = type.toUpperCase();
43
+ if (upper.startsWith('IFCREL'))
44
+ return false;
45
+ if (upper.startsWith('IFCPROPERTY'))
46
+ return false;
47
+ if (upper.startsWith('IFCQUANTITY'))
48
+ return false;
49
+ if (upper === 'IFCELEMENTQUANTITY')
50
+ return false;
51
+ if (upper.endsWith('TYPE'))
52
+ return false;
53
+ return true;
54
+ }
55
+ function normalizeBoolean(value) {
56
+ if (value === true || value === '.T.' || value === 'true' || value === 'TRUE')
57
+ return 'true';
58
+ if (value === false || value === '.F.' || value === 'false' || value === 'FALSE')
59
+ return 'false';
60
+ return value;
61
+ }
62
+ /** The overlay's answer for an entity it created, in `EntityData` shape. */
63
+ function createdEntityData(created, ref) {
64
+ return {
65
+ ref,
66
+ globalId: created.globalId,
67
+ name: created.name ?? '',
68
+ type: created.ifcType,
69
+ description: created.description ?? '',
70
+ // Slot 4 is `ObjectType` on an IfcObject but `ApplicableOccurrence` on an
71
+ // IfcTypeObject, so it is not read positionally. An `entity_set_attribute`
72
+ // override still lands, applied by the caller.
73
+ objectType: '',
74
+ };
75
+ }
76
+ /**
77
+ * One authored STEP attribute as a plain scalar, for `bim.attributes` on a
78
+ * created entity.
79
+ *
80
+ * **Not `stepText`.** That helper answers "is this text?", and deliberately says
81
+ * no to `#42` because its caller reads an entity's *Name* and must not mistake a
82
+ * reference for one. Reusing it here dropped every structural attribute an agent
83
+ * authored — `ObjectPlacement: '#40'` vanished from the readback (#2014). The
84
+ * fix belongs on this side of the line, not in `stepText`: a reference *is* the
85
+ * value of a structural attribute, and it is what will be serialised.
86
+ *
87
+ * Coercion mirrors the parsed path (`coerceRaw` in `@ifc-lite/query`) so a
88
+ * created entity and a parsed one report the same shapes: `$`/`*`/`.U.`/`.X.`
89
+ * are absent, `.T.`/`.F.` are booleans, other dotted tokens are bare enum names,
90
+ * quoted text is unquoted.
91
+ *
92
+ * Lists are skipped — and so are they on the parsed path, where `coerceRaw`
93
+ * answers null for an array. `EntityAttributeData.value` has no array form to
94
+ * put one in, and reporting a created entity's `RelatedElements` while a parsed
95
+ * entity's stays hidden would trade one inconsistency for another. The queued
96
+ * relationships those lists express are read back through `related()` instead,
97
+ * where they have somewhere to go.
98
+ */
99
+ function authoredValue(value) {
100
+ if (typeof value === 'number' || typeof value === 'boolean')
101
+ return value;
102
+ // The authoring API's wrapper forms (`StoreEditor.addEntity`).
103
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
104
+ const wrapper = value;
105
+ if (typeof wrapper.real === 'number')
106
+ return wrapper.real;
107
+ if (wrapper.typed && wrapper.typed.value !== undefined)
108
+ return wrapper.typed.value;
109
+ return undefined;
110
+ }
111
+ if (typeof value !== 'string')
112
+ return undefined;
113
+ const trimmed = value.trim();
114
+ if (trimmed === '' || trimmed === '$' || trimmed === '*')
115
+ return undefined;
116
+ if (trimmed === '.T.')
117
+ return true;
118
+ if (trimmed === '.F.')
119
+ return false;
120
+ if (trimmed === '.U.' || trimmed === '.X.')
121
+ return undefined;
122
+ if (trimmed.startsWith('#'))
123
+ return trimmed;
124
+ if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
125
+ return trimmed.slice(1, -1).replace(/''/g, "'");
126
+ }
127
+ if (trimmed.length >= 2 && trimmed.startsWith('.') && trimmed.endsWith('.'))
128
+ return trimmed.slice(1, -1);
129
+ return trimmed;
130
+ }
131
+ /**
132
+ * Build the query adapter over a store, folding whatever `overlay()` returns at
133
+ * call time. `overlay` is a getter, not a value: the backend creates its
134
+ * `MutablePropertyView` lazily on the first mutation, so a session that is only
135
+ * ever read gets `null` on every call and keeps the original store-only path.
136
+ */
137
+ export function createQueryAdapter(store, modelId, overlay) {
138
+ function entityData(ref) {
139
+ const pending = overlay();
140
+ if (pending?.deleted.has(ref.expressId))
141
+ return null;
142
+ const created = pending?.createdEntity(ref.expressId);
143
+ if (created)
144
+ return withOverrides(createdEntityData(created, ref), pending, ref.expressId);
145
+ if (!store.entityIndex.byId.has(ref.expressId))
146
+ return null;
147
+ const node = new EntityNode(store, ref.expressId);
148
+ const type = node.type;
149
+ if (!type || type === 'Unknown')
150
+ return null;
151
+ return withOverrides({
152
+ ref,
153
+ globalId: node.globalId,
154
+ name: node.name,
155
+ type,
156
+ description: node.description,
157
+ objectType: node.objectType,
158
+ }, pending, ref.expressId);
159
+ }
160
+ function withOverrides(data, pending, expressId) {
161
+ if (!pending)
162
+ return data;
163
+ const overrides = pending.attributes(expressId);
164
+ if (overrides.size === 0)
165
+ return data;
166
+ // `EntityData` has a slot for exactly these three; anything else the session
167
+ // wrote (`Tag`) reaches the caller through `attributes()` below, which
168
+ // carries the whole map.
169
+ return {
170
+ ...data,
171
+ name: overrides.get('Name') ?? data.name,
172
+ description: overrides.get('Description') ?? data.description,
173
+ objectType: overrides.get('ObjectType') ?? data.objectType,
174
+ };
175
+ }
176
+ function properties(ref, captured) {
177
+ // `captured` lets a caller that already has the overlay pass it in rather
178
+ // than have it rebuilt per entity — the filter loop in `entities()` runs
179
+ // this once per candidate row.
180
+ const pending = captured !== undefined ? captured : overlay();
181
+ // An entity this session deleted answers nothing, as `entityData` and
182
+ // `entities` already have it answer nothing (#2014 review).
183
+ if (pending?.deleted.has(ref.expressId))
184
+ return [];
185
+ // `getForEntity` reads the same on-demand extraction the store would, then
186
+ // applies the overlay on top — so it is the whole answer, not the delta.
187
+ const psets = pending
188
+ ? pending.propertySets(ref.expressId)
189
+ : new EntityNode(store, ref.expressId).properties();
190
+ return psets.map((pset) => ({
191
+ name: pset.name,
192
+ globalId: pset.globalId,
193
+ properties: pset.properties.map((p) => ({ name: p.name, type: p.type, value: p.value })),
194
+ }));
195
+ }
196
+ function quantities(ref) {
197
+ const pending = overlay();
198
+ if (pending?.deleted.has(ref.expressId))
199
+ return [];
200
+ const qsets = pending
201
+ ? pending.quantitySets(ref.expressId)
202
+ : new EntityNode(store, ref.expressId).quantities();
203
+ return qsets.map((qset) => ({
204
+ name: qset.name,
205
+ quantities: qset.quantities.map((q) => ({ name: q.name, type: q.type, value: q.value })),
206
+ }));
207
+ }
208
+ function attributes(ref) {
209
+ const pending = overlay();
210
+ if (pending?.deleted.has(ref.expressId))
211
+ return [];
212
+ const created = pending?.createdEntity(ref.expressId);
213
+ const base = created
214
+ // Not in the store, so there is nothing to extract: name the authored
215
+ // positional list from the schema instead. Cross-schema, because a created
216
+ // IFC2X3 or IFC4X3 class is not in the IFC4 codegen pin (#2003).
217
+ ? namedAuthoredAttributes(created)
218
+ : extractAllEntityAttributes(store, ref.expressId);
219
+ if (!pending)
220
+ return base;
221
+ const overrides = pending.attributes(ref.expressId);
222
+ if (overrides.size === 0)
223
+ return base;
224
+ // Overwrite what the base carries, then append what it does not. The append
225
+ // is the half that was missing (#2014): `extractAllEntityAttributes` omits
226
+ // an attribute whose stored value is `$`, so setting a previously-unset
227
+ // `Description` changed the top-level field while this list still denied it
228
+ // — one payload contradicting itself. Appended names go last; the list is
229
+ // name-keyed and its order is not positional (the base already drops nulls).
230
+ const merged = base.map((attr) => {
231
+ const written = overrides.get(attr.name);
232
+ return written === undefined ? attr : { ...attr, value: written };
233
+ });
234
+ const present = new Set(merged.map((attr) => attr.name));
235
+ for (const [name, value] of overrides) {
236
+ if (!present.has(name))
237
+ merged.push({ name, value });
238
+ }
239
+ return merged;
240
+ }
241
+ function namedAuthoredAttributes(created) {
242
+ // The *model's* schema, not the IFC4 pin. `IfcRelCoversSpaces` names slot 4
243
+ // `RelatedSpace` in IFC2X3 and `RelatingSpace` in IFC4, so the pinned answer
244
+ // reported a name the file would not serialise. Falls back to the parser's
245
+ // cross-schema list when the declared schema does not carry the class.
246
+ const names = attributeNamesForSchema(created.ifcType, store.schemaVersion);
247
+ const out = [];
248
+ for (let i = 0; i < created.attributes.length; i++) {
249
+ const value = authoredValue(created.attributes[i]);
250
+ if (value === undefined)
251
+ continue;
252
+ // No synthetic `Attribute7` names: `bim.attributes` is a list of IFC
253
+ // EXPRESS attribute names, and an invented one is not one. A payload
254
+ // longer than the schema knows about is the caller's to explain.
255
+ const name = names[i];
256
+ if (name === undefined)
257
+ continue;
258
+ out.push({ name, value });
259
+ }
260
+ return out;
261
+ }
262
+ return {
263
+ entities(descriptor) {
264
+ const pending = overlay();
265
+ const requested = descriptor.types && descriptor.types.length > 0
266
+ ? expandTypes(descriptor.types)
267
+ : null;
268
+ const entityIds = [];
269
+ if (requested) {
270
+ for (const type of requested) {
271
+ const typeIds = store.entityIndex.byType.get(type) ?? [];
272
+ for (const eid of typeIds)
273
+ entityIds.push(eid);
274
+ }
275
+ }
276
+ else {
277
+ for (const [typeName, ids] of store.entityIndex.byType) {
278
+ if (isProductType(typeName)) {
279
+ for (const eid of ids)
280
+ entityIds.push(eid);
281
+ }
282
+ }
283
+ }
284
+ const results = [];
285
+ for (const expressId of entityIds) {
286
+ if (expressId === 0)
287
+ continue;
288
+ if (pending?.deleted.has(expressId))
289
+ continue;
290
+ const node = new EntityNode(store, expressId);
291
+ results.push(withOverrides({
292
+ ref: { modelId, expressId },
293
+ globalId: node.globalId,
294
+ name: node.name,
295
+ type: node.type,
296
+ description: node.description,
297
+ objectType: node.objectType,
298
+ }, pending, expressId));
299
+ }
300
+ // Queued entities join the same result set under the same type rules, so
301
+ // an agent that creates a wall and then queries for walls finds it.
302
+ // `createdAll`, not `created`: `model_info` and `count_entities` count
303
+ // every queued entity, so a typed query over the same class has to list
304
+ // every one of them or the two contradict each other about what exists
305
+ // (#2014). A queued entity with no GlobalId is still an entity; callers
306
+ // address it by the `expressId` every row carries.
307
+ const wanted = requested ? new Set(requested) : null;
308
+ for (const created of pending?.createdAll ?? []) {
309
+ const key = created.ifcType.toUpperCase();
310
+ if (wanted ? !wanted.has(key) : !isProductType(key))
311
+ continue;
312
+ results.push(withOverrides(createdEntityData(created, { modelId, expressId: created.expressId }), pending, created.expressId));
313
+ }
314
+ let filtered = results;
315
+ if (descriptor.filters && descriptor.filters.length > 0) {
316
+ const propsCache = new Map();
317
+ const cachedProps = (ref) => {
318
+ let cached = propsCache.get(ref.expressId);
319
+ if (!cached) {
320
+ cached = properties(ref, pending);
321
+ propsCache.set(ref.expressId, cached);
322
+ }
323
+ return cached;
324
+ };
325
+ for (const filter of descriptor.filters) {
326
+ filtered = filtered.filter((entity) => {
327
+ const props = cachedProps(entity.ref);
328
+ const pset = props.find((p) => p.name === filter.psetName);
329
+ if (!pset)
330
+ return false;
331
+ const prop = pset.properties.find((p) => p.name === filter.propName);
332
+ if (!prop)
333
+ return false;
334
+ if (filter.operator === 'exists')
335
+ return true;
336
+ const v = normalizeBoolean(prop.value);
337
+ const f = normalizeBoolean(filter.value);
338
+ switch (filter.operator) {
339
+ case '=': return String(v) === String(f);
340
+ case '!=': return String(v) !== String(f);
341
+ case '>': return Number(v) > Number(f);
342
+ case '<': return Number(v) < Number(f);
343
+ case '>=': return Number(v) >= Number(f);
344
+ case '<=': return Number(v) <= Number(f);
345
+ case 'contains': return String(v).toLowerCase().includes(String(f).toLowerCase());
346
+ default: return false;
347
+ }
348
+ });
349
+ }
350
+ }
351
+ // `&&` alone lets a NaN offset/limit through silently: every NaN
352
+ // comparison is false, so `descriptor.offset > 0` was falsy and the
353
+ // guard did nothing -- a caller that computed a bad value (e.g.
354
+ // `Number(userInput)` on a non-numeric string) got back MORE rows
355
+ // than asked for, with no error. The same falsy-zero shape made
356
+ // `limit: 0` ("no rows") silently mean "every row" instead. Fail
357
+ // loudly on a non-finite or negative value instead of quietly
358
+ // serving the wrong slice, matching the misconfigured-caller
359
+ // convention this adapter already uses elsewhere (see the `add*`
360
+ // stubs in headless-backend.ts). `limit: 0` is now a deliberate
361
+ // empty result.
362
+ //
363
+ // No built-in MCP tool reaches this today: `query_entities`
364
+ // (tools/query.ts) validates `limit`/`offset` as JSON-Schema
365
+ // integers before its handler runs and does its own pagination via
366
+ // `paginate()` rather than chaining `.limit()/.offset()` on the
367
+ // query builder. This guards the public SDK path instead --
368
+ // `HeadlessLikeBackend` is exported from `./index.js` and
369
+ // `./browser.js` for programmatic use, and an embedder driving it
370
+ // through `@ifc-lite/sdk`'s fluent `QueryBuilder` reaches
371
+ // `descriptor.limit`/`descriptor.offset` directly. Same shape as
372
+ // the CLI's `headless-backend.ts` (#2298) -- a parallel
373
+ // implementation, not a shared import, so it needed its own fix.
374
+ if (descriptor.offset != null) {
375
+ if (!Number.isFinite(descriptor.offset) || descriptor.offset < 0) {
376
+ throw new Error(`Invalid offset: ${descriptor.offset} (must be a non-negative finite number)`);
377
+ }
378
+ if (descriptor.offset > 0)
379
+ filtered = filtered.slice(descriptor.offset);
380
+ }
381
+ if (descriptor.limit != null) {
382
+ if (!Number.isFinite(descriptor.limit) || descriptor.limit < 0) {
383
+ throw new Error(`Invalid limit: ${descriptor.limit} (must be a non-negative finite number)`);
384
+ }
385
+ filtered = filtered.slice(0, descriptor.limit);
386
+ }
387
+ return filtered;
388
+ },
389
+ // Headless contexts have no interactive viewer filter, so there is never an
390
+ // "active filter" to report (issue #1107).
391
+ entitiesMatchingActiveFilter: () => null,
392
+ entityData,
393
+ attributes,
394
+ properties: (ref) => properties(ref),
395
+ quantities,
396
+ classifications(ref) {
397
+ return extractClassificationsOnDemand(store, ref.expressId);
398
+ },
399
+ materials(ref) {
400
+ return extractMaterialsOnDemand(store, ref.expressId);
401
+ },
402
+ typeProperties(ref) {
403
+ const info = extractTypePropertiesOnDemand(store, ref.expressId);
404
+ if (!info)
405
+ return null;
406
+ return {
407
+ typeName: info.typeName,
408
+ typeId: info.typeId,
409
+ properties: info.properties.map((pset) => ({
410
+ name: pset.name,
411
+ globalId: pset.globalId,
412
+ properties: pset.properties.map((p) => ({ name: p.name, type: p.type, value: p.value })),
413
+ })),
414
+ };
415
+ },
416
+ documents(ref) {
417
+ return extractDocumentsOnDemand(store, ref.expressId);
418
+ },
419
+ relationships(ref) {
420
+ return extractRelationshipsOnDemand(store, ref.expressId);
421
+ },
422
+ /**
423
+ * Containment, aggregation and typing, with the session's queued edits
424
+ * applied (#2014).
425
+ *
426
+ * This is the seam every containment answer already passes through:
427
+ * `bim.storey`, `bim.path`, `bim.contains`, `bim.decomposes` and
428
+ * `bim.containedIn` are all thin wrappers over it. Folding here is what
429
+ * stopped `query_entities(in_storey)` from dropping an entity that the same
430
+ * session had just created *and* placed with a queued
431
+ * `IfcRelContainedInSpatialStructure` — a query that returns an entity
432
+ * without the filter and drops it with one reads as a wrong storey rather
433
+ * than a missing fold.
434
+ *
435
+ * Three rules, in order:
436
+ *
437
+ * 1. A parsed edge is dropped when the session deleted the `IfcRel…` record
438
+ * that produced it. The graph carries `relationshipId` per edge, so this
439
+ * is exact rather than inferred.
440
+ * 2. An edge to or from a tombstoned entity is dropped. Deleting a storey
441
+ * has to stop answering "this wall is in that storey".
442
+ * 3. Queued relationships are added. Deleting a queued relationship forgets
443
+ * it outright, so there is no tombstone case to handle on this side.
444
+ *
445
+ * `forward` walks Relating → Related (a storey to its elements, a whole to
446
+ * its parts); `inverse` walks back.
447
+ */
448
+ related(ref, relType, direction) {
449
+ const relEnum = REL_TYPE_MAP[relType];
450
+ if (relEnum === undefined)
451
+ return [];
452
+ const pending = overlay();
453
+ // A deleted entity relates to nothing. Filtering only the far end left it
454
+ // answering questions about itself (#2014 review).
455
+ if (pending?.deleted.has(ref.expressId))
456
+ return [];
457
+ const half = direction === 'forward' ? store.relationships.forward : store.relationships.inverse;
458
+ const out = [];
459
+ const seen = new Set();
460
+ const take = (expressId) => {
461
+ if (pending?.deleted.has(expressId) || seen.has(expressId))
462
+ return;
463
+ seen.add(expressId);
464
+ out.push(expressId);
465
+ };
466
+ for (const edge of half.getEdges(ref.expressId, relEnum)) {
467
+ if (pending?.deleted.has(edge.relationshipId))
468
+ continue;
469
+ take(edge.target);
470
+ }
471
+ for (const relation of pending?.queuedRelations(relType) ?? []) {
472
+ if (direction === 'forward') {
473
+ if (relation.relating !== ref.expressId)
474
+ continue;
475
+ for (const target of relation.related)
476
+ take(target);
477
+ }
478
+ else if (relation.related.includes(ref.expressId)) {
479
+ take(relation.relating);
480
+ }
481
+ }
482
+ return out.map((expressId) => ({ modelId: ref.modelId, expressId }));
483
+ },
484
+ };
485
+ }
486
+ //# sourceMappingURL=backend-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-query.js","sourceRoot":"","sources":["../src/backend-query.ts"],"names":[],"mappings":"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"}