@snaptrude/plugin-core 0.9.9 → 0.9.11

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 (34) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/api-manifest.json +76 -390
  3. package/dist/api/core/mode/index.d.ts +19 -7
  4. package/dist/api/core/mode/index.d.ts.map +1 -1
  5. package/dist/api/design/create/grids.d.ts +132 -0
  6. package/dist/api/design/create/grids.d.ts.map +1 -0
  7. package/dist/api/design/create/index.d.ts +109 -1
  8. package/dist/api/design/create/index.d.ts.map +1 -1
  9. package/dist/api/design/grids.d.ts +237 -0
  10. package/dist/api/design/grids.d.ts.map +1 -0
  11. package/dist/api/design/index.d.ts +4 -0
  12. package/dist/api/design/index.d.ts.map +1 -1
  13. package/dist/api/design/query/grids.d.ts +287 -0
  14. package/dist/api/design/query/grids.d.ts.map +1 -0
  15. package/dist/api/design/query/index.d.ts +29 -0
  16. package/dist/api/design/query/index.d.ts.map +1 -1
  17. package/dist/api/design/update/index.d.ts +74 -0
  18. package/dist/api/design/update/index.d.ts.map +1 -1
  19. package/dist/api/workspace/index.d.ts +49 -2
  20. package/dist/api/workspace/index.d.ts.map +1 -1
  21. package/dist/index.cjs +2163 -1968
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.js +2143 -1973
  24. package/dist/index.js.map +1 -1
  25. package/package.json +13 -13
  26. package/src/api/core/mode/index.ts +19 -7
  27. package/src/api/design/create/grids.ts +137 -0
  28. package/src/api/design/create/index.ts +131 -0
  29. package/src/api/design/grids.ts +237 -0
  30. package/src/api/design/index.ts +5 -0
  31. package/src/api/design/query/grids.ts +197 -0
  32. package/src/api/design/query/index.ts +27 -0
  33. package/src/api/design/update/index.ts +53 -0
  34. package/src/api/workspace/index.ts +51 -2
package/api-manifest.json CHANGED
@@ -4038,19 +4038,6 @@
4038
4038
  "argsType": "ComponentHandle",
4039
4039
  "resultType": "PluginCoreTagsGetTagsForComponentResult"
4040
4040
  },
4041
- {
4042
- "path": "core.tags.listForComponents",
4043
- "namespace": "core.tags",
4044
- "summary": "List the tags carried by many components in one call.",
4045
- "examplePrompts": [
4046
- "Get the tags of every space with their colors",
4047
- "List the tags on all rooms so I can color them by Occupancy",
4048
- "Which tag does each selected space carry?\n\n# Example\n```ts\nconst { components } = await snaptrude.core.tags.listForComponents()\nfor (const c of components) {\nconst occupancy = c.tags.find((t) => t.categoryName === \"Occupancy\")\nif (occupancy) paint(c.componentId, occupancy.color)\n}\n```"
4049
- ],
4050
- "argsType": "ComponentHandle[]",
4051
- "resultType": "PluginCoreTagsListForComponentsResult",
4052
- "performance": "One round-trip for any number of components — use this instead of a `listForComponent` loop."
4053
- },
4054
4041
  {
4055
4042
  "path": "core.tags.unassign",
4056
4043
  "namespace": "core.tags",
@@ -4312,27 +4299,10 @@
4312
4299
  "Put a door from the catalog at this point on the wall",
4313
4300
  "Insert the entrance door into this wall",
4314
4301
  "Add a door to the wall and call it Entry-01",
4315
- "Add a door that opens into the living room",
4316
- "Put a door here hinged on the north jamb\n\n# Example\n```ts\nconst [wall] = await snaptrude.design.query.listWalls({ isSelected: true })\nconst [entry] = await snaptrude.design.doors.listCatalog()\nconst door = await snaptrude.design.create.door(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\n{ label: \"Entry-01\" },\n)\n// …facing a specific side of the wall (pass a point inside that room):\nconst intoKitchen = await snaptrude.design.create.door(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\nundefined,\nawait snaptrude.core.math.vec3.new(3, 0, 9),\n)\n// …and hinged on the jamb nearest a point (here the +x end of the opening):\nconst hingedRight = await snaptrude.design.create.door(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\n{ hinge: await snaptrude.core.math.vec3.new(3.5, 0, 5) },\nawait snaptrude.core.math.vec3.new(3, 0, 9),\n)\n```"
4302
+ "Add a door that opens into the living room\n\n# Example\n```ts\nconst [wall] = await snaptrude.design.query.listWalls({ isSelected: true })\nconst [entry] = await snaptrude.design.doors.listCatalog()\nconst door = await snaptrude.design.create.door(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\n{ label: \"Entry-01\" },\n)\n// …facing a specific side of the wall (pass a point inside that room):\nconst intoKitchen = await snaptrude.design.create.door(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\nundefined,\nawait snaptrude.core.math.vec3.new(3, 0, 9),\n)\n```"
4317
4303
  ],
4318
4304
  "argsType": "string",
4319
- "resultType": "ComponentHandle",
4320
- "performance": "For MORE THAN ONE door, call `design.create.doors(items[])` — one host round-trip and ONE undo entry, with each host wall re-cut once per opening inside that single call. Looping this single-door creator is N round-trips."
4321
- },
4322
- {
4323
- "path": "design.create.doors",
4324
- "namespace": "design.create",
4325
- "summary": "Place **many doors** into host walls in one undoable operation (bulk plural of {@linkcode door}). Each item carries its own catalog id, host wall, world position, and optional `facing`, `label`, `width` and `height` — the same fields as a `\"door\"` {@linkcode PluginDesignCreateOpeningOptions}. Validate-all-or-throw; one command.",
4326
- "examplePrompts": [
4327
- "Add doors to all of these walls at once",
4328
- "Place a door in every room in one operation",
4329
- "Bulk add the entrance doors from this schedule",
4330
- "Put three doors on this wall in a single undo step",
4331
- "Add all the doors for this floor plan together"
4332
- ],
4333
- "argsType": "PluginCreateDoorItem[]",
4334
- "resultType": "ComponentHandle[]",
4335
- "performance": "Bulk creator — the whole batch is ONE host round-trip and ONE undo entry, and each distinct catalog source loads once. Always prefer this over calling `design.create.door` in a loop: build the full `items[]` array first (all host walls and points up front), then make one call. # Example ```ts const v = snaptrude.core.math.vec3 const [wall] = await snaptrude.design.query.listWalls({ isSelected: true }) const [entry] = await snaptrude.design.doors.listCatalog() const [front, side] = await snaptrude.design.create.doors([ { catalogId: entry.id, hostWall: wall, position: await v.new(2, 0, 5), label: \"D-01\" }, { catalogId: entry.id, hostWall: wall, position: await v.new(6, 0, 5), width: 1.2 }, ]) // `wall` was re-cut twice and no longer resolves — ask the opening for its host: const currentWall = await snaptrude.design.query.getHost(front) ```"
4305
+ "resultType": "ComponentHandle"
4336
4306
  },
4337
4307
  {
4338
4308
  "path": "design.create.floor",
@@ -4345,23 +4315,7 @@
4345
4315
  "Put a floor at this position with 150mm thickness\n\n# Example\n```ts\nconst rect = await snaptrude.core.geom.create.profileRect(5, 4)\nconst contour = await snaptrude.core.geom.create.contourFromProfile(rect)\nconst floor = await snaptrude.design.create.floor(contour, 0.1)\n```"
4346
4316
  ],
4347
4317
  "argsType": "ContourHandle",
4348
- "resultType": "ComponentHandle",
4349
- "performance": "For MORE THAN ONE floor, call `design.create.floors(items[])` — one host round-trip and ONE undo entry for the whole batch. Looping this single-floor creator is N round-trips and N undo entries."
4350
- },
4351
- {
4352
- "path": "design.create.floors",
4353
- "namespace": "design.create",
4354
- "summary": "Create **many floors** in one undoable operation (bulk plural of {@linkcode floor}). Each item extrudes its own footprint contour (outer profile + holes) upward by its own `thickness`, at its own optional position offset. Validate-all-or-throw; one command.",
4355
- "examplePrompts": [
4356
- "Create floors for all these room outlines at once",
4357
- "Add a floor to every space in one operation",
4358
- "Bulk create the floor plates for this building",
4359
- "Lay 100mm floors across these five footprints in one undo step",
4360
- "Create the ground and first floor slabs together"
4361
- ],
4362
- "argsType": "PluginCreateFloorItem[]",
4363
- "resultType": "ComponentHandle[]",
4364
- "performance": "Bulk creator — the whole batch is ONE host round-trip and ONE undo entry. Always prefer this over calling `design.create.floor` in a loop: build the full `items[]` array first (all contours and offsets up front), then make one call. # Example ```ts const rect = await snaptrude.core.geom.create.profileRect(5, 4) const contour = await snaptrude.core.geom.create.contourFromProfile(rect) const [ground, upper] = await snaptrude.design.create.floors([ { contour, thickness: 0.1 }, { contour, thickness: 0.1, position: await snaptrude.core.math.vec3.new(0, 3, 0) }, ]) ```"
4318
+ "resultType": "ComponentHandle"
4365
4319
  },
4366
4320
  {
4367
4321
  "path": "design.create.furniture",
@@ -4376,23 +4330,7 @@
4376
4330
  "Place a chair here rotated 90 degrees\n\n# Example\n```ts\nconst chair = await snaptrude.design.create.furniture(\n\"6620f1a…\", // from design.furniture.listCatalog()\nawait snaptrude.core.math.vec3.new(3, 0, 5),\n{ label: \"Chair-01\" },\n)\n// …placed already turned 90° about the vertical axis:\nconst turned = await snaptrude.design.create.furniture(\n\"6620f1a…\",\nawait snaptrude.core.math.vec3.new(3, 0, 5),\nundefined,\n90,\n)\n```"
4377
4331
  ],
4378
4332
  "argsType": "string",
4379
- "resultType": "ComponentHandle",
4380
- "performance": "For MORE THAN ONE item, call `design.create.furnitureItems(items[])` — one host round-trip and ONE undo entry, and a catalog source shared by several items is fetched once. Looping this single-item creator is N round-trips."
4381
- },
4382
- {
4383
- "path": "design.create.furnitureItems",
4384
- "namespace": "design.create",
4385
- "summary": "Place **many furniture items** in one undoable operation (bulk plural of {@linkcode furniture}). Each item names a catalog id and an absolute world position (`position.y` is the REST elevation — the same grounding contract as the singular creator), with optional label and rotation. A catalog source shared by several items is fetched and recorded once for the whole batch, so the host — not the caller — owns source persistence (there is no per-item `createNewSourceMesh`). Validate-all-or-throw; one command.",
4386
- "examplePrompts": [
4387
- "Place all the desks for this office at once",
4388
- "Furnish every bedroom in one operation",
4389
- "Bulk place these chairs around the table",
4390
- "Add the whole furniture layout in a single undo step",
4391
- "Drop twenty copies of this chair at these positions"
4392
- ],
4393
- "argsType": "PluginCreateFurnitureItem[]",
4394
- "resultType": "ComponentHandle[]",
4395
- "performance": "Bulk creator — the whole batch is ONE host round-trip and ONE undo entry, and each distinct catalog source loads once. Always prefer this over calling `design.create.furniture` in a loop: build the full `items[]` array first (all positions and angles up front), then make one call. # Example ```ts const v = snaptrude.core.math.vec3 const [chair] = await snaptrude.design.furniture.listCatalog() const placed = await snaptrude.design.create.furnitureItems([ { catalogId: chair.id, position: await v.new(3, 0, 5), label: \"Chair-01\" }, { catalogId: chair.id, position: await v.new(4, 0, 5), angleInDegrees: 90 }, { catalogId: chair.id, position: await v.new(5, 0, 5), angleInDegrees: 180 }, ]) ```"
4333
+ "resultType": "ComponentHandle"
4396
4334
  },
4397
4335
  {
4398
4336
  "path": "design.create.mass",
@@ -4429,7 +4367,7 @@
4429
4367
  ],
4430
4368
  "argsType": "PluginDesignCreateOpeningOptions",
4431
4369
  "resultType": "ComponentHandle",
4432
- "performance": "Single-opening creator — use it for one hosted opening. For MORE THAN ONE, call `design.create.doors(items[])` / `design.create.windows(items[])`: the same per-item fields, one host round-trip, ONE undo entry. # Example ```ts const opening = await snaptrude.design.create.opening({ kind: \"window\", catalogId: windowType.id, hostWall: wall, position: await snaptrude.core.math.vec3.new(3, 0, 5), width: 1.2, height: 1.5, sillHeight: 0.9, }) ```"
4370
+ "performance": "Single-opening creator — use it for one hosted opening. A plural API is intentionally unavailable until host placement can be atomic. # Example ```ts const opening = await snaptrude.design.create.opening({ kind: \"window\", catalogId: windowType.id, hostWall: wall, position: await snaptrude.core.math.vec3.new(3, 0, 5), width: 1.2, height: 1.5, sillHeight: 0.9, }) ```"
4433
4371
  },
4434
4372
  {
4435
4373
  "path": "design.create.referenceLines",
@@ -4475,13 +4413,12 @@
4475
4413
  {
4476
4414
  "path": "design.create.smartLayout",
4477
4415
  "namespace": "design.create",
4478
- "summary": "Place a **smart layout** — clone an in-scene template cluster (walls, furniture, doors, windows, floors) into one or more target ROOM/DEPARTMENT spaces, adapting orientation and fit to each target.",
4416
+ "summary": "Place a **smart layout** — apply a saved smart-layout template from the team/user library (walls, floors, spaces, furniture, doors, windows) onto one or more target ROOM/DEPARTMENT spaces, adapting orientation and fit to each target.",
4479
4417
  "examplePrompts": [
4480
- "Copy this room's layout into the selected rooms",
4481
- "Apply this furniture arrangement to the other offices",
4482
- "Replicate this template into these two spaces",
4483
- "Place this desk cluster into every meeting room",
4484
- "Use this room as a template for the rooms I selected but keep them visible\n\n# Example\n```ts\nconst [templateRoom, ...targets] = await snaptrude.design.query.listSpaces({ isSelected: true })\nconst result = await snaptrude.design.create.smartLayout({\ntemplateComponents: [templateRoom],\ntargets,\n})\nconsole.log(\"placed walls:\", result.created.walls.length, \"skipped:\", result.skippedWalls)\n\n// …or clone a saved group by its id (from core.groups.list)\nconst { groups } = await snaptrude.core.groups.list()\nawait snaptrude.design.create.smartLayout({ templateGroup: groups[0].id, targets })\n```"
4418
+ "Apply this saved layout template to the selected rooms",
4419
+ "Place the \"Meeting Room A\" template into these two spaces",
4420
+ "Fill every office with my saved desk-cluster layout",
4421
+ "Use a template from my library to lay out this room\n\n# Example\n```ts\nconst targets = await snaptrude.design.query.listSpaces({ isSelected: true })\nconst [template] = await snaptrude.design.smartLayouts.listCatalog()\nconst result = await snaptrude.design.create.smartLayout({\ntemplateId: template.id,\ntargets,\n})\nconsole.log(\"placed walls:\", result.created.walls.length, \"skipped:\", result.skippedWalls)\n```"
4485
4422
  ],
4486
4423
  "argsType": "PluginSmartLayoutArgs",
4487
4424
  "resultType": "PluginSmartLayoutResult"
@@ -4531,21 +4468,6 @@
4531
4468
  "argsType": "PluginStaircasePreset",
4532
4469
  "resultType": "ComponentHandle"
4533
4470
  },
4534
- {
4535
- "path": "design.create.wallRuns",
4536
- "namespace": "design.create",
4537
- "summary": "Create **many wall runs** in one undoable operation (bulk plural of {@linkcode walls}). Each item is one full run — a wall per curve in that item's profile chain, mitred at shared endpoints. Junctions resolve within a run, not between runs. Each item carries its own dimensions, `wallType` and `storey`, so a single call can build a whole floor plate or several storeys at once. Validate-all-or-throw; one command.",
4538
- "examplePrompts": [
4539
- "Draw all the walls of this floor plan at once",
4540
- "Build every room's perimeter in one operation",
4541
- "Bulk create wall runs from these centerlines",
4542
- "Create the walls for both storeys in a single undo step",
4543
- "Turn these polylines into 200mm brick walls together"
4544
- ],
4545
- "argsType": "PluginCreateWallRunItem[]",
4546
- "resultType": "ComponentHandle[][]",
4547
- "performance": "Bulk creator — the whole batch is ONE host round-trip and ONE undo entry. Always prefer this over calling `design.create.walls` in a loop: build the full `items[]` array first (all profiles up front), then make one call. # Example ```ts const v = snaptrude.core.math.vec3 const ground = await snaptrude.core.geom.create.profileFromLinePoints([ await v.new(0, 0, 0), await v.new(8, 0, 0), await v.new(8, 0, 6), ]) const upper = await snaptrude.core.geom.create.profileFromLinePoints([ await v.new(0, 0, 0), await v.new(8, 0, 0), ]) const [groundWalls, upperWalls] = await snaptrude.design.create.wallRuns([ { profile: ground, height: 3, thickness: 0.2 }, { profile: upper, height: 3, storey: 2 }, ]) console.log(groundWalls.length, \"walls on the ground floor\") ```"
4548
- },
4549
4471
  {
4550
4472
  "path": "design.create.walls",
4551
4473
  "namespace": "design.create",
@@ -4560,8 +4482,7 @@
4560
4482
  "Build the perimeter in exposed concrete walls\n\n# Example\n```ts\nconst v = snaptrude.core.math.vec3\nconst centerlines = await snaptrude.core.geom.create.profileFromLinePoints([\nawait v.new(0, 0, 0),\nawait v.new(8, 0, 0),\nawait v.new(8, 0, 6),\n])\nconst walls = await snaptrude.design.create.walls(centerlines, 3, 0.2)\n// …built as a specific wall type (layers/material/thickness from the type):\nconst [brick] = await snaptrude.design.types.list(\"wall\")\nconst brickWalls = await snaptrude.design.create.walls(\ncenterlines, 3, undefined, brick.label,\n)\n```"
4561
4483
  ],
4562
4484
  "argsType": "ProfileHandle",
4563
- "resultType": "ComponentHandle[]",
4564
- "performance": "For MORE THAN ONE run, call `design.create.wallRuns(items[])` — one host round-trip and ONE undo entry for every run in the batch. Looping this single-run creator is N round-trips and N undo entries."
4485
+ "resultType": "ComponentHandle[]"
4565
4486
  },
4566
4487
  {
4567
4488
  "path": "design.create.window",
@@ -4576,23 +4497,7 @@
4576
4497
  "Add a casement window opening toward the garden side\n\n# Example\n```ts\nconst [wall] = await snaptrude.design.query.listWalls({ isSelected: true })\nconst [entry] = await snaptrude.design.windows.listCatalog()\nconst window = await snaptrude.design.create.window(\nentry.id,\nwall,\nawait snaptrude.core.math.vec3.new(3, 0, 5),\n{ label: \"Win-01\" },\n)\n```"
4577
4498
  ],
4578
4499
  "argsType": "string",
4579
- "resultType": "ComponentHandle",
4580
- "performance": "For MORE THAN ONE window, call `design.create.windows(items[])` — one host round-trip and ONE undo entry, with each host wall re-cut once per opening inside that single call. Looping this single-window creator is N round-trips."
4581
- },
4582
- {
4583
- "path": "design.create.windows",
4584
- "namespace": "design.create",
4585
- "summary": "Place **many windows** into host walls in one undoable operation (bulk plural of {@linkcode window}). Each item carries its own catalog id, host wall, world position, and optional `facing`, `label`, `width`, `height` and `sillHeight` — the same fields as a `\"window\"` {@linkcode PluginDesignCreateOpeningOptions}. `sillHeight` is measured from the host wall base to the BOTTOM of the window. Validate-all-or-throw; one command.",
4586
- "examplePrompts": [
4587
- "Add windows along this whole facade at once",
4588
- "Place a window in every bedroom in one operation",
4589
- "Bulk add the windows from this schedule",
4590
- "Put four windows on this wall in a single undo step",
4591
- "Add all the windows with a 0.9m sill height together"
4592
- ],
4593
- "argsType": "PluginCreateWindowItem[]",
4594
- "resultType": "ComponentHandle[]",
4595
- "performance": "Bulk creator — the whole batch is ONE host round-trip and ONE undo entry, and each distinct catalog source loads once. Always prefer this over calling `design.create.window` in a loop: build the full `items[]` array first (all host walls and points up front), then make one call. # Example ```ts const v = snaptrude.core.math.vec3 const [wall] = await snaptrude.design.query.listWalls({ isSelected: true }) const [casement] = await snaptrude.design.windows.listCatalog() const placed = await snaptrude.design.create.windows([ { catalogId: casement.id, hostWall: wall, position: await v.new(2, 0, 5), sillHeight: 0.9 }, { catalogId: casement.id, hostWall: wall, position: await v.new(5, 0, 5), sillHeight: 0.9 }, ]) const currentWall = await snaptrude.design.query.getHost(placed[0]) ```"
4500
+ "resultType": "ComponentHandle"
4596
4501
  },
4597
4502
  {
4598
4503
  "path": "design.delete.entities",
@@ -4609,82 +4514,6 @@
4609
4514
  "resultType": "PluginDesignChangeResult",
4610
4515
  "performance": "Array delete — pass every target in one call (one host round-trip). There is no per-item delete; collect the whole set and never loop this per entity. # Example ```ts // Hard-delete every furniture item on storey 2 (a single undo entry) const furniture = await snaptrude.design.query.listFurniture({ storeys: [2] }) if (furniture.length > 0) { const { affected } = await snaptrude.design.delete.entities(furniture) } ```"
4611
4516
  },
4612
- {
4613
- "path": "design.dimensions.create",
4614
- "namespace": "design.dimensions",
4615
- "summary": "Draw one dimension line between two world points, anchored to a component.",
4616
- "examplePrompts": [
4617
- "Dimension every wall on level 2",
4618
- "Add a dimension line along this wall",
4619
- "Measure the width of this room and label it on the plan\n\n# Example\n```ts\nconst { design, core } = snaptrude\nconst v = core.math.vec3\nconst curve = core.geom.query.curve\nfor (const wall of await design.query.listWalls({ storeys: [2] })) {\nconst cl = await design.query.geometry.getCenterline(wall)\nif (!cl) continue\nconst a = await curve.getStartPoint(cl)\nconst b = await curve.getEndPoint(cl)\nawait design.dimensions.create(\nawait v.new(a.x, a.y, a.z),\nawait v.new(b.x, b.y, b.z),\nwall,\n)\n}\n```"
4620
- ],
4621
- "argsType": "Vec3Handle",
4622
- "resultType": "DimensionHandle"
4623
- },
4624
- {
4625
- "path": "design.dimensions.delete",
4626
- "namespace": "design.dimensions",
4627
- "summary": "Delete dimension lines — the same hard removal as selecting them and pressing Delete. Undoable as a **single** entry for the whole batch.",
4628
- "examplePrompts": [
4629
- "Remove all dimension lines",
4630
- "Delete the dimensions on this wall",
4631
- "Clear the measurements I added to level 2"
4632
- ],
4633
- "argsType": "DimensionHandle[]",
4634
- "resultType": "PluginDimensionsChangeResult",
4635
- "performance": "Array API — pass the whole set in one call (one host round-trip, one undo entry). Never loop this per dimension. # Example ```ts const dims = snaptrude.design.dimensions const onWall = await dims.list({ anchors: [wall] }) if (onWall.length > 0) await dims.delete(onWall.map((d) => d.id)) ```"
4636
- },
4637
- {
4638
- "path": "design.dimensions.get",
4639
- "namespace": "design.dimensions",
4640
- "summary": "Read one dimension line by handle.",
4641
- "examplePrompts": [
4642
- "Read the dimension line I just created",
4643
- "How long is this dimension and what does its label say?",
4644
- "Check whether that dimension line still exists\n\n# Example\n```ts\nconst dim = await snaptrude.design.dimensions.get(handle)\nif (dim) console.log(dim.label, dim.length, dim.storey)\n```"
4645
- ],
4646
- "argsType": "DimensionHandle",
4647
- "resultType": "PluginDimensionLine | null"
4648
- },
4649
- {
4650
- "path": "design.dimensions.hide",
4651
- "namespace": "design.dimensions",
4652
- "summary": "Hide dimension lines from the viewport — the same as the right-click \"Hide\" action (it sets the user Hide flag, `isHidden`). Undoable. Already-hidden dimensions are skipped and are not reported in `affected`.",
4653
- "examplePrompts": [
4654
- "Hide the dimensions on this storey",
4655
- "Hide every dimension line while I present",
4656
- "Temporarily hide the measurements on level 3"
4657
- ],
4658
- "argsType": "DimensionHandle[]",
4659
- "resultType": "PluginDimensionsChangeResult",
4660
- "performance": "Array API — one host round-trip and one undo entry for the whole set. # Example ```ts const dims = snaptrude.design.dimensions const onLevel3 = await dims.list({ storeys: [3] }) const { affected } = await dims.hide(onLevel3.map((d) => d.id)) ```"
4661
- },
4662
- {
4663
- "path": "design.dimensions.list",
4664
- "namespace": "design.dimensions",
4665
- "summary": "List the dimension lines in the project as full records.",
4666
- "examplePrompts": [
4667
- "List all the dimension lines in this model",
4668
- "Which dimensions are on level 3?",
4669
- "Flag any dimension line shorter than 600 mm"
4670
- ],
4671
- "argsType": "{\n storeys?: number[]\n anchors?: ComponentHandle[]\n isHidden?: boolean\n }",
4672
- "resultType": "PluginDimensionLine[]",
4673
- "performance": "Array read — one host round-trip returns every record. Filter in one call rather than calling `get` per dimension. # Example ```ts const units = snaptrude.core.units const min = await units.convert(600, \"millimeters\", await units.getBabylonType()) const short = (await snaptrude.design.dimensions.list()).filter( (d) => d.length < min, ) console.log(short.map((d) => `${d.label} on storey ${d.storey}`)) ```"
4674
- },
4675
- {
4676
- "path": "design.dimensions.show",
4677
- "namespace": "design.dimensions",
4678
- "summary": "Reveal hidden dimension lines — clear the user Hide flag, the inverse of {@linkcode PluginDesignDimensionsApi.hide}. Undoable. Already-visible dimensions are skipped and are not reported in `affected`.",
4679
- "examplePrompts": [
4680
- "Show the dimension lines again",
4681
- "Unhide all the hidden dimensions",
4682
- "Bring back the measurements I hid on this storey"
4683
- ],
4684
- "argsType": "DimensionHandle[]",
4685
- "resultType": "PluginDimensionsChangeResult",
4686
- "performance": "Array API — one host round-trip and one undo entry for the whole set. # Example ```ts const dims = snaptrude.design.dimensions const hidden = await dims.list({ isHidden: true }) await dims.show(hidden.map((d) => d.id)) ```"
4687
- },
4688
4517
  {
4689
4518
  "path": "design.doors.exists",
4690
4519
  "namespace": "design.doors",
@@ -4766,7 +4595,7 @@
4766
4595
  {
4767
4596
  "path": "design.doors.getSwingDirection",
4768
4597
  "namespace": "design.doors",
4769
- "summary": "Get a door's swing (hinge) handedness. Stand on the side the door swings open to, facing the door: `'left'` when the hinged jamb is on your left, `'right'` when it is on your right. Derived from the placed mesh's orientation (the same reflection `mirror` and the `hinge` placement option apply), not a persisted field.",
4598
+ "summary": "Get a door's swing (hinge) handedness — whether it opens as a left-hand or right-hand door. Derived from the door mesh's reflection state, not a persisted field.",
4770
4599
  "examplePrompts": [
4771
4600
  "Which way does this door swing?",
4772
4601
  "Is the selected door left-handed or right-handed?",
@@ -4831,13 +4660,13 @@
4831
4660
  {
4832
4661
  "path": "design.doors.mirror",
4833
4662
  "namespace": "design.doors",
4834
- "summary": "Mirror a door about its own axes. `'x'` (default) flips the swing side — the door opens to the other side of the wall; `'z'` swaps the hinged jamb (left-hand ↔ right-hand, same swing side); `'y'` turns it upside down. Undoable as a single command.",
4663
+ "summary": "Mirror a door across an axis, flipping its swing so it opens from the other side. Undoable as a single command.",
4835
4664
  "examplePrompts": [
4836
4665
  "Flip this door's swing",
4837
4666
  "Mirror the selected door",
4838
4667
  "Make this door open the other way",
4839
4668
  "Reverse the hinge side of the entrance door",
4840
- "Change the door to swing from the other side\n\n# Example\n```ts\n// Flip the selected door's swing side — axis defaults to \"x\"\nconst [door] = await snaptrude.design.query.listDoors({ isSelected: true })\nconst { affected } = await snaptrude.design.doors.mirror(door)\n// …or swap the hinged jamb instead (keeps the swing side)\nawait snaptrude.design.doors.mirror(door, \"z\")\n```"
4669
+ "Change the door to swing from the other side\n\n# Example\n```ts\n// Flip the selected door's swing — axis defaults to \"x\" (the swing-flip\n// axis); pass \"y\" or \"z\" to reflect across a different axis\nconst [door] = await snaptrude.design.query.listDoors({ isSelected: true })\nconst { affected } = await snaptrude.design.doors.mirror(door)\n```"
4841
4670
  ],
4842
4671
  "argsType": "ComponentHandle",
4843
4672
  "resultType": "PluginDesignChangeResult"
@@ -5842,6 +5671,67 @@
5842
5671
  "argsType": "PluginSelectionFilter",
5843
5672
  "resultType": "PluginDesignChangeResult"
5844
5673
  },
5674
+ {
5675
+ "path": "design.smartLayouts.create",
5676
+ "namespace": "design.smartLayouts",
5677
+ "summary": "**Create** a smart-layout template in the library from an in-scene component cluster (walls, floors, furniture, doors, windows) — the save side of `design.create.smartLayout`.",
5678
+ "examplePrompts": [
5679
+ "Save this room's layout as a template",
5680
+ "Add the selected furniture cluster to my template library",
5681
+ "Save this arrangement as \"Meeting Room A\" under Offices\n\n# Example\n```ts\nconst selected = await snaptrude.design.selection.list()\nconst item = await snaptrude.design.smartLayouts.create({\ncomponents: selected,\nname: \"Meeting Room A\",\n})\nconsole.log(\"saved:\", item.id, item.name)\n```"
5682
+ ],
5683
+ "argsType": "PluginSmartLayoutCreateArgs",
5684
+ "resultType": "PluginSmartLayoutCatalogItem"
5685
+ },
5686
+ {
5687
+ "path": "design.smartLayouts.exists",
5688
+ "namespace": "design.smartLayouts",
5689
+ "summary": "Test whether a saved smart-layout template exists for the given catalog id.",
5690
+ "examplePrompts": [
5691
+ "Is this layout template still in the library?",
5692
+ "Check whether this template id exists",
5693
+ "Verify the template is available before placing it\n\n# Example\n```ts\nconst [entry] = await snaptrude.design.smartLayouts.listCatalog()\nconst stillAvailable = await snaptrude.design.smartLayouts.exists(entry.id)\nconsole.log(stillAvailable ? \"safe to place\" : \"removed from library\")\n```"
5694
+ ],
5695
+ "argsType": "string",
5696
+ "resultType": "boolean"
5697
+ },
5698
+ {
5699
+ "path": "design.smartLayouts.getCatalogItem",
5700
+ "namespace": "design.smartLayouts",
5701
+ "summary": "Get a single saved smart-layout template by its catalog id.",
5702
+ "examplePrompts": [
5703
+ "Get the details of this saved layout template",
5704
+ "Look up the template with this id",
5705
+ "What's the floor area of this saved template?\n\n# Example\n```ts\nconst [entry] = await snaptrude.design.smartLayouts.listCatalog()\nconst item = await snaptrude.design.smartLayouts.getCatalogItem(entry.id)\nif (item) console.log(item.name, item.categoryId)\n```"
5706
+ ],
5707
+ "argsType": "string",
5708
+ "resultType": "PluginSmartLayoutCatalogItem | null"
5709
+ },
5710
+ {
5711
+ "path": "design.smartLayouts.listCatalog",
5712
+ "namespace": "design.smartLayouts",
5713
+ "summary": "List the saved smart-layout templates of the ambient library scope, optionally restricted to one category.",
5714
+ "examplePrompts": [
5715
+ "What layout templates can I place?",
5716
+ "List every saved smart layout in my library",
5717
+ "Show the templates in the \"Meeting Rooms\" category",
5718
+ "Browse the smart layout catalog\n\n# Example\n```ts\nconst items = await snaptrude.design.smartLayouts.listCatalog()\nfor (const item of items) console.log(item.id, item.name, item.area)\n```"
5719
+ ],
5720
+ "argsType": "string",
5721
+ "resultType": "PluginSmartLayoutCatalogItem[]"
5722
+ },
5723
+ {
5724
+ "path": "design.smartLayouts.listCatalogGroups",
5725
+ "namespace": "design.smartLayouts",
5726
+ "summary": "List the smart-layout template categories of the ambient library scope. The implicit `Default` bucket is always present and listed first; the rest follow alphabetically.",
5727
+ "examplePrompts": [
5728
+ "What smart layout categories does my library have?",
5729
+ "List the template categories",
5730
+ "Which buckets can I save a layout template into?\n\n# Example\n```ts\nconst groups = await snaptrude.design.smartLayouts.listCatalogGroups()\nfor (const g of groups) console.log(g.id, g.label)\n```"
5731
+ ],
5732
+ "argsType": null,
5733
+ "resultType": "PluginSmartLayoutCatalogGroup[]"
5734
+ },
5845
5735
  {
5846
5736
  "path": "design.transform.align",
5847
5737
  "namespace": "design.transform",
@@ -7675,18 +7565,6 @@
7675
7565
  "argsType": "string",
7676
7566
  "resultType": "PluginProgramDepartmentsSetTargetAreaResult"
7677
7567
  },
7678
- {
7679
- "path": "program.departments.setTargetCount",
7680
- "namespace": "program.departments",
7681
- "summary": "Set a department's target unit count.",
7682
- "examplePrompts": [
7683
- "Set the Bedrooms department unit count to 12",
7684
- "The program needs 4 clinic blocks — update the department count",
7685
- "Update the target count for department dep_123\n\n# Example\n```ts\nawait snaptrude.program.departments.setTargetCount(\"dep_123\", 12)\n```"
7686
- ],
7687
- "argsType": "string",
7688
- "resultType": "PluginProgramDepartmentsSetTargetCountResult"
7689
- },
7690
7568
  {
7691
7569
  "path": "program.departments.unassign",
7692
7570
  "namespace": "program.departments",
@@ -7713,65 +7591,6 @@
7713
7591
  "argsType": "string",
7714
7592
  "resultType": "PluginProgramDepartmentsUpdateResult"
7715
7593
  },
7716
- {
7717
- "path": "program.labels.create",
7718
- "namespace": "program.labels",
7719
- "summary": "Create labels (program rows), optionally creating their spaces too.",
7720
- "examplePrompts": [
7721
- "Add program rows for 4 exam rooms of 120 sqft each",
7722
- "Create the labels from this interpreted program",
7723
- "Add an Office label with a 2000 sqft target to the Admin department",
7724
- "Create program rows and their spaces on the canvas\n\n# Example\n```ts\nconst { labelIds } = await snaptrude.program.labels.create(\n[{ name: \"Exam Room\", targetArea: 480, targetCount: 4, departmentName: \"Clinic\" }],\n{ units: \"ft2\" },\n)\n```"
7725
- ],
7726
- "argsType": "PluginProgramLabelCreateItem[]",
7727
- "resultType": "PluginProgramLabelsCreateResult"
7728
- },
7729
- {
7730
- "path": "program.labels.get",
7731
- "namespace": "program.labels",
7732
- "summary": "Get a single label by id.",
7733
- "examplePrompts": [
7734
- "Get the label with id lbl_12",
7735
- "What is the target area of this program row?\n\n# Example\n```ts\nconst label = await snaptrude.program.labels.get(\"lbl_12\")\nif (label) console.log(label.name, label.targetArea, label.units)\n```"
7736
- ],
7737
- "argsType": "string",
7738
- "resultType": "PluginProgramLabelsGetResult"
7739
- },
7740
- {
7741
- "path": "program.labels.list",
7742
- "namespace": "program.labels",
7743
- "summary": "List the labels (program rows) of the active program.",
7744
- "examplePrompts": [
7745
- "List all the program rows with their target areas",
7746
- "What space labels are in the program and how many of each?",
7747
- "Show every label with its department and target\n\n# Example\n```ts\nconst { units, labels } = await snaptrude.program.labels.list()\nfor (const l of labels) console.log(l.name, l.targetArea, units, l.targetCount)\n```"
7748
- ],
7749
- "argsType": null,
7750
- "resultType": "PluginProgramLabelsListResult"
7751
- },
7752
- {
7753
- "path": "program.labels.setTargetArea",
7754
- "namespace": "program.labels",
7755
- "summary": "Set a label's total target area.",
7756
- "examplePrompts": [
7757
- "Set the Exam Room target area to 480 sqft",
7758
- "Give the Corridor program row a 150 sqm target",
7759
- "Update the area target for label lbl_12\n\n# Example\n```ts\nawait snaptrude.program.labels.setTargetArea(\"lbl_12\", 480, \"ft2\")\n```"
7760
- ],
7761
- "argsType": "string",
7762
- "resultType": "PluginProgramLabelsSetTargetAreaResult"
7763
- },
7764
- {
7765
- "path": "program.labels.setTargetCount",
7766
- "namespace": "program.labels",
7767
- "summary": "Set a label's target unit count (how many of this space the program calls for).",
7768
- "examplePrompts": [
7769
- "Set the Exam Room count to 6",
7770
- "The program needs 12 patient rooms — update the count\n\n# Example\n```ts\nawait snaptrude.program.labels.setTargetCount(\"lbl_12\", 6)\n```"
7771
- ],
7772
- "argsType": "string",
7773
- "resultType": "PluginProgramLabelsSetTargetCountResult"
7774
- },
7775
7594
  {
7776
7595
  "path": "program.layout.applySolution",
7777
7596
  "namespace": "program.layout",
@@ -7845,81 +7664,6 @@
7845
7664
  "argsType": null,
7846
7665
  "resultType": "PluginProgramLayoutStackResult"
7847
7666
  },
7848
- {
7849
- "path": "program.metadata.createHeader",
7850
- "namespace": "program.metadata",
7851
- "summary": "Create a metadata header (a custom column on the Program Data sheet).",
7852
- "examplePrompts": [
7853
- "Add a custom column called Occupancy to the program sheet",
7854
- "Create a metadata header named Department Code",
7855
- "Make a new program-mode column for Finish Level\n\n# Example\n```ts\nconst header = await snaptrude.program.metadata.createHeader(\"Occupancy\", {\ndescription: \"People per room\",\n})\n```"
7856
- ],
7857
- "argsType": "string",
7858
- "resultType": "PluginProgramMetadataCreateHeaderResult"
7859
- },
7860
- {
7861
- "path": "program.metadata.get",
7862
- "namespace": "program.metadata",
7863
- "summary": "Get one space's metadata values, keyed by header id.",
7864
- "examplePrompts": [
7865
- "Get the metadata on this space",
7866
- "Read the custom column values for space sp_12",
7867
- "What is this room's Occupancy metadata?\n\n# Example\n```ts\nconst record = await snaptrude.program.metadata.get(\"sp_12\")\nif (record) console.log(record.values)\n```"
7868
- ],
7869
- "argsType": "ComponentHandle",
7870
- "resultType": "PluginProgramMetadataGetResult"
7871
- },
7872
- {
7873
- "path": "program.metadata.list",
7874
- "namespace": "program.metadata",
7875
- "summary": "List metadata values for many spaces at once.",
7876
- "examplePrompts": [
7877
- "List the metadata of every space",
7878
- "Read the custom column values for all rooms",
7879
- "Get the metadata for these three spaces in one call\n\n# Example\n```ts\nconst { records } = await snaptrude.program.metadata.list()\nconst byId = Object.fromEntries(records.map((r) => [r.spaceId, r.values]))\n```"
7880
- ],
7881
- "argsType": "ComponentHandle[]",
7882
- "resultType": "PluginProgramMetadataListResult",
7883
- "performance": "One round-trip for any number of spaces — use this instead of a `get` loop."
7884
- },
7885
- {
7886
- "path": "program.metadata.listHeaders",
7887
- "namespace": "program.metadata",
7888
- "summary": "List the metadata headers (custom columns) of the Program Data sheet.",
7889
- "examplePrompts": [
7890
- "List the custom metadata columns in program mode",
7891
- "What metadata headers does the program sheet have?",
7892
- "Show every custom column with its id\n\n# Example\n```ts\nconst { headers } = await snaptrude.program.metadata.listHeaders()\nfor (const h of headers) console.log(h.headerId, h.name)\n```"
7893
- ],
7894
- "argsType": null,
7895
- "resultType": "PluginProgramMetadataListHeadersResult"
7896
- },
7897
- {
7898
- "path": "program.metadata.update",
7899
- "namespace": "program.metadata",
7900
- "summary": "Update a space's metadata values (sparse).",
7901
- "examplePrompts": [
7902
- "Set the Occupancy metadata of this space to 4",
7903
- "Store a department code on the selected rooms",
7904
- "Write custom column values onto space sp_12",
7905
- "Clear the Finish Level metadata on this space\n\n# Example\n```ts\nconst header = await snaptrude.program.metadata.createHeader(\"Occupancy\")\nawait snaptrude.program.metadata.update(\"sp_12\", { [header.headerId]: 4 })\n```"
7906
- ],
7907
- "argsType": "ComponentHandle",
7908
- "resultType": "PluginProgramMetadataUpdateResult"
7909
- },
7910
- {
7911
- "path": "program.metadata.updateMany",
7912
- "namespace": "program.metadata",
7913
- "summary": "Update metadata values on many spaces in one undoable step.",
7914
- "examplePrompts": [
7915
- "Fill the Occupancy column for all bedrooms",
7916
- "Write metadata onto every selected space at once",
7917
- "Bulk-update custom column values\n\n# Example\n```ts\nawait snaptrude.program.metadata.updateMany([\n{ spaceId: \"sp_12\", values: { [headerId]: 4 } },\n{ spaceId: \"sp_13\", values: { [headerId]: 2 } },\n])\n```"
7918
- ],
7919
- "argsType": "PluginProgramMetadataUpdateItem[]",
7920
- "resultType": "PluginProgramMetadataUpdateManyResult",
7921
- "performance": "One round-trip and one undo step for up to 1000 spaces — use this instead of an `update` loop."
7922
- },
7923
7667
  {
7924
7668
  "path": "program.metrics.get",
7925
7669
  "namespace": "program.metrics",
@@ -8158,19 +7902,6 @@
8158
7902
  "argsType": "{\n name?: string\n }",
8159
7903
  "resultType": "PluginProgramSpreadsheetBindingsRefreshResult"
8160
7904
  },
8161
- {
8162
- "path": "program.spreadsheet.createCustomSheet",
8163
- "namespace": "program.spreadsheet",
8164
- "summary": "Create a **custom program sheet** — a live view of the program grouped by a configurable hierarchy (the Program tab's \"Custom\" sheet with *Organize → Group by*).",
8165
- "examplePrompts": [
8166
- "Create a custom sheet grouped by department then sub-department",
8167
- "Make a program view grouped by storey and label",
8168
- "Build a grouped program sheet for the healthcare hierarchy",
8169
- "Add a custom sheet with a department → room type group-by\n\n# Example\n```ts\nconst { headers } = await snaptrude.program.metadata.listHeaders()\nconst subDept = headers.find((h) => h.name === \"Sub-department\")\nawait snaptrude.program.spreadsheet.createCustomSheet(\"Clinical Program\", {\ngroupBy: [\"departmentName\", subDept.headerId, \"label\"],\nproperties: [\"label\", \"count\", \"areas\", \"netAreaAchieved\"],\n})\n```"
8170
- ],
8171
- "argsType": "string",
8172
- "resultType": "PluginProgramSpreadsheetCustomSheetResult"
8173
- },
8174
7905
  {
8175
7906
  "path": "program.spreadsheet.createSheet",
8176
7907
  "namespace": "program.spreadsheet",
@@ -8236,17 +7967,6 @@
8236
7967
  "argsType": "{\n limit?: number\n }",
8237
7968
  "resultType": "PluginProgramSpreadsheetGetAuditLogResult"
8238
7969
  },
8239
- {
8240
- "path": "program.spreadsheet.getCustomSheet",
8241
- "namespace": "program.spreadsheet",
8242
- "summary": "Get a custom program sheet's configuration.",
8243
- "examplePrompts": [
8244
- "How is the Clinical Program sheet grouped?",
8245
- "Get the group-by configuration of this custom sheet\n\n# Example\n```ts\nconst cfg = await snaptrude.program.spreadsheet.getCustomSheet(\"Clinical Program\")\nif (cfg) console.log(cfg.groupBy, cfg.properties)\n```"
8246
- ],
8247
- "argsType": "string",
8248
- "resultType": "PluginProgramSpreadsheetGetCustomSheetResult"
8249
- },
8250
7970
  {
8251
7971
  "path": "program.spreadsheet.getMaterialTakeoff",
8252
7972
  "namespace": "program.spreadsheet",
@@ -8313,28 +8033,6 @@
8313
8033
  "argsType": "string",
8314
8034
  "resultType": "PluginProgramSpreadsheetHighlightCellsResult"
8315
8035
  },
8316
- {
8317
- "path": "program.spreadsheet.listCustomSheetProperties",
8318
- "namespace": "program.spreadsheet",
8319
- "summary": "List the property ids a custom program sheet can show as columns or group by.",
8320
- "examplePrompts": [
8321
- "What can I group a custom program sheet by?",
8322
- "List the columns available for a custom sheet\n\n# Example\n```ts\nconst { properties } = await snaptrude.program.spreadsheet.listCustomSheetProperties()\nconst groupable = properties.filter((p) => p.groupable).map((p) => p.id)\n```"
8323
- ],
8324
- "argsType": null,
8325
- "resultType": "PluginProgramSpreadsheetListCustomSheetPropertiesResult"
8326
- },
8327
- {
8328
- "path": "program.spreadsheet.listCustomSheets",
8329
- "namespace": "program.spreadsheet",
8330
- "summary": "List the custom program sheets in the workbook with their configurations.",
8331
- "examplePrompts": [
8332
- "List the custom program sheets",
8333
- "Which sheets are grouped program views?\n\n# Example\n```ts\nconst { sheets } = await snaptrude.program.spreadsheet.listCustomSheets()\n```"
8334
- ],
8335
- "argsType": null,
8336
- "resultType": "PluginProgramSpreadsheetListCustomSheetsResult"
8337
- },
8338
8036
  {
8339
8037
  "path": "program.spreadsheet.listSheets",
8340
8038
  "namespace": "program.spreadsheet",
@@ -8511,18 +8209,6 @@
8511
8209
  "argsType": "PluginSpreadsheetTransactionOp[]",
8512
8210
  "resultType": "PluginProgramSpreadsheetTransactionResult"
8513
8211
  },
8514
- {
8515
- "path": "program.spreadsheet.updateCustomSheet",
8516
- "namespace": "program.spreadsheet",
8517
- "summary": "Update a custom program sheet's group-by hierarchy, columns, or group colors.",
8518
- "examplePrompts": [
8519
- "Change the custom sheet to group by storey first",
8520
- "Add the Occupancy column to my grouped program sheet",
8521
- "Regroup the Clinical Program sheet by department only\n\n# Example\n```ts\nawait snaptrude.program.spreadsheet.updateCustomSheet(\"Clinical Program\", {\ngroupBy: [\"storey\", \"departmentName\"],\n})\n```"
8522
- ],
8523
- "argsType": "string",
8524
- "resultType": "PluginProgramSpreadsheetCustomSheetResult"
8525
- },
8526
8212
  {
8527
8213
  "path": "workspace.closePresentMode",
8528
8214
  "namespace": "workspace",