@snaptrude/plugin-core 0.8.0 → 0.9.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 (129) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/api-manifest.full.json +1350 -89
  3. package/api-manifest.json +1146 -48
  4. package/dist/api/analysis/daylight.d.ts +603 -0
  5. package/dist/api/analysis/daylight.d.ts.map +1 -0
  6. package/dist/api/analysis/heatmaps.d.ts +438 -14
  7. package/dist/api/analysis/heatmaps.d.ts.map +1 -1
  8. package/dist/api/analysis/index.d.ts +15 -0
  9. package/dist/api/analysis/index.d.ts.map +1 -1
  10. package/dist/api/analysis/solar.d.ts +249 -0
  11. package/dist/api/analysis/solar.d.ts.map +1 -0
  12. package/dist/api/analysis/weather.d.ts +193 -0
  13. package/dist/api/analysis/weather.d.ts.map +1 -0
  14. package/dist/api/core/camera/index.d.ts +37 -0
  15. package/dist/api/core/camera/index.d.ts.map +1 -1
  16. package/dist/api/core/geom/create/index.d.ts +318 -1
  17. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  18. package/dist/api/core/index.d.ts +9 -0
  19. package/dist/api/core/index.d.ts.map +1 -1
  20. package/dist/api/core/io/export/index.d.ts +3 -1
  21. package/dist/api/core/io/export/index.d.ts.map +1 -1
  22. package/dist/api/core/io/import/index.d.ts +61 -0
  23. package/dist/api/core/io/import/index.d.ts.map +1 -1
  24. package/dist/api/core/io/terrain/index.d.ts +132 -0
  25. package/dist/api/core/io/terrain/index.d.ts.map +1 -1
  26. package/dist/api/core/mode/index.d.ts +99 -0
  27. package/dist/api/core/mode/index.d.ts.map +1 -0
  28. package/dist/api/core/storeys/index.d.ts +251 -0
  29. package/dist/api/core/storeys/index.d.ts.map +1 -0
  30. package/dist/api/core/tags.d.ts +24 -0
  31. package/dist/api/core/tags.d.ts.map +1 -1
  32. package/dist/api/core/zoom/index.d.ts +4 -0
  33. package/dist/api/core/zoom/index.d.ts.map +1 -1
  34. package/dist/api/design/create/index.d.ts +115 -4
  35. package/dist/api/design/create/index.d.ts.map +1 -1
  36. package/dist/api/design/delete/index.d.ts +3 -0
  37. package/dist/api/design/delete/index.d.ts.map +1 -1
  38. package/dist/api/design/query/geometry/index.d.ts +112 -0
  39. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  40. package/dist/api/design/query/index.d.ts +4 -0
  41. package/dist/api/design/query/index.d.ts.map +1 -1
  42. package/dist/api/design/query/referenceLines.d.ts +45 -0
  43. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  44. package/dist/api/design/query/spaces.d.ts +173 -0
  45. package/dist/api/design/query/spaces.d.ts.map +1 -1
  46. package/dist/api/design/transform/index.d.ts +12 -0
  47. package/dist/api/design/transform/index.d.ts.map +1 -1
  48. package/dist/api/design/update/index.d.ts +51 -1
  49. package/dist/api/design/update/index.d.ts.map +1 -1
  50. package/dist/api/entity/buildableEnvelope.d.ts +4 -0
  51. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
  52. package/dist/api/entity/referenceLine.d.ts +8 -0
  53. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  54. package/dist/api/entity/story.d.ts +20 -0
  55. package/dist/api/entity/story.d.ts.map +1 -1
  56. package/dist/api/index.d.ts +5 -0
  57. package/dist/api/index.d.ts.map +1 -1
  58. package/dist/api/presentation/annotate.d.ts +23 -4
  59. package/dist/api/presentation/annotate.d.ts.map +1 -1
  60. package/dist/api/presentation/diagrams.d.ts +64 -2
  61. package/dist/api/presentation/diagrams.d.ts.map +1 -1
  62. package/dist/api/presentation/export.d.ts +4 -0
  63. package/dist/api/presentation/export.d.ts.map +1 -1
  64. package/dist/api/presentation/import.d.ts +6 -0
  65. package/dist/api/presentation/import.d.ts.map +1 -1
  66. package/dist/api/presentation/index.d.ts +20 -1
  67. package/dist/api/presentation/index.d.ts.map +1 -1
  68. package/dist/api/presentation/placedViews.d.ts +1139 -0
  69. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  70. package/dist/api/presentation/shapes.d.ts +481 -0
  71. package/dist/api/presentation/shapes.d.ts.map +1 -0
  72. package/dist/api/presentation/sheets.d.ts +42 -0
  73. package/dist/api/presentation/sheets.d.ts.map +1 -1
  74. package/dist/api/presentation/slideshow.d.ts +125 -0
  75. package/dist/api/presentation/slideshow.d.ts.map +1 -0
  76. package/dist/api/presentation/tables.d.ts +81 -0
  77. package/dist/api/presentation/tables.d.ts.map +1 -0
  78. package/dist/api/program/site.d.ts +260 -2
  79. package/dist/api/program/site.d.ts.map +1 -1
  80. package/dist/api/program/spreadsheet.d.ts +260 -28
  81. package/dist/api/program/spreadsheet.d.ts.map +1 -1
  82. package/dist/api/workspace/index.d.ts +505 -0
  83. package/dist/api/workspace/index.d.ts.map +1 -0
  84. package/dist/index.cjs +2904 -1761
  85. package/dist/index.cjs.map +1 -1
  86. package/dist/index.js +2762 -1761
  87. package/dist/index.js.map +1 -1
  88. package/package.json +3 -2
  89. package/scripts/generate-manifest.mjs +45 -0
  90. package/src/api/analysis/daylight.ts +470 -0
  91. package/src/api/analysis/heatmaps.ts +444 -17
  92. package/src/api/analysis/index.ts +15 -0
  93. package/src/api/analysis/solar.ts +237 -0
  94. package/src/api/analysis/weather.ts +179 -0
  95. package/src/api/core/camera/index.ts +39 -0
  96. package/src/api/core/geom/create/index.ts +344 -1
  97. package/src/api/core/index.ts +9 -0
  98. package/src/api/core/io/export/index.ts +3 -1
  99. package/src/api/core/io/import/index.ts +64 -0
  100. package/src/api/core/io/terrain/index.ts +143 -0
  101. package/src/api/core/mode/index.ts +96 -0
  102. package/src/api/core/storeys/index.ts +279 -0
  103. package/src/api/core/tags.ts +27 -0
  104. package/src/api/core/zoom/index.ts +4 -0
  105. package/src/api/design/create/index.ts +138 -1
  106. package/src/api/design/delete/index.ts +3 -0
  107. package/src/api/design/query/geometry/index.ts +125 -3
  108. package/src/api/design/query/index.ts +4 -0
  109. package/src/api/design/query/referenceLines.ts +52 -0
  110. package/src/api/design/query/spaces.ts +143 -0
  111. package/src/api/design/transform/index.ts +12 -0
  112. package/src/api/design/update/index.ts +66 -1
  113. package/src/api/entity/buildableEnvelope.ts +4 -0
  114. package/src/api/entity/referenceLine.ts +8 -0
  115. package/src/api/entity/story.ts +20 -0
  116. package/src/api/index.ts +5 -0
  117. package/src/api/presentation/annotate.ts +27 -2
  118. package/src/api/presentation/diagrams.ts +67 -2
  119. package/src/api/presentation/export.ts +4 -0
  120. package/src/api/presentation/import.ts +6 -0
  121. package/src/api/presentation/index.ts +20 -1
  122. package/src/api/presentation/placedViews.ts +1120 -0
  123. package/src/api/presentation/shapes.ts +274 -0
  124. package/src/api/presentation/sheets.ts +54 -0
  125. package/src/api/presentation/slideshow.ts +134 -0
  126. package/src/api/presentation/tables.ts +84 -0
  127. package/src/api/program/site.ts +205 -2
  128. package/src/api/program/spreadsheet.ts +251 -6
  129. package/src/api/workspace/index.ts +563 -0
package/api-manifest.json CHANGED
@@ -1,4 +1,30 @@
1
1
  [
2
+ {
3
+ "path": "analysis.daylight.compute",
4
+ "namespace": "analysis.daylight",
5
+ "summary": "Compute annual daylight metrics for the model's spaces.",
6
+ "examplePrompts": [
7
+ "Run an LM-83 ASE daylight analysis on all my spaces",
8
+ "Which rooms fail annual sunlight exposure?",
9
+ "Compute ASE with a 0.6m sensor grid at desk height",
10
+ "Run an LM-83 sDA analysis with blinds operated",
11
+ "Which spaces meet sDA300/50%?",
12
+ "Compute sDA with 70% reflective ceilings and Tvis 0.6 glazing\n\n# Example\n```ts\nlet res = await snaptrude.analysis.daylight.compute({\nstandard: \"IES-LM-83-23\",\nmetrics: [\"sDA\", \"ASE\"],\ngrid: { spacingM: 0.6, workplaneHeightM: 0.76, boundaryOffsetM: 0.5 },\noptics: { materials: { \"Glass - Clear\": { transmittance: 0.6 } } },\n})\nconst runId = res.runId\nwhile (res.status === \"running\" && runId) {\nawait new Promise((r) => setTimeout(r, 5000))\nres = await snaptrude.analysis.daylight.poll({ runId })\n}\nconst failing = res.aggregates.filter(\n(a) => a.scope === \"space\" && (a.sdaPercent ?? 0) < 55,\n)\n```"
13
+ ],
14
+ "argsType": "PluginDaylightComputeArgs",
15
+ "resultType": "PluginDaylightResults"
16
+ },
17
+ {
18
+ "path": "analysis.daylight.poll",
19
+ "namespace": "analysis.daylight",
20
+ "summary": "Poll an asynchronous daylight run started by {@linkcode PluginAnalysisDaylightApi.compute}.",
21
+ "examplePrompts": [
22
+ "Check whether my sDA run has finished",
23
+ "Get the results of the daylight run"
24
+ ],
25
+ "argsType": "PluginDaylightPollArgs",
26
+ "resultType": "PluginDaylightResults"
27
+ },
2
28
  {
3
29
  "path": "analysis.heatmaps.isActive",
4
30
  "namespace": "analysis.heatmaps",
@@ -11,6 +37,79 @@
11
37
  "argsType": null,
12
38
  "resultType": "boolean"
13
39
  },
40
+ {
41
+ "path": "analysis.heatmaps.overlays.hide",
42
+ "namespace": "analysis.heatmaps.overlays",
43
+ "summary": "Hide an overlay without removing it.",
44
+ "examplePrompts": [
45
+ "Hide the wind overlay but keep it around",
46
+ "Temporarily hide my heatmap",
47
+ "Turn off the occupancy colours without deleting them\n\n# Example\n```ts\nawait snaptrude.analysis.heatmaps.overlays.hide(\"wind\")\n```"
48
+ ],
49
+ "argsType": "string",
50
+ "resultType": "boolean"
51
+ },
52
+ {
53
+ "path": "analysis.heatmaps.overlays.list",
54
+ "namespace": "analysis.heatmaps.overlays",
55
+ "summary": "List the registered heatmap overlays.",
56
+ "examplePrompts": [
57
+ "Which heatmap overlays do I have?",
58
+ "List my rendered analysis overlays",
59
+ "Check which heatmap is currently visible\n\n# Example\n```ts\nconst { overlays } = await snaptrude.analysis.heatmaps.overlays.list()\nconst visible = overlays.find((o) => o.visible)\n```"
60
+ ],
61
+ "argsType": null,
62
+ "resultType": "PluginAnalysisHeatmapOverlaysListResult"
63
+ },
64
+ {
65
+ "path": "analysis.heatmaps.overlays.remove",
66
+ "namespace": "analysis.heatmaps.overlays",
67
+ "summary": "Remove an overlay — dispose its meshes and forget it.",
68
+ "examplePrompts": [
69
+ "Delete the wind overlay",
70
+ "Remove my occupancy heatmap for good",
71
+ "Free up an overlay slot\n\n# Example\n```ts\nawait snaptrude.analysis.heatmaps.overlays.remove(\"wind\")\n```"
72
+ ],
73
+ "argsType": "string",
74
+ "resultType": "boolean"
75
+ },
76
+ {
77
+ "path": "analysis.heatmaps.overlays.removeAll",
78
+ "namespace": "analysis.heatmaps.overlays",
79
+ "summary": "Remove every registered overlay and close the legend.",
80
+ "examplePrompts": [
81
+ "Clear all my heatmap overlays",
82
+ "Remove every analysis overlay from the scene",
83
+ "Start over with a clean set of overlays\n\n# Example\n```ts\nconst removed = await snaptrude.analysis.heatmaps.overlays.removeAll()\n```"
84
+ ],
85
+ "argsType": null,
86
+ "resultType": "number"
87
+ },
88
+ {
89
+ "path": "analysis.heatmaps.overlays.show",
90
+ "namespace": "analysis.heatmaps.overlays",
91
+ "summary": "Make a registered overlay the visible one.",
92
+ "examplePrompts": [
93
+ "Switch back to my wind heatmap",
94
+ "Show the occupancy overlay",
95
+ "Flip between my two analysis overlays\n\n# Example\n```ts\nawait snaptrude.analysis.heatmaps.overlays.show(\"wind\")\n```"
96
+ ],
97
+ "argsType": "string",
98
+ "resultType": "boolean"
99
+ },
100
+ {
101
+ "path": "analysis.heatmaps.renderField",
102
+ "namespace": "analysis.heatmaps",
103
+ "summary": "Render a heatmap from **arbitrary cell geometry** — planar polygons or pre-tessellated meshes, one scalar value each.",
104
+ "examplePrompts": [
105
+ "Overlay my FEA stress results on their solver mesh",
106
+ "Color these Voronoi regions by footfall",
107
+ "Paint each façade panel polygon by its PV yield",
108
+ "Render pass/fail daylight compliance per zone polygon\n\n# Example\n```ts\n// Two triangular cells at ground level, coloured pass/fail at 300 lux.\nawait snaptrude.analysis.heatmaps.renderField(\n[\n{ polygon: [{ x: 0, y: 0, z: 0 }, { x: 4, y: 0, z: 0 }, { x: 0, y: 0, z: 4 }], value: 420 },\n{ polygon: [{ x: 4, y: 0, z: 4 }, { x: 0, y: 0, z: 4 }, { x: 4, y: 0, z: 0 }], value: 180 },\n],\n{ title: \"Daylight\", unit: \"lux\", scale: { type: \"threshold\", threshold: 300 } },\n)\n```"
109
+ ],
110
+ "argsType": "PluginAnalysisHeatmapFieldCell[]",
111
+ "resultType": "PluginAnalysisHeatmapsRenderResult"
112
+ },
14
113
  {
15
114
  "path": "analysis.heatmaps.renderGrid",
16
115
  "namespace": "analysis.heatmaps",
@@ -35,10 +134,23 @@
35
134
  "argsType": "PluginAnalysisHeatmapSpaceEntry[]",
36
135
  "resultType": "PluginAnalysisHeatmapsRenderResult"
37
136
  },
137
+ {
138
+ "path": "analysis.heatmaps.renderSurfaceGrid",
139
+ "namespace": "analysis.heatmaps",
140
+ "summary": "Render a grid heatmap on an **arbitrarily oriented plane** — a façade, a section cut, any flat surface.",
141
+ "examplePrompts": [
142
+ "Paint the solar irradiance results on the south façade",
143
+ "Show my daylight values as a heatmap on this wall",
144
+ "Render panel-level PV yield on the building face",
145
+ "Overlay wind pressure on the tower's west elevation\n\n# Example\n```ts\n// Samples lie on a wall plane facing +X; colour each 1-unit cell by irradiance.\nawait snaptrude.analysis.heatmaps.renderSurfaceGrid(\nsamples.map((s) => ({ position: { x: wallX, y: s.y, z: s.z }, value: s.irradiance })),\n1,\n{ x: 1, y: 0, z: 0 }, // façade normal\n{ title: \"Irradiance\", unit: \"kWh/m²\", colors: [\"#0000ff\", \"#ffff00\", \"#ff0000\"] },\n)\n```"
146
+ ],
147
+ "argsType": "PluginAnalysisHeatmapGridCell[]",
148
+ "resultType": "PluginAnalysisHeatmapsRenderResult"
149
+ },
38
150
  {
39
151
  "path": "analysis.heatmaps.reset",
40
152
  "namespace": "analysis.heatmaps",
41
- "summary": "Clear the plugin heatmap from the scene.",
153
+ "summary": "Clear every plugin heatmap overlay from the scene.",
42
154
  "examplePrompts": [
43
155
  "Clear my custom heatmap",
44
156
  "Remove the wind overlay from the model",
@@ -155,6 +267,18 @@
155
267
  "argsType": "string",
156
268
  "resultType": "PluginAnalysisShadowsDateTimeResult"
157
269
  },
270
+ {
271
+ "path": "analysis.solar.sampleGrid",
272
+ "namespace": "analysis.solar",
273
+ "summary": "Sample solar exposure at a set of points.",
274
+ "examplePrompts": [
275
+ "What's the irradiance at these facade points at noon on June 21?",
276
+ "How shaded are these balcony points across the summer?",
277
+ "Sample direct sun visibility at these roof points right now\n\n# Example\n```ts\nconst grid = await snaptrude.analysis.solar.sampleGrid({\npoints: [\n{ id: \"a\", position: [0, 3, 0] },\n{ id: \"b\", position: [5, 3, 0], normal: [0, 0, 1] },\n],\ndateTime: \"2026-06-21T12:00:00+05:30\",\n})\nfor (const r of grid.results) {\nconsole.log(r.id, r.directSunVisible, r.totalIrradiance, grid.units)\n}\n```"
278
+ ],
279
+ "argsType": "PluginSolarSampleGridArgs",
280
+ "resultType": "PluginSolarSampleGridResult"
281
+ },
158
282
  {
159
283
  "path": "analysis.sunlightHours.cancel",
160
284
  "namespace": "analysis.sunlightHours",
@@ -239,6 +363,18 @@
239
363
  "argsType": null,
240
364
  "resultType": "boolean"
241
365
  },
366
+ {
367
+ "path": "analysis.weather.getSeries",
368
+ "namespace": "analysis.weather",
369
+ "summary": "Get the hourly weather series for a date range, paged.",
370
+ "examplePrompts": [
371
+ "Get the weather series for June at my site",
372
+ "Pull the hourly temperature and irradiance for this location",
373
+ "What EPW weather file is my project using?\n\n# Example\n```ts\nlet cursor: string | undefined = undefined\nconst rows = []\ndo {\nconst page = await snaptrude.analysis.weather.getSeries({\nstartDate: \"2026-06-01\",\nendDate: \"2026-06-30\",\ncursor,\n})\nrows.push(...page.rows)\ncursor = page.nextCursor ?? undefined\n} while (cursor)\n```"
374
+ ],
375
+ "argsType": "PluginWeatherGetSeriesArgs",
376
+ "resultType": "PluginWeatherSeriesResult"
377
+ },
242
378
  {
243
379
  "path": "core.buildings.copy",
244
380
  "namespace": "core.buildings",
@@ -412,6 +548,32 @@
412
548
  "argsType": "PluginStandardView",
413
549
  "resultType": "boolean"
414
550
  },
551
+ {
552
+ "path": "core.camera.zoomExtents",
553
+ "namespace": "core.camera",
554
+ "summary": "Zoom (fit) the camera to all geometry in the scene — the \"zoom extents\" action. View-state only — not undoable. Canonical home of the zoom-extents read (the deprecated `core.zoom.extents`).",
555
+ "examplePrompts": [
556
+ "Zoom out so I can see the whole model",
557
+ "Fit everything in the view",
558
+ "Frame the entire building in the viewport",
559
+ "Do a zoom extents on the canvas\n\n# Example\n```ts\nawait snaptrude.core.camera.zoomExtents()\n```"
560
+ ],
561
+ "argsType": null,
562
+ "resultType": "boolean"
563
+ },
564
+ {
565
+ "path": "core.camera.zoomSelection",
566
+ "namespace": "core.camera",
567
+ "summary": "Zoom (fit) the camera to the current selection. View-state only — not undoable. Canonical home of the zoom-to-selection read (the deprecated `core.zoom.selection`).",
568
+ "examplePrompts": [
569
+ "Zoom in on what I have selected",
570
+ "Frame the selected walls in the view",
571
+ "Focus the camera on my current selection",
572
+ "Fit the view to the selected room\n\n# Example\n```ts\nawait snaptrude.core.camera.zoomSelection()\n```"
573
+ ],
574
+ "argsType": null,
575
+ "resultType": "boolean"
576
+ },
415
577
  {
416
578
  "path": "core.comment.create",
417
579
  "namespace": "core.comment",
@@ -553,6 +715,90 @@
553
715
  "argsType": "Vec3Handle",
554
716
  "resultType": "ArcHandle"
555
717
  },
718
+ {
719
+ "path": "core.geom.create.brepFromExtrusion",
720
+ "namespace": "core.geom.create",
721
+ "summary": "Create a closed solid **B-rep** by extruding a contour along a direction. Host API call — returns a {@linkcode BrepHandle}. The direction is normalised by the host, so `amount` is the extrusion distance in raw Babylon units (negative extrudes the opposite way). The contour is copied — the input handle is never mutated. Holes and arc/circle profiles extrude natively (a circle profile yields a cylinder).",
722
+ "examplePrompts": [
723
+ "Extrude this profile 3 metres up",
724
+ "Make a solid by extruding this outline",
725
+ "Create a cylinder from a circle profile\n\n# Example\n```ts\nconst rect = await snaptrude.core.geom.create.profileRect(4, 3)\nconst contour = await snaptrude.core.geom.create.contourFromProfile(rect)\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst faceCount = await snaptrude.core.geom.query.brep.getFaceCount(brep) // 6\n```"
726
+ ],
727
+ "argsType": "ContourHandle",
728
+ "resultType": "BrepHandle"
729
+ },
730
+ {
731
+ "path": "core.geom.create.brepFromFaces",
732
+ "namespace": "core.geom.create",
733
+ "summary": "Create a closed solid **B-rep** from explicit face loops. Host API call — returns a {@linkcode BrepHandle}. Faces are plain arrays of `{x, y, z}` point components, NOT point handles (bulk-data precedent: `design.query.geometry.getTriangulatedMeshes`), in raw Babylon units.",
734
+ "examplePrompts": [
735
+ "Create a brep from faces",
736
+ "Build a custom solid from a set of faces",
737
+ "Make a pyramid from triangular faces\n\n# Example\n```ts\n// A pyramid: square base + 4 triangular sides\nconst apex = { x: 0, y: 4, z: 0 }\nconst a = { x: -2, y: 0, z: -2 }\nconst b = { x: 2, y: 0, z: -2 }\nconst c = { x: 2, y: 0, z: 2 }\nconst d = { x: -2, y: 0, z: 2 }\nconst brep = await snaptrude.core.geom.create.brepFromFaces([\n[a, d, c, b], // base\n[a, b, apex],\n[b, c, apex],\n[c, d, apex],\n[d, a, apex],\n])\nconst faceCount = await snaptrude.core.geom.query.brep.getFaceCount(brep) // 5\n```"
738
+ ],
739
+ "argsType": "Vec3Components[][]",
740
+ "resultType": "BrepHandle"
741
+ },
742
+ {
743
+ "path": "core.geom.create.brepFromIntersection",
744
+ "namespace": "core.geom.create",
745
+ "summary": "Create a closed solid **B-rep** as the boolean **intersection** of two breps (`a ∩ b` — the shared volume only). Host API call — returns a new {@linkcode BrepHandle}. Inputs are read-only and may be authored or scene-derived breps (see {@linkcode PluginGeomCreateApi.brepFromUnion}); coordinates are combined as-is.",
746
+ "examplePrompts": [
747
+ "Keep only the overlap of these two solids",
748
+ "Intersect these two masses",
749
+ "Clip the tower to the zoning envelope\n\n# Example\n```ts\nconst overlap = await snaptrude.core.geom.create.brepFromIntersection(towerBrep, envelopeBrep)\n```"
750
+ ],
751
+ "argsType": "BrepHandle",
752
+ "resultType": "BrepHandle"
753
+ },
754
+ {
755
+ "path": "core.geom.create.brepFromLoft",
756
+ "namespace": "core.geom.create",
757
+ "summary": "Create a closed solid **B-rep** by lofting between a bottom and a top contour. Host API call — returns a {@linkcode BrepHandle}. Both contours must have the same number of edges (and matching hole counts); side faces connect corresponding edges by authored index. Corresponding edges must stay coplanar — a twisted loft would produce non-planar side faces and is rejected. The contours are copied — the input handles are never mutated.",
758
+ "examplePrompts": [
759
+ "Make a tapered tower from these two outlines",
760
+ "Loft between a large base and a smaller top",
761
+ "Create a frustum from two squares\n\n# Example\n```ts\n// A square frustum: 4m base lofted to a 2m top, 3m up\nconst base = await snaptrude.core.geom.create.profileRect(4, 4)\nconst top = await snaptrude.core.geom.create.profileRect(2, 2, await snaptrude.core.math.vec3.new(0, 3, 0))\nconst brep = await snaptrude.core.geom.create.brepFromLoft(\nawait snaptrude.core.geom.create.contourFromProfile(base),\nawait snaptrude.core.geom.create.contourFromProfile(top),\n)\nconst faceCount = await snaptrude.core.geom.query.brep.getFaceCount(brep) // 6\n```"
762
+ ],
763
+ "argsType": "ContourHandle",
764
+ "resultType": "BrepHandle"
765
+ },
766
+ {
767
+ "path": "core.geom.create.brepFromMesh",
768
+ "namespace": "core.geom.create",
769
+ "summary": "Create a closed solid **B-rep** from indexed mesh data: a vertex position array plus face loops of indices into it. Host API call — returns a {@linkcode BrepHandle}. The indexed form of {@linkcode PluginGeomCreateApi.brepFromFaces} — same validation (planar faces, closed manifold solid, every edge shared by exactly two faces) after the indices are expanded to point loops.",
770
+ "examplePrompts": [
771
+ "Create a brep from mesh vertices and indices",
772
+ "Turn this indexed mesh into a solid",
773
+ "Build a solid from vertex positions and face indices\n\n# Example\n```ts\n// A tetrahedron from 4 vertices and 4 triangular faces\nconst positions = [\n{ x: 0, y: 0, z: 0 },\n{ x: 4, y: 0, z: 0 },\n{ x: 2, y: 0, z: 4 },\n{ x: 2, y: 3, z: 1.5 },\n]\nconst brep = await snaptrude.core.geom.create.brepFromMesh(positions, [\n[0, 2, 1], // base\n[0, 1, 3],\n[1, 2, 3],\n[2, 0, 3],\n])\nconst vertexCount = await snaptrude.core.geom.query.brep.getVertexCount(brep) // 4\n```"
774
+ ],
775
+ "argsType": "Vec3Components[]",
776
+ "resultType": "BrepHandle"
777
+ },
778
+ {
779
+ "path": "core.geom.create.brepFromSubtraction",
780
+ "namespace": "core.geom.create",
781
+ "summary": "Create a closed solid **B-rep** as the boolean **subtraction** of two breps: **`a` minus `b`** — `b` is cut away from `a`. Host API call — returns a new {@linkcode BrepHandle}. Argument order matters: `brepFromSubtraction(a, b)` removes `b`'s volume from `a`. Inputs are read-only and may be authored or scene-derived breps (see {@linkcode PluginGeomCreateApi.brepFromUnion}); coordinates are combined as-is.",
782
+ "examplePrompts": [
783
+ "Subtract the courtyard from the building mass",
784
+ "Cut this solid out of that one",
785
+ "Punch a hole through the slab with this box\n\n# Example\n```ts\n// buildingBrep minus courtyardBrep — order matters\nconst carved = await snaptrude.core.geom.create.brepFromSubtraction(buildingBrep, courtyardBrep)\n```"
786
+ ],
787
+ "argsType": "BrepHandle",
788
+ "resultType": "BrepHandle"
789
+ },
790
+ {
791
+ "path": "core.geom.create.brepFromUnion",
792
+ "namespace": "core.geom.create",
793
+ "summary": "Create a closed solid **B-rep** as the boolean **union** of two breps (`a ∪ b`). Host API call — returns a new {@linkcode BrepHandle}. Inputs are read-only and may be authored breps (any `core.geom.create` brep constructor) or scene-derived breps from `design.query.geometry.getBrep`; coordinates are combined as-is, so both inputs must share a frame. The result must be a single solid — disjoint inputs are rejected.",
794
+ "examplePrompts": [
795
+ "Union these two solids",
796
+ "Merge these breps into one mass",
797
+ "Combine the tower and the podium into a single solid\n\n# Example\n```ts\nconst a = await snaptrude.core.geom.create.brepFromExtrusion(baseContour, { x: 0, y: 1, z: 0 }, 3)\nconst b = await snaptrude.core.geom.create.brepFromExtrusion(overlappingContour, { x: 0, y: 1, z: 0 }, 5)\nconst merged = await snaptrude.core.geom.create.brepFromUnion(a, b)\n```"
798
+ ],
799
+ "argsType": "BrepHandle",
800
+ "resultType": "BrepHandle"
801
+ },
556
802
  {
557
803
  "path": "core.geom.create.circle",
558
804
  "namespace": "core.geom.create",
@@ -632,7 +878,8 @@
632
878
  "summary": "Free a transient contour resource handle — releases its registry entry and reclaims its share of the plugin's resource quota. Handle-lifecycle only; does NOT tear down engine-side geometry, nor the contour's child profile handles.",
633
879
  "examplePrompts": [],
634
880
  "argsType": "ContourHandle",
635
- "resultType": "void"
881
+ "resultType": "void",
882
+ "deprecated": "core.handles.release"
636
883
  },
637
884
  {
638
885
  "path": "core.geom.delete.profile",
@@ -640,7 +887,8 @@
640
887
  "summary": "Free a transient profile resource handle — releases its registry entry and reclaims its share of the plugin's resource quota. This is a handle-lifecycle operation only and does NOT tear down any engine-side geometry.",
641
888
  "examplePrompts": [],
642
889
  "argsType": "ProfileHandle",
643
- "resultType": "void"
890
+ "resultType": "void",
891
+ "deprecated": "core.handles.release"
644
892
  },
645
893
  {
646
894
  "path": "core.geom.query.arc.getAxis",
@@ -2220,6 +2468,18 @@
2220
2468
  "argsType": "string",
2221
2469
  "resultType": "ImportJobHandle"
2222
2470
  },
2471
+ {
2472
+ "path": "core.io.import.epw",
2473
+ "namespace": "core.io.import",
2474
+ "summary": "Import an **EPW weather file** into the project's weather catalog.",
2475
+ "examplePrompts": [
2476
+ "Import this EPW weather file for the site",
2477
+ "Upload a custom weather file for the daylight analysis",
2478
+ "Use this .epw as the project's weather source\n\n# Example\n```ts\nconst { weatherFileId, label } = await snaptrude.core.io.import.epw(\n\"https://example.com/Chicago-OHare.epw\",\n)\nconsole.log(`Weather set to ${label} (${weatherFileId})`)\n```"
2479
+ ],
2480
+ "argsType": "string",
2481
+ "resultType": "PluginImportEpwResult"
2482
+ },
2223
2483
  {
2224
2484
  "path": "core.io.import.image",
2225
2485
  "namespace": "core.io.import",
@@ -2490,6 +2750,19 @@
2490
2750
  "argsType": null,
2491
2751
  "resultType": "boolean | null"
2492
2752
  },
2753
+ {
2754
+ "path": "core.io.terrain.replaceMesh",
2755
+ "namespace": "core.io.terrain",
2756
+ "summary": "Replace the terrain surface with a caller-supplied triangle mesh. Undoable (one step), and the replacement persists with the project.",
2757
+ "examplePrompts": [
2758
+ "Replace the terrain with this surveyed mesh",
2759
+ "Flatten a building pad into the site surface",
2760
+ "Load a custom DEM surface onto the terrain",
2761
+ "Regrade the terrain from these points\n\n# Example\n```ts\n// Projects with no terrain yet: import first, then replace.\nif (!(await snaptrude.core.io.terrain.exists())) {\nawait snaptrude.core.io.import.terrain(40.7128, -74.006, 300, 300)\n}\nconst result = await snaptrude.core.io.terrain.replaceMesh(\npositions, // [x0, y0, z0, x1, y1, z1, …] — world space\nindices, // [a0, b0, c0, a1, b1, c1, …]\n\"meters\",\n{\ncoordinateSpace: \"world\",\nexpectedTerrain: await snaptrude.core.io.terrain.get(),\nbaseline: \"make-replacement-original\",\npreserve: { datum: true, geolocation: true, satellite: true, material: true },\nclientMutationId: \"survey-2026-08-05-r1\",\n},\n)\n// result.modelRevision — pass back as expectedModelRevision on the next call\n```"
2762
+ ],
2763
+ "argsType": "number[]",
2764
+ "resultType": "PluginTerrainReplaceMeshResult"
2765
+ },
2493
2766
  {
2494
2767
  "path": "core.io.terrain.setDatum",
2495
2768
  "namespace": "core.io.terrain",
@@ -2923,6 +3196,41 @@
2923
3196
  "argsType": "Vec3Handle",
2924
3197
  "resultType": "Vec3Handle"
2925
3198
  },
3199
+ {
3200
+ "path": "core.mode.get",
3201
+ "namespace": "core.mode",
3202
+ "summary": "Get the currently active application mode.",
3203
+ "examplePrompts": [
3204
+ "Which mode am I in right now?",
3205
+ "Am I in present mode?",
3206
+ "Check whether the editor is in BIM mode\n\n# Example\n```ts\nconst mode = await snaptrude.core.mode.get()\nif (mode !== \"present\") await snaptrude.core.mode.set(\"present\")\n```"
3207
+ ],
3208
+ "argsType": null,
3209
+ "resultType": "PluginAppMode"
3210
+ },
3211
+ {
3212
+ "path": "core.mode.list",
3213
+ "namespace": "core.mode",
3214
+ "summary": "List every application mode the editor has.",
3215
+ "examplePrompts": [
3216
+ "What modes does Snaptrude have?",
3217
+ "List the editor modes I can switch to\n\n# Example\n```ts\nconst { modes } = await snaptrude.core.mode.list()\n// [\"design\", \"bim\", \"present\", \"program\"]\n```"
3218
+ ],
3219
+ "argsType": null,
3220
+ "resultType": "PluginCoreModeListResult"
3221
+ },
3222
+ {
3223
+ "path": "core.mode.set",
3224
+ "namespace": "core.mode",
3225
+ "summary": "Switch the editor to another application mode — the same action as clicking that tab in the top menu bar.",
3226
+ "examplePrompts": [
3227
+ "Switch to present mode",
3228
+ "Open BIM mode",
3229
+ "Go back to design mode\n\n# Example\n```ts\nawait snaptrude.core.mode.set(\"present\")\n// ... presentation work ...\nawait snaptrude.core.mode.set(\"design\")\n```"
3230
+ ],
3231
+ "argsType": "PluginAppMode",
3232
+ "resultType": "PluginCoreModeSetResult"
3233
+ },
2926
3234
  {
2927
3235
  "path": "core.project.settings.getTolerance",
2928
3236
  "namespace": "core.project.settings",
@@ -3292,6 +3600,98 @@
3292
3600
  "argsType": "string",
3293
3601
  "resultType": "PluginCoreProposalsSetActiveResult"
3294
3602
  },
3603
+ {
3604
+ "path": "core.storeys.copy",
3605
+ "namespace": "core.storeys",
3606
+ "summary": "Copy a storey into the adjacent level, up or down.",
3607
+ "examplePrompts": [
3608
+ "Copy this floor to the storey above",
3609
+ "Copy the ground floor down into a new basement",
3610
+ "Repeat this level upwards with its own independent geometry",
3611
+ "Copy just the selected walls onto the next floor up\n\n# Example\n```ts\n// Copy the whole active storey one level up (instanced copies).\nconst { targetStories, created, skipped } =\nawait snaptrude.core.storeys.copy(\"up\")\nconsole.log(`Copied ${created.length} elements onto storey ${targetStories}`)\nif (skipped) console.log(`${skipped} elements were skipped`)\n```"
3612
+ ],
3613
+ "argsType": "\"up\" | \"down\"",
3614
+ "resultType": "PluginStoryDuplicateResult"
3615
+ },
3616
+ {
3617
+ "path": "core.storeys.create",
3618
+ "namespace": "core.storeys",
3619
+ "summary": "Create a new storey (floor) in the project.",
3620
+ "examplePrompts": [
3621
+ "Add a third floor to the building",
3622
+ "Create a new storey above the second floor",
3623
+ "Add a basement level to this project",
3624
+ "Insert a new level with a custom floor height\n\n# Example\n```ts\n// Create a new third floor with custom height\nconst { storyId } = await snaptrude.core.storeys.create(3, 4.5)\n```"
3625
+ ],
3626
+ "argsType": "number",
3627
+ "resultType": "PluginStoryCreateResult"
3628
+ },
3629
+ {
3630
+ "path": "core.storeys.delete",
3631
+ "namespace": "core.storeys",
3632
+ "summary": "Delete a storey and everything on it — the same as removing it from the storey panel. Every element placed on the storey (walls, floors, masses, …) is deleted with it, the remaining storeys are re-stacked, and the active storey falls back to an adjacent one. Committed as a single undo step.",
3633
+ "examplePrompts": [
3634
+ "Delete the top floor",
3635
+ "Remove the basement level",
3636
+ "Get rid of storey 3",
3637
+ "Delete the second floor and everything on it\n\n# Example\n```ts\nconst { newActiveStory } = await snaptrude.core.storeys.delete(3)\nconsole.log(`Deleted storey 3; now on storey ${newActiveStory}`)\n```"
3638
+ ],
3639
+ "argsType": "number",
3640
+ "resultType": "PluginStoryDeleteResult"
3641
+ },
3642
+ {
3643
+ "path": "core.storeys.get",
3644
+ "namespace": "core.storeys",
3645
+ "summary": "Get properties of a storey by its storey number.",
3646
+ "examplePrompts": [
3647
+ "What is the height of the ground floor?",
3648
+ "How many rooms are on the second storey?",
3649
+ "Get the total floor area of level 3",
3650
+ "Is the first floor hidden in the viewport?",
3651
+ "Show me the name and height of storey 2\n\n# Example\n```ts\nconst info = await snaptrude.core.storeys.get(1, [\"height\", \"name\", \"spacesCount\"])\nconsole.log(info.name, info.height, info.spacesCount)\n```"
3652
+ ],
3653
+ "argsType": "number",
3654
+ "resultType": "PluginStoryGetResult"
3655
+ },
3656
+ {
3657
+ "path": "core.storeys.list",
3658
+ "namespace": "core.storeys",
3659
+ "summary": "List all storeys in the current project.",
3660
+ "examplePrompts": [
3661
+ "How many floors does this building have?",
3662
+ "List all the storeys in the project",
3663
+ "Show me every level with its name",
3664
+ "Which storeys exist in this model?\n\n# Example\n```ts\nconst { storeys } = await snaptrude.core.storeys.list()\nfor (const s of storeys) {\nconsole.log(`Storey ${s.value}: ${s.name} (id: ${s.id})`)\n}\n```"
3665
+ ],
3666
+ "argsType": null,
3667
+ "resultType": "PluginCoreStoreysListResult"
3668
+ },
3669
+ {
3670
+ "path": "core.storeys.setActive",
3671
+ "namespace": "core.storeys",
3672
+ "summary": "Make a storey the active storey — the same as clicking it in the storey/layer panel. Subsequent draws and creates target this storey, and in 2D the viewport switches to it. This is a view/navigation change: it is **not** undoable and commits nothing to the model.",
3673
+ "examplePrompts": [
3674
+ "Switch to the second floor",
3675
+ "Make the ground storey active",
3676
+ "Go to the basement level",
3677
+ "Set level 3 as the current storey\n\n# Example\n```ts\n// Activate storey 2, then draw a wall — it lands on storey 2.\nawait snaptrude.core.storeys.setActive(2)\n```"
3678
+ ],
3679
+ "argsType": "number",
3680
+ "resultType": "PluginStorySetActiveResult"
3681
+ },
3682
+ {
3683
+ "path": "core.storeys.update",
3684
+ "namespace": "core.storeys",
3685
+ "summary": "Update a storey's floor-to-floor `height` and/or `name`.",
3686
+ "examplePrompts": [
3687
+ "Change the ground floor height to 3.5 metres",
3688
+ "Make the second storey taller",
3689
+ "Rename the ground floor to \"Lobby\"",
3690
+ "Set the floor-to-floor height of level 1\n\n# Example\n```ts\n// Set ground floor height to 5 Babylon units — walls stretch and the\n// floors above move up to match, all in a single undo step.\nconst result = await snaptrude.core.storeys.update(1, 5)\n// Rename only, leaving the height untouched.\nawait snaptrude.core.storeys.update(1, undefined, { name: \"Lobby\" })\n```"
3691
+ ],
3692
+ "argsType": "number",
3693
+ "resultType": "PluginStoryUpdateResult"
3694
+ },
3295
3695
  {
3296
3696
  "path": "core.tags.assign",
3297
3697
  "namespace": "core.tags",
@@ -3386,7 +3786,8 @@
3386
3786
  "Show the labels applied to this room\n\n# Example\n```ts\nconst { tags } = await snaptrude.core.tags.getTagsForComponent(\"cmp_42\")\nfor (const t of tags) console.log(t.categoryName, t.tagName)\n```"
3387
3787
  ],
3388
3788
  "argsType": "ComponentHandle",
3389
- "resultType": "PluginCoreTagsGetTagsForComponentResult"
3789
+ "resultType": "PluginCoreTagsGetTagsForComponentResult",
3790
+ "deprecated": "core.tags.listForComponent"
3390
3791
  },
3391
3792
  {
3392
3793
  "path": "core.tags.list",
@@ -3424,6 +3825,18 @@
3424
3825
  "argsType": "{ tagId?: string; categoryId?: string; untagged?: boolean }",
3425
3826
  "resultType": "PluginCoreTagsListComponentsResult"
3426
3827
  },
3828
+ {
3829
+ "path": "core.tags.listForComponent",
3830
+ "namespace": "core.tags",
3831
+ "summary": "List the tags carried by a component.",
3832
+ "examplePrompts": [
3833
+ "What tags does this space have?",
3834
+ "List the tags on component cmp_42",
3835
+ "Show the labels applied to this room\n\n# Example\n```ts\nconst { tags } = await snaptrude.core.tags.listForComponent(\"cmp_42\")\nfor (const t of tags) console.log(t.categoryName, t.tagName)\n```"
3836
+ ],
3837
+ "argsType": "ComponentHandle",
3838
+ "resultType": "PluginCoreTagsGetTagsForComponentResult"
3839
+ },
3427
3840
  {
3428
3841
  "path": "core.tags.unassign",
3429
3842
  "namespace": "core.tags",
@@ -3550,7 +3963,8 @@
3550
3963
  "Show me the full scene\n\n# Example\n```ts\nawait snaptrude.core.zoom.extents()\n```"
3551
3964
  ],
3552
3965
  "argsType": null,
3553
- "resultType": "boolean"
3966
+ "resultType": "boolean",
3967
+ "deprecated": "core.camera.zoomExtents"
3554
3968
  },
3555
3969
  {
3556
3970
  "path": "core.zoom.selection",
@@ -3563,7 +3977,8 @@
3563
3977
  "Fit the view to the selected room\n\n# Example\n```ts\nawait snaptrude.core.zoom.selection()\n```"
3564
3978
  ],
3565
3979
  "argsType": null,
3566
- "resultType": "boolean"
3980
+ "resultType": "boolean",
3981
+ "deprecated": "core.camera.zoomSelection"
3567
3982
  },
3568
3983
  {
3569
3984
  "path": "design.boolean.intersect",
@@ -3619,6 +4034,19 @@
3619
4034
  "argsType": "ContourHandle",
3620
4035
  "resultType": "ComponentHandle"
3621
4036
  },
4037
+ {
4038
+ "path": "design.create.buildableEnvelope",
4039
+ "namespace": "design.create",
4040
+ "summary": "Create a new parametric buildable envelope — the zoning-regulated volume a building may occupy — generated from a site polygon, tiered setbacks, a height or floor-count cap, and optional FAR and lot-coverage limits. The host mints the envelope id and returns it. Canonical home of the create formerly at `entity.buildableEnvelope.create` (now deprecated).",
4041
+ "examplePrompts": [
4042
+ "Create a buildable envelope for my site",
4043
+ "Generate the zoning envelope with 10ft front setbacks",
4044
+ "Show the maximum buildable volume with a 150ft height limit",
4045
+ "Create a zoning envelope capped at 12 floors with FAR 3\n\n# Example\n```ts\nconst { buildableEnvelopeId } = await snaptrude.design.create.buildableEnvelope(\n[\n{ x: 0, z: 0 },\n{ x: 100, z: 0 },\n{ x: 100, z: 80 },\n{ x: 0, z: 80 },\n],\n\"ft\",\n[\n{ aboveHeight: 0, front: 10, side: 5, rear: 10 },\n{ aboveHeight: 100, front: 20, side: 10, rear: 20 },\n],\n{ kind: \"max_height\", maxHeight: 150 },\n12,\n)\n```"
4046
+ ],
4047
+ "argsType": "PluginBuildableEnvelopePolygonVertex[]",
4048
+ "resultType": "PluginBuildableEnvelopeCreateResult"
4049
+ },
3622
4050
  {
3623
4051
  "path": "design.create.ceiling",
3624
4052
  "namespace": "design.create",
@@ -3654,10 +4082,11 @@
3654
4082
  "Duplicate the selected furniture along the X axis",
3655
4083
  "Make 5 copies of this column at 4 metre intervals",
3656
4084
  "Array these walls with a 3m offset",
3657
- "Clone the desk as a unique copy, not an instance\n\n# Example\n```ts\nconst { vec3 } = snaptrude.core.math\nconst copies = await snaptrude.design.create.copy([\"space-id\"], vec3.new(6, 0, 0), { count: 3 })\n```"
4085
+ "Clone the desk as a unique copy, not an instance"
3658
4086
  ],
3659
4087
  "argsType": "ComponentHandle[]",
3660
- "resultType": "ComponentHandle[]"
4088
+ "resultType": "ComponentHandle[]",
4089
+ "performance": "To place N repeats of the same geometry, bulk-create the seed(s) once then call this ONCE with `{ count: N - 1 }` — one host round-trip for all copies. Never reproduce geometry by looping `design.create.*` N times. Copy only after the create that mints the seed ids. # Example ```ts const { vec3 } = snaptrude.core.math const copies = await snaptrude.design.create.copy([\"space-id\"], vec3.new(6, 0, 0), { count: 3 }) ```"
3661
4090
  },
3662
4091
  {
3663
4092
  "path": "design.create.door",
@@ -3715,6 +4144,18 @@
3715
4144
  "argsType": "ContourHandle",
3716
4145
  "resultType": "ComponentHandle"
3717
4146
  },
4147
+ {
4148
+ "path": "design.create.massFromBrep",
4149
+ "namespace": "design.create",
4150
+ "summary": "Create a **mass** from a custom solid built with a `core.geom.create` brep constructor (`brepFromFaces`, `brepFromExtrusion`, `brepFromLoft`, `brepFromMesh`, or a brep boolean) — the free-form counterpart of {@linkcode PluginDesignCreateApi.mass}, for solids that are not simple footprint extrusions (pyramids, wedges, faceted volumes).",
4151
+ "examplePrompts": [
4152
+ "Create a mass from these faces",
4153
+ "Turn this custom brep into a scene mass",
4154
+ "Add a pyramid-shaped mass to the model\n\n# Example\n```ts\nconst apex = { x: 0, y: 4, z: 0 }\nconst a = { x: -2, y: 0, z: -2 }\nconst b = { x: 2, y: 0, z: -2 }\nconst c = { x: 2, y: 0, z: 2 }\nconst d = { x: -2, y: 0, z: 2 }\nconst brep = await snaptrude.core.geom.create.brepFromFaces([\n[a, d, c, b],\n[a, b, apex],\n[b, c, apex],\n[c, d, apex],\n[d, a, apex],\n])\nconst pyramid = await snaptrude.design.create.massFromBrep(brep, \"Pavilion\")\n```"
4155
+ ],
4156
+ "argsType": "BrepHandle",
4157
+ "resultType": "ComponentHandle"
4158
+ },
3718
4159
  {
3719
4160
  "path": "design.create.referenceLines",
3720
4161
  "namespace": "design.create",
@@ -3780,10 +4221,11 @@
3780
4221
  "Make a bedroom here and assign it to the Residential department",
3781
4222
  "Extrude this closed outline into a 10 foot high room",
3782
4223
  "Can you create a Kitchen space from the sketch I just drew?",
3783
- "Create a bedroom on the second floor from this outline\n\n# Example\n```ts\nconst v = snaptrude.core.math.vec3\nconst outer = await snaptrude.core.geom.create.profileFromLinePoints([\nawait v.new(0, 0, 0),\nawait v.new(10, 0, 0),\nawait v.new(10, 0, 8),\nawait v.new(0, 0, 8),\n])\nconst contour = await snaptrude.core.geom.create.contourFromProfile(outer)\nconst space = await snaptrude.design.create.space(contour, 3, \"Living\")\n// …place one directly on the second floor (no setActive dance):\nconst upstairs = await snaptrude.design.create.space(\ncontour, 3, \"Bedroom\", undefined, undefined, undefined, undefined, 2,\n)\n```"
4224
+ "Create a bedroom on the second floor from this outline"
3784
4225
  ],
3785
4226
  "argsType": "ContourHandle",
3786
- "resultType": "ComponentHandle"
4227
+ "resultType": "ComponentHandle",
4228
+ "performance": "For MORE THAN ONE space, call `design.create.spaces(items[])` — the whole batch is one host round-trip. Looping this single-space creator is N round-trips (slow, and a large loop can trip the plugin rate limit). # Example ```ts const v = snaptrude.core.math.vec3 const outer = await snaptrude.core.geom.create.profileFromLinePoints([ await v.new(0, 0, 0), await v.new(10, 0, 0), await v.new(10, 0, 8), await v.new(0, 0, 8), ]) const contour = await snaptrude.core.geom.create.contourFromProfile(outer) const space = await snaptrude.design.create.space(contour, 3, \"Living\") // …place one directly on the second floor (no setActive dance): const upstairs = await snaptrude.design.create.space( contour, 3, \"Bedroom\", undefined, undefined, undefined, undefined, 2, ) ```"
3787
4229
  },
3788
4230
  {
3789
4231
  "path": "design.create.spaces",
@@ -3794,10 +4236,11 @@
3794
4236
  "Generate all the bedrooms in one operation",
3795
4237
  "Bulk create the spaces for this floor plan",
3796
4238
  "Add three rooms with different heights in a single undo step",
3797
- "Create one room on the ground floor and one on the first floor\n\n# Example\n```ts\nconst rect = await snaptrude.core.geom.create.profileRect(4, 3)\nconst contour = await snaptrude.core.geom.create.contourFromProfile(rect)\nconst [a, b] = await snaptrude.design.create.spaces([\n{ contour, height: 3, label: \"R1\" },\n{ contour, height: 4, label: \"R2\", position: await vec3.new(10, 0, 0) },\n])\n```"
4239
+ "Create one room on the ground floor and one on the first floor"
3798
4240
  ],
3799
4241
  "argsType": "PluginCreateSpaceItem[]",
3800
- "resultType": "ComponentHandle[]"
4242
+ "resultType": "ComponentHandle[]",
4243
+ "performance": "Bulk creator — the whole batch is ONE host round-trip. Always prefer this over calling `design.create.space` in a loop: build the full `items[]` array first (all per-item math and geometry up front), then make one call. # Example ```ts const rect = await snaptrude.core.geom.create.profileRect(4, 3) const contour = await snaptrude.core.geom.create.contourFromProfile(rect) const [a, b] = await snaptrude.design.create.spaces([ { contour, height: 3, label: \"R1\" }, { contour, height: 4, label: \"R2\", position: await vec3.new(10, 0, 0) }, ]) ```"
3801
4244
  },
3802
4245
  {
3803
4246
  "path": "design.create.staircase",
@@ -3853,10 +4296,11 @@
3853
4296
  "Remove these walls from the model",
3854
4297
  "Get rid of this mass entirely",
3855
4298
  "Delete all the furniture I picked",
3856
- "Remove the door and window I just created\n\n# Example\n```ts\n// Hard-delete every furniture item on storey 2 (a single undo entry)\nconst furniture = await snaptrude.design.query.listFurniture({ storeys: [2] })\nif (furniture.length > 0) {\nconst { affected } = await snaptrude.design.delete.entities(furniture)\n}\n```"
4299
+ "Remove the door and window I just created"
3857
4300
  ],
3858
4301
  "argsType": "ComponentHandle[]",
3859
- "resultType": "PluginDesignChangeResult"
4302
+ "resultType": "PluginDesignChangeResult",
4303
+ "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) } ```"
3860
4304
  },
3861
4305
  {
3862
4306
  "path": "design.doors.exists",
@@ -4485,6 +4929,19 @@
4485
4929
  "argsType": "ComponentHandle",
4486
4930
  "resultType": "CurveHandle | null"
4487
4931
  },
4932
+ {
4933
+ "path": "design.query.geometry.getTriangulatedMeshes",
4934
+ "namespace": "design.query.geometry",
4935
+ "summary": "Get the **triangulated render meshes** of scene components as plain, serializable arrays — flat world-space vertex `positions` (`[x0, y0, z0, x1, …]`) and triangle `indices` (three per triangle), one record per requested component.",
4936
+ "examplePrompts": [
4937
+ "Export the selected masses as a triangle mesh",
4938
+ "Get the raw vertices and triangles of this wall in world coordinates",
4939
+ "Give me the triangulated geometry of every space with its materials",
4940
+ "Compute the surface area of this roof from its triangles"
4941
+ ],
4942
+ "argsType": "ComponentHandle[]",
4943
+ "resultType": "PluginDesignQueryGeometryGetTriangulatedMeshesResult"
4944
+ },
4488
4945
  {
4489
4946
  "path": "design.query.getBoundingBox",
4490
4947
  "namespace": "design.query",
@@ -4844,19 +5301,45 @@
4844
5301
  "resultType": "PluginEntityMeasurements | null"
4845
5302
  },
4846
5303
  {
4847
- "path": "design.query.spaces.get",
4848
- "namespace": "design.query.spaces",
4849
- "summary": "Get selected properties of a space the selective multi-property read.",
5304
+ "path": "design.query.referenceLines.get",
5305
+ "namespace": "design.query.referenceLines",
5306
+ "summary": "Get properties of a reference line by its ID.",
4850
5307
  "examplePrompts": [
4851
- "What is the area of this room?",
4852
- "Get the name, storey and height of the selected space",
4853
- "Which department does this room belong to?",
4854
- "Where is this space positioned on the plan?",
4855
- "Read the room type and dimensions of the selected room\n\n# Example\n```ts\nconst [space] = await snaptrude.design.query.listSpaces()\nconst info = await snaptrude.design.query.spaces.get(space, [\"name\", \"area\", \"position\"])\nconsole.log(info.name, info.area, info.position)\n```"
5308
+ "Get the curve geometry of this reference line",
5309
+ "Where does this grid line run?",
5310
+ "Read the geometry of a guide line by its id",
5311
+ "Look up the curve of the selected reference line\n\n# Example\n```ts\nconst [refLine] = await snaptrude.design.query.listReferenceLines()\nconst result = await snaptrude.design.query.referenceLines.get(refLine, [\"curve\"])\n// result.curve is an opaque CurveHandle; read its coordinates via\n// `snaptrude.core.geom.curve`.\n```"
5312
+ ],
5313
+ "argsType": "string",
5314
+ "resultType": "PluginReferenceLineGetResult"
5315
+ },
5316
+ {
5317
+ "path": "design.query.spaces.get",
5318
+ "namespace": "design.query.spaces",
5319
+ "summary": "Get selected properties of a space — the selective multi-property read.",
5320
+ "examplePrompts": [
5321
+ "What is the area of this room?",
5322
+ "Get the name, storey and height of the selected space",
5323
+ "Which department does this room belong to?",
5324
+ "Where is this space positioned on the plan?",
5325
+ "Read the room type and dimensions of the selected room\n\n# Example\n```ts\nconst [space] = await snaptrude.design.query.listSpaces()\nconst info = await snaptrude.design.query.spaces.get(space, [\"name\", \"area\", \"position\"])\nconsole.log(info.name, info.area, info.position)\n```"
4856
5326
  ],
4857
5327
  "argsType": "ComponentHandle",
4858
5328
  "resultType": "PluginDesignQuerySpacesGetResult"
4859
5329
  },
5330
+ {
5331
+ "path": "design.query.spaces.getEnclosure",
5332
+ "namespace": "design.query.spaces",
5333
+ "summary": "Get the **enclosure** of a space — the floor and ceiling that cap it, the bounding walls around it (with each wall's door/window openings), and the neighbouring spaces it shares a boundary with.",
5334
+ "examplePrompts": [
5335
+ "What walls, floor and ceiling enclose this room?",
5336
+ "Which of this room's walls are external?",
5337
+ "List the doors and windows around the selected space",
5338
+ "Which spaces are adjacent to this room, and through which wall?\n\n# Example\n```ts\nconst [space] = await snaptrude.design.query.listSpaces()\nconst enclosure = await snaptrude.design.query.spaces.getEnclosure(space)\nif (enclosure) {\nconst walls = enclosure.surfaces.filter((s) => s.role === \"wall\")\nconst external = walls.filter((s) => s.isExternal)\nconsole.log(`${walls.length} walls, ${external.length} external`)\n}\n```"
5339
+ ],
5340
+ "argsType": "ComponentHandle",
5341
+ "resultType": "PluginSpaceEnclosure | null"
5342
+ },
4860
5343
  {
4861
5344
  "path": "design.query.spaces.getFootprint",
4862
5345
  "namespace": "design.query.spaces",
@@ -4960,10 +5443,11 @@
4960
5443
  "Line up these masses along their top edges",
4961
5444
  "Center these columns horizontally",
4962
5445
  "Align all the walls to the left edge of this reference wall",
4963
- "Snap the bottom edges of these spaces together\n\n# Example\n```ts\nconst rooms = await snaptrude.design.selection.get()\n// align every room's left (world -X) edge to a common minimum\nawait snaptrude.design.transform.align(rooms, \"left\")\n// …or align them to a fixed reference component's left edge\nconst [anchor] = await snaptrude.design.query.listWalls({ storeys: [1] })\nawait snaptrude.design.transform.align(rooms, \"left\", { reference: anchor })\n```"
5446
+ "Snap the bottom edges of these spaces together"
4964
5447
  ],
4965
5448
  "argsType": "ComponentHandle[]",
4966
- "resultType": "PluginDesignChangeResult"
5449
+ "resultType": "PluginDesignChangeResult",
5450
+ "performance": "Array API — one host round-trip for the whole set. Pass every target in a single call; never loop `design.transform.align` per entity. # Example ```ts const rooms = await snaptrude.design.selection.get() // align every room's left (world -X) edge to a common minimum await snaptrude.design.transform.align(rooms, \"left\") // …or align them to a fixed reference component's left edge const [anchor] = await snaptrude.design.query.listWalls({ storeys: [1] }) await snaptrude.design.transform.align(rooms, \"left\", { reference: anchor }) ```"
4967
5451
  },
4968
5452
  {
4969
5453
  "path": "design.transform.mirror",
@@ -4974,10 +5458,11 @@
4974
5458
  "Flip these rooms left to right",
4975
5459
  "Mirror this furniture block horizontally",
4976
5460
  "Flip the selected walls front to back",
4977
- "Create a mirror image of these masses about the z axis\n\n# Example\n```ts\nconst rooms = await snaptrude.design.selection.get()\nawait snaptrude.design.transform.mirror(rooms, \"x\")\n```"
5461
+ "Create a mirror image of these masses about the z axis"
4978
5462
  ],
4979
5463
  "argsType": "ComponentHandle[]",
4980
- "resultType": "PluginDesignChangeResult"
5464
+ "resultType": "PluginDesignChangeResult",
5465
+ "performance": "Array API — one host round-trip for the whole set. Pass every target in a single call; never loop `design.transform.mirror` per entity. # Example ```ts const rooms = await snaptrude.design.selection.get() await snaptrude.design.transform.mirror(rooms, \"x\") ```"
4981
5466
  },
4982
5467
  {
4983
5468
  "path": "design.transform.move",
@@ -4988,10 +5473,11 @@
4988
5473
  "Shift these walls 3m along the x axis",
4989
5474
  "Nudge this space 500mm north",
4990
5475
  "Translate the furniture block by (10, 0, 5)",
4991
- "Move these masses up one storey\n\n# Example\n```ts\nconst { vec3 } = snaptrude.core.math\nawait snaptrude.design.transform.move([\"space-id\"], vec3.new(10, 0, 0))\n```"
5476
+ "Move these masses up one storey"
4992
5477
  ],
4993
5478
  "argsType": "ComponentHandle[]",
4994
- "resultType": "PluginDesignChangeResult"
5479
+ "resultType": "PluginDesignChangeResult",
5480
+ "performance": "Array API — one host round-trip for the whole set. Pass every target in a single call; never loop `design.transform.move` per entity. # Example ```ts const { vec3 } = snaptrude.core.math await snaptrude.design.transform.move([\"space-id\"], vec3.new(10, 0, 0)) ```"
4995
5481
  },
4996
5482
  {
4997
5483
  "path": "design.transform.rotate",
@@ -5002,10 +5488,11 @@
5002
5488
  "Turn this room 45 degrees clockwise",
5003
5489
  "Spin the furniture block 180 degrees about its centre",
5004
5490
  "Rotate these masses 30 degrees around the vertical axis",
5005
- "Rotate these walls 90 degrees about the origin\n\n# Example\n```ts\nawait snaptrude.design.transform.rotate([\"space-id\"], 90)\n// …or rotate about an explicit pivot point\nconst { vec3 } = snaptrude.core.math\nawait snaptrude.design.transform.rotate([\"space-id\"], 90, { pivot: vec3.new(0, 0, 0) })\n```"
5491
+ "Rotate these walls 90 degrees about the origin"
5006
5492
  ],
5007
5493
  "argsType": "ComponentHandle[]",
5008
- "resultType": "PluginDesignChangeResult"
5494
+ "resultType": "PluginDesignChangeResult",
5495
+ "performance": "Array API — one host round-trip for the whole set. Pass every target in a single call; never loop `design.transform.rotate` per entity. # Example ```ts await snaptrude.design.transform.rotate([\"space-id\"], 90) // …or rotate about an explicit pivot point const { vec3 } = snaptrude.core.math await snaptrude.design.transform.rotate([\"space-id\"], 90, { pivot: vec3.new(0, 0, 0) }) ```"
5009
5496
  },
5010
5497
  {
5011
5498
  "path": "design.types.get",
@@ -5059,6 +5546,19 @@
5059
5546
  "argsType": "ComponentHandle[]",
5060
5547
  "resultType": "PluginDesignChangeResult"
5061
5548
  },
5549
+ {
5550
+ "path": "design.update.buildableEnvelope",
5551
+ "namespace": "design.update",
5552
+ "summary": "Update an existing parametric buildable envelope — regenerate the zoning volume from a revised site polygon, setbacks, vertical cap, or FAR and lot-coverage limits, keeping the same envelope id. Canonical home of the update formerly at `entity.buildableEnvelope.update` (now deprecated).",
5553
+ "examplePrompts": [
5554
+ "Change the envelope's height limit to 175 feet",
5555
+ "Update the setbacks on the buildable envelope",
5556
+ "Regenerate the zoning envelope with a new site boundary",
5557
+ "Increase the FAR on the buildable volume\n\n# Example\n```ts\nconst { buildableEnvelopeId } = await snaptrude.design.update.buildableEnvelope(\nexistingId,\n[\n{ x: 0, z: 0 },\n{ x: 100, z: 0 },\n{ x: 100, z: 80 },\n{ x: 0, z: 80 },\n],\n\"ft\",\n[{ aboveHeight: 0, front: 10, side: 5, rear: 10 }],\n{ kind: \"max_height\", maxHeight: 175 },\n12,\n)\n```"
5558
+ ],
5559
+ "argsType": "string",
5560
+ "resultType": "PluginBuildableEnvelopeUpdateResult"
5561
+ },
5062
5562
  {
5063
5563
  "path": "design.update.ceiling",
5064
5564
  "namespace": "design.update",
@@ -5170,10 +5670,11 @@
5170
5670
  "Change this space's room type to Meeting Room",
5171
5671
  "Set the height of this room to 3 metres",
5172
5672
  "Move this space into the Circulation department",
5173
- "Exclude this room from the area calculations\n\n# Example\n```ts\nawait snaptrude.design.update.space(\"space-id\", { properties: { room_type: \"Office\" } })\n```"
5673
+ "Exclude this room from the area calculations"
5174
5674
  ],
5175
5675
  "argsType": "ComponentHandle",
5176
- "resultType": "PluginSpaceUpdateResult"
5676
+ "resultType": "PluginSpaceUpdateResult",
5677
+ "performance": "For MORE THAN ONE space, call `design.update.spaces(items[])` — the whole batch is one host round-trip. Looping this single-space updater is N round-trips. # Example ```ts await snaptrude.design.update.space(\"space-id\", { properties: { room_type: \"Office\" } }) ```"
5177
5678
  },
5178
5679
  {
5179
5680
  "path": "design.update.spaces",
@@ -5184,10 +5685,11 @@
5184
5685
  "Change the room type of these five spaces at once",
5185
5686
  "Set every room on this floor to a 3m height in one go",
5186
5687
  "Bulk-assign these spaces to the Service department",
5187
- "Mark all of these rooms as excluded from area in one update\n\n# Example\n```ts\n// Re-label every selected room and mark it NET area — one undoable bulk update\nconst rooms = await snaptrude.design.query.listSpaces({ isSelected: true })\nconst results = await snaptrude.design.update.spaces(\nrooms.map((space) => ({\nspace,\nproperties: { room_type: \"Bedroom\", areaClass: \"NET\" },\n})),\n)\n// One result per item, in input order\nconsole.log(results.map((r) => r.spaceId))\n```"
5688
+ "Mark all of these rooms as excluded from area in one update"
5188
5689
  ],
5189
5690
  "argsType": "PluginUpdateSpaceItem[]",
5190
- "resultType": "PluginSpaceUpdateResult[]"
5691
+ "resultType": "PluginSpaceUpdateResult[]",
5692
+ "performance": "Bulk update — the whole batch is ONE host round-trip. Prefer over looping `design.update.space`: build the `items[]` array first, then make one call. # Example ```ts // Re-label every selected room and mark it NET area — one undoable bulk update const rooms = await snaptrude.design.query.listSpaces({ isSelected: true }) const results = await snaptrude.design.update.spaces( rooms.map((space) => ({ space, properties: { room_type: \"Bedroom\", areaClass: \"NET\" }, })), ) // One result per item, in input order console.log(results.map((r) => r.spaceId)) ```"
5191
5693
  },
5192
5694
  {
5193
5695
  "path": "design.update.staircase",
@@ -5399,7 +5901,8 @@
5399
5901
  "Create a zoning envelope capped at 12 floors with FAR 3\n\n# Example\n```ts\nconst { buildableEnvelopeId } = await snaptrude.entity.buildableEnvelope.create(\n[\n{ x: 0, z: 0 },\n{ x: 100, z: 0 },\n{ x: 100, z: 80 },\n{ x: 0, z: 80 },\n],\n\"ft\",\n[\n{ aboveHeight: 0, front: 10, side: 5, rear: 10 },\n{ aboveHeight: 100, front: 20, side: 10, rear: 20 },\n],\n{ kind: \"max_height\", maxHeight: 150 },\n12,\n)\n```"
5400
5902
  ],
5401
5903
  "argsType": "PluginBuildableEnvelopePolygonVertex[]",
5402
- "resultType": "PluginBuildableEnvelopeCreateResult"
5904
+ "resultType": "PluginBuildableEnvelopeCreateResult",
5905
+ "deprecated": "design.create.buildableEnvelope"
5403
5906
  },
5404
5907
  {
5405
5908
  "path": "entity.buildableEnvelope.update",
@@ -5413,7 +5916,8 @@
5413
5916
  "Modify the envelope to allow 15 storeys instead\n\n# Example\n```ts\nconst { buildableEnvelopeId } = await snaptrude.entity.buildableEnvelope.update(\nexistingId,\n[\n{ x: 0, z: 0 },\n{ x: 100, z: 0 },\n{ x: 100, z: 80 },\n{ x: 0, z: 80 },\n],\n\"ft\",\n[{ aboveHeight: 0, front: 10, side: 5, rear: 10 }],\n{ kind: \"max_height\", maxHeight: 175 },\n12,\n)\n```"
5414
5917
  ],
5415
5918
  "argsType": "string",
5416
- "resultType": "PluginBuildableEnvelopeUpdateResult"
5919
+ "resultType": "PluginBuildableEnvelopeUpdateResult",
5920
+ "deprecated": "design.update.buildableEnvelope"
5417
5921
  },
5418
5922
  {
5419
5923
  "path": "entity.referenceLine.createMulti",
@@ -5427,7 +5931,8 @@
5427
5931
  "Turn this profile into reference lines\n\n# Example\n```ts\nconst { vec3 } = snaptrude.core.math\n\nconst start = await vec3.new(0, 0, 0)\nconst mid = await vec3.new(10, 0, 0)\nconst end = await vec3.new(10, 0, 10)\nconst l1 = await snaptrude.core.geom.create.line(start, mid)\nconst l2 = await snaptrude.core.geom.create.line(mid, end)\nconst profile = await snaptrude.core.geom.create.profileFromCurves([l1, l2])\n\nconst { referenceLineIds } = await snaptrude.entity.referenceLine.createMulti(profile)\n```"
5428
5932
  ],
5429
5933
  "argsType": "ProfileHandle",
5430
- "resultType": "PluginReferenceLineCreateMultiResult"
5934
+ "resultType": "PluginReferenceLineCreateMultiResult",
5935
+ "deprecated": "design.create.referenceLines"
5431
5936
  },
5432
5937
  {
5433
5938
  "path": "entity.referenceLine.delete",
@@ -5440,7 +5945,8 @@
5440
5945
  "Erase a reference line by its id\n\n# Example\n```ts\nawait snaptrude.entity.referenceLine.delete(\"some-ref-line-id\")\n```"
5441
5946
  ],
5442
5947
  "argsType": "string",
5443
- "resultType": "PluginReferenceLineDeleteResult"
5948
+ "resultType": "PluginReferenceLineDeleteResult",
5949
+ "deprecated": "design.delete.entities"
5444
5950
  },
5445
5951
  {
5446
5952
  "path": "entity.referenceLine.get",
@@ -5453,7 +5959,8 @@
5453
5959
  "Look up the curve of the selected reference line\n\n# Example\n```ts\nconst result = await snaptrude.entity.referenceLine.get(\"some-ref-line-id\", [\"curve\"])\n// result.curve is an opaque CurveHandle; a dedicated curve read API for its\n// coordinates is exposed separately via `snaptrude.core.geom.curve`.\n```"
5454
5960
  ],
5455
5961
  "argsType": "string",
5456
- "resultType": "PluginReferenceLineGetResult"
5962
+ "resultType": "PluginReferenceLineGetResult",
5963
+ "deprecated": "design.query.referenceLines.get"
5457
5964
  },
5458
5965
  {
5459
5966
  "path": "entity.referenceLine.getAll",
@@ -5466,7 +5973,8 @@
5466
5973
  "Do I have any reference lines in this project?\n\n# Example\n```ts\nconst { referenceLineIds } = await snaptrude.entity.referenceLine.getAll()\nconsole.log(`Project has ${referenceLineIds.length} reference lines`)\n```"
5467
5974
  ],
5468
5975
  "argsType": null,
5469
- "resultType": "PluginReferenceLineGetAllResult"
5976
+ "resultType": "PluginReferenceLineGetAllResult",
5977
+ "deprecated": "design.query.listReferenceLines"
5470
5978
  },
5471
5979
  {
5472
5980
  "path": "entity.story.create",
@@ -5480,7 +5988,8 @@
5480
5988
  "Add another floor on top of the building\n\n# Example\n```ts\n// Create a new third floor with custom height\nconst { storyId } = await snaptrude.entity.story.create(3, 4.5)\n```"
5481
5989
  ],
5482
5990
  "argsType": "number",
5483
- "resultType": "PluginStoryCreateResult"
5991
+ "resultType": "PluginStoryCreateResult",
5992
+ "deprecated": "core.storeys.create"
5484
5993
  },
5485
5994
  {
5486
5995
  "path": "entity.story.delete",
@@ -5493,7 +6002,8 @@
5493
6002
  "Delete the second floor and everything on it\n\n# Example\n```ts\nconst { newActiveStory } = await snaptrude.entity.story.delete(3)\nconsole.log(`Deleted story 3; now on story ${newActiveStory}`)\n```"
5494
6003
  ],
5495
6004
  "argsType": "number",
5496
- "resultType": "PluginStoryDeleteResult"
6005
+ "resultType": "PluginStoryDeleteResult",
6006
+ "deprecated": "core.storeys.delete"
5497
6007
  },
5498
6008
  {
5499
6009
  "path": "entity.story.duplicate",
@@ -5503,10 +6013,12 @@
5503
6013
  "Duplicate this floor to the storey above",
5504
6014
  "Copy the ground floor down into a new basement",
5505
6015
  "Repeat this level upwards with its own independent geometry",
5506
- "Duplicate just the selected walls onto the next floor up\n\n# Example\n```ts\n// Duplicate the whole active story one level up (instanced copies).\nconst { targetStories, created, skipped } =\nawait snaptrude.entity.story.duplicate(\"up\")\nconsole.log(`Copied ${created.length} elements onto story ${targetStories}`)\nif (skipped) console.log(`${skipped} elements were skipped`)\n```"
6016
+ "Duplicate just the selected walls onto the next floor up"
5507
6017
  ],
5508
6018
  "argsType": "\"up\" | \"down\"",
5509
- "resultType": "PluginStoryDuplicateResult"
6019
+ "resultType": "PluginStoryDuplicateResult",
6020
+ "performance": "For storeys that share a layout, duplicate the storey instead of recreating its contents floor by floor — this copies every eligible element in one call, and the default instanced copies keep the floors linked. To stack many identical floors, either call this per level or capture the storey's component ids and `design.create.copy(ids, oneFloorRise, { count })` to lay them all down in a single call. # Example ```ts // Duplicate the whole active story one level up (instanced copies). const { targetStories, created, skipped } = await snaptrude.entity.story.duplicate(\"up\") console.log(`Copied ${created.length} elements onto story ${targetStories}`) if (skipped) console.log(`${skipped} elements were skipped`) ```",
6021
+ "deprecated": "core.storeys.copy"
5510
6022
  },
5511
6023
  {
5512
6024
  "path": "entity.story.get",
@@ -5520,7 +6032,8 @@
5520
6032
  "Show me the name and height of story 2\n\n# Example\n```ts\nconst info = await snaptrude.entity.story.get(1, [\"height\", \"name\", \"spacesCount\"])\nconsole.log(info.name, info.height, info.spacesCount)\n```"
5521
6033
  ],
5522
6034
  "argsType": "number",
5523
- "resultType": "PluginStoryGetResult"
6035
+ "resultType": "PluginStoryGetResult",
6036
+ "deprecated": "core.storeys.get"
5524
6037
  },
5525
6038
  {
5526
6039
  "path": "entity.story.getAll",
@@ -5533,7 +6046,8 @@
5533
6046
  "Which stories exist in this model?\n\n# Example\n```ts\nconst { stories } = await snaptrude.entity.story.getAll()\nfor (const s of stories) {\nconsole.log(`Story ${s.value}: ${s.name} (id: ${s.id})`)\n}\n```"
5534
6047
  ],
5535
6048
  "argsType": null,
5536
- "resultType": "PluginStoryGetAllResult"
6049
+ "resultType": "PluginStoryGetAllResult",
6050
+ "deprecated": "core.storeys.list"
5537
6051
  },
5538
6052
  {
5539
6053
  "path": "entity.story.setActive",
@@ -5546,7 +6060,8 @@
5546
6060
  "Set level 3 as the current storey\n\n# Example\n```ts\n// Activate story 2, then draw a wall — it lands on story 2.\nawait snaptrude.entity.story.setActive(2)\n```"
5547
6061
  ],
5548
6062
  "argsType": "number",
5549
- "resultType": "PluginStorySetActiveResult"
6063
+ "resultType": "PluginStorySetActiveResult",
6064
+ "deprecated": "core.storeys.setActive"
5550
6065
  },
5551
6066
  {
5552
6067
  "path": "entity.story.update",
@@ -5560,7 +6075,8 @@
5560
6075
  "Rename storey 2 and make it taller in one go\n\n# Example\n```ts\n// Set ground floor height to 5 Babylon units — walls stretch and the\n// floors above move up to match, all in a single undo step.\nconst result = await snaptrude.entity.story.update(1, 5)\n// Rename only, leaving the height untouched.\nawait snaptrude.entity.story.update(1, undefined, { name: \"Lobby\" })\n```"
5561
6076
  ],
5562
6077
  "argsType": "number",
5563
- "resultType": "PluginStoryUpdateResult"
6078
+ "resultType": "PluginStoryUpdateResult",
6079
+ "deprecated": "core.storeys.update"
5564
6080
  },
5565
6081
  {
5566
6082
  "path": "presentation.aiInspiration.cancelJob",
@@ -5829,6 +6345,18 @@
5829
6345
  "argsType": null,
5830
6346
  "resultType": "PluginPresentationDiagramsGenerateResult"
5831
6347
  },
6348
+ {
6349
+ "path": "presentation.diagrams.generateSite",
6350
+ "namespace": "presentation.diagrams",
6351
+ "summary": "Generate the site diagrams (location, streetview, climate) for the current model, creating new layout sheets.",
6352
+ "examplePrompts": [
6353
+ "Generate the site diagrams for this project",
6354
+ "Create the location, streetview and climate sheets",
6355
+ "Add a climate diagram sheet to the presentation\n\n# Example\n```ts\nconst { sheetIds } = await snaptrude.presentation.diagrams.generateSite({\ntypes: [\"location\", \"climate\"],\n})\n```"
6356
+ ],
6357
+ "argsType": "{\n types?: PluginPresentationSiteDiagramType[]\n }",
6358
+ "resultType": "PluginPresentationDiagramsGenerateResult"
6359
+ },
5832
6360
  {
5833
6361
  "path": "presentation.diagrams.place",
5834
6362
  "namespace": "presentation.diagrams",
@@ -5894,6 +6422,316 @@
5894
6422
  "argsType": "{ url?: string; dataUrl?: string }",
5895
6423
  "resultType": "PluginPresentationImportResult"
5896
6424
  },
6425
+ {
6426
+ "path": "presentation.placedViews.deleteShapes",
6427
+ "namespace": "presentation.placedViews",
6428
+ "summary": "Delete Present-canvas shapes. One undoable step for the whole batch, and the batch is atomic — if any id is rejected, nothing is deleted.",
6429
+ "examplePrompts": [
6430
+ "Delete the old AI renders from the sheet",
6431
+ "Remove that placed view",
6432
+ "Clear the diagram images I placed\n\n# Example\n```ts\nconst { deleted } = await snaptrude.presentation.placedViews.deleteShapes([\nout1.shapeId,\nout2.shapeId,\n])\n```"
6433
+ ],
6434
+ "argsType": "string[]",
6435
+ "resultType": "PluginCanvasShapesDeleteResult"
6436
+ },
6437
+ {
6438
+ "path": "presentation.placedViews.get",
6439
+ "namespace": "presentation.placedViews",
6440
+ "summary": "Get a single placed view by its shape id.",
6441
+ "examplePrompts": [
6442
+ "Get the placed view I just dropped on the sheet",
6443
+ "Read the position and scale of this placed view",
6444
+ "What's the crop on shape_123?\n\n# Example\n```ts\nconst placed = await snaptrude.presentation.placedViews.get(shapeId)\nconsole.log(placed.position, placed.scale)\n```"
6445
+ ],
6446
+ "argsType": "string",
6447
+ "resultType": "PluginPlacedView"
6448
+ },
6449
+ {
6450
+ "path": "presentation.placedViews.getShape",
6451
+ "namespace": "presentation.placedViews",
6452
+ "summary": "Get one Present-canvas shape by id — works for any top-level shape (placed view, AI output, diagram image, plugin shape, annotation), unlike `get` which requires a placed view. Requires Present mode to be open.",
6453
+ "examplePrompts": [
6454
+ "Inspect the AI render I just generated",
6455
+ "Get the bounds of that diagram image"
6456
+ ],
6457
+ "argsType": "string",
6458
+ "resultType": "PluginCanvasShape"
6459
+ },
6460
+ {
6461
+ "path": "presentation.placedViews.getStyles",
6462
+ "namespace": "presentation.placedViews",
6463
+ "summary": "Read a placed view's (or sheet's) per-category presentation styles.",
6464
+ "examplePrompts": [
6465
+ "What line weights is this placed plan using?",
6466
+ "Read the styling of the placed view",
6467
+ "Which categories can I restyle on this sheet?\n\n# Example\n```ts\nconst styles = await snaptrude.presentation.placedViews.getStyles(shapeId)\nconst space = styles.categories.find((c) => c.category === \"Space\")\nconsole.log(space?.settings.cutWidth, space?.settings.lineStyle)\n```"
6468
+ ],
6469
+ "argsType": "string",
6470
+ "resultType": "PluginPlacedViewStylesResult"
6471
+ },
6472
+ {
6473
+ "path": "presentation.placedViews.list",
6474
+ "namespace": "presentation.placedViews",
6475
+ "summary": "List the placed views in the presentation.",
6476
+ "examplePrompts": [
6477
+ "Which views are placed on this sheet?",
6478
+ "List all the placed views in the presentation",
6479
+ "What's laid out on sheet 2?",
6480
+ "Show me every view on the Present canvas\n\n# Example\n```ts\nconst { placedViews } = await snaptrude.presentation.placedViews.list(\"sheet_1\")\n```"
6481
+ ],
6482
+ "argsType": "string",
6483
+ "resultType": "PluginPresentationPlacedViewsListResult"
6484
+ },
6485
+ {
6486
+ "path": "presentation.placedViews.listLabels",
6487
+ "namespace": "presentation.placedViews",
6488
+ "summary": "List a placed view's labels — the text children generated from the view's content (space names, departments, areas, dimension texts). Each label is individually addressable: it can be moved and hidden. Returns `[]` when the view has no labels. Requires Present mode to be open.",
6489
+ "examplePrompts": [
6490
+ "List the labels on this placed plan",
6491
+ "Where are the space labels on this view?",
6492
+ "Show every label with its position\n\n# Example\n```ts\nconst { labels } = await snaptrude.presentation.placedViews.listLabels(shapeId)\nfor (const l of labels) console.log(l.text, l.position, l.hidden)\n```"
6493
+ ],
6494
+ "argsType": "string",
6495
+ "resultType": "PluginPlacedViewLabelsResult"
6496
+ },
6497
+ {
6498
+ "path": "presentation.placedViews.listShapes",
6499
+ "namespace": "presentation.placedViews",
6500
+ "summary": "List the top-level shapes on the Present canvas — not just placed views: AI-generated outputs, placed diagram images, plugin-created shapes, and annotations, each with an `origin` classification. Sheets (frames) are not listed — use `sheets.list`. Pass `sheetId` to list only shapes on that sheet. Returns `[]` when Present mode is closed.",
6501
+ "examplePrompts": [
6502
+ "List everything on the Present canvas",
6503
+ "What AI outputs are on this sheet?",
6504
+ "Show all the shapes with their positions\n\n# Example\n```ts\nconst { shapes } = await snaptrude.presentation.placedViews.listShapes()\nconst aiOutputs = shapes.filter((s) => s.origin === \"aiOutput\")\n```"
6505
+ ],
6506
+ "argsType": "string",
6507
+ "resultType": "PluginCanvasShapesListResult"
6508
+ },
6509
+ {
6510
+ "path": "presentation.placedViews.move",
6511
+ "namespace": "presentation.placedViews",
6512
+ "summary": "Move a placed view.",
6513
+ "examplePrompts": [
6514
+ "Move the site plan view to the top-left of sheet 2",
6515
+ "Reposition this placed view to 100, 200",
6516
+ "Move the hero perspective onto the cover sheet\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.move(shapeId, { x: 50, y: 50 }, {\nsheetId: \"sheet_2\",\n})\n```"
6517
+ ],
6518
+ "argsType": "string",
6519
+ "resultType": "PluginPlacedView"
6520
+ },
6521
+ {
6522
+ "path": "presentation.placedViews.moveLabel",
6523
+ "namespace": "presentation.placedViews",
6524
+ "summary": "Move a label to a new position (coordinates relative to its placed view, the same space `listLabels` reports). The manual position survives style changes. Undoable. Requires Present mode to be open.",
6525
+ "examplePrompts": [
6526
+ "Move the kitchen label out of the hatched area",
6527
+ "Nudge this label 20 units right",
6528
+ "Reposition the area text"
6529
+ ],
6530
+ "argsType": "string",
6531
+ "resultType": "PluginPlacedViewLabel"
6532
+ },
6533
+ {
6534
+ "path": "presentation.placedViews.moveShape",
6535
+ "namespace": "presentation.placedViews",
6536
+ "summary": "Move any Present-canvas shape (AI outputs, diagram images, plugin shapes, annotations — placed views too). Same coordinate semantics as `move`: sheet-local when on a sheet, page coordinates otherwise; pass `options.sheetId` to reparent onto a sheet. Undoable. Requires Present mode to be open.",
6537
+ "examplePrompts": [
6538
+ "Move the AI render to the top of the sheet",
6539
+ "Put the diagram image at 100, 200"
6540
+ ],
6541
+ "argsType": "string",
6542
+ "resultType": "PluginCanvasShape"
6543
+ },
6544
+ {
6545
+ "path": "presentation.placedViews.resetStyles",
6546
+ "namespace": "presentation.placedViews",
6547
+ "summary": "Reset a placed view's styling to defaults — the sidebar's Reset button: clears every per-category override and view-style restyle, resets font styles, and un-hides labels hidden by styling. Undoable. Requires Present mode to be open.",
6548
+ "examplePrompts": [
6549
+ "Reset this view's styling",
6550
+ "Clear all the style overrides on the placed plan",
6551
+ "Put the sheet styles back to default"
6552
+ ],
6553
+ "argsType": "string",
6554
+ "resultType": "void"
6555
+ },
6556
+ {
6557
+ "path": "presentation.placedViews.resizeShape",
6558
+ "namespace": "presentation.placedViews",
6559
+ "summary": "Resize any Present-canvas shape by a uniform factor about its top-left corner (aspect ratio held) — the generic counterpart of `scale`, which requires a placed view. Undoable. Requires Present mode to be open.",
6560
+ "examplePrompts": [
6561
+ "Make the AI output half its size",
6562
+ "Double the size of that image"
6563
+ ],
6564
+ "argsType": "string",
6565
+ "resultType": "PluginCanvasShape"
6566
+ },
6567
+ {
6568
+ "path": "presentation.placedViews.rotateShape",
6569
+ "namespace": "presentation.placedViews",
6570
+ "summary": "Rotate any Present-canvas shape (AI outputs, diagram images, plugin shapes, annotations — placed views too) — the generic counterpart of `setRotation`, same target rules as `moveShape`. Same semantics: **absolute** angle in radians (tldraw convention) about the shape's bounds center, canonicalized into `[0, 2π)` (pass values in that range for an exact round-trip via `getShape`), one undo step. A placed view passed here falls under the same 3D-only rule as `setRotation`: 2D and site-plan views cannot rotate and are refused with a typed `PRECONDITION_FAILED`. Requires Present mode to be open.",
6571
+ "examplePrompts": [
6572
+ "Rotate the AI render 15 degrees",
6573
+ "Turn that image sideways",
6574
+ "Reset the diagram image's rotation"
6575
+ ],
6576
+ "argsType": "string",
6577
+ "resultType": "PluginCanvasShape"
6578
+ },
6579
+ {
6580
+ "path": "presentation.placedViews.scale",
6581
+ "namespace": "presentation.placedViews",
6582
+ "summary": "Resize a placed view by a uniform factor.",
6583
+ "examplePrompts": [
6584
+ "Make this placed view twice as big",
6585
+ "Shrink the placed 3D view to half its size",
6586
+ "Scale the placed plan up by 50%\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.scale(shapeId, 2)\n```"
6587
+ ],
6588
+ "argsType": "string",
6589
+ "resultType": "PluginPlacedView"
6590
+ },
6591
+ {
6592
+ "path": "presentation.placedViews.setCrop",
6593
+ "namespace": "presentation.placedViews",
6594
+ "summary": "Crop a placed view, or clear its crop.",
6595
+ "examplePrompts": [
6596
+ "Crop the placed view to its left half",
6597
+ "Crop this view to the top-right quarter",
6598
+ "Remove the crop from the placed plan\n\n# Example\n```ts\n// keep the left half of the view\nawait snaptrude.presentation.placedViews.setCrop(shapeId, {\ntopLeft: { x: 0, y: 0 },\nbottomRight: { x: 0.5, y: 1 },\n})\nawait snaptrude.presentation.placedViews.setCrop(shapeId, null) // clear\n```"
6599
+ ],
6600
+ "argsType": "string",
6601
+ "resultType": "PluginPlacedView"
6602
+ },
6603
+ {
6604
+ "path": "presentation.placedViews.setLabelHidden",
6605
+ "namespace": "presentation.placedViews",
6606
+ "summary": "Hide or show a single label (independent of the category-level label visibility). Undoable. Requires Present mode to be open.",
6607
+ "examplePrompts": [
6608
+ "Hide the corridor label",
6609
+ "Show that label again"
6610
+ ],
6611
+ "argsType": "string",
6612
+ "resultType": "PluginPlacedViewLabel"
6613
+ },
6614
+ {
6615
+ "path": "presentation.placedViews.setMask",
6616
+ "namespace": "presentation.placedViews",
6617
+ "summary": "Toggle \"mask context buildings\" on a placed view — mutes the inactive proposal buildings in the view (the sidebar checkbox). Views only. Undoable. Requires Present mode to be open.",
6618
+ "examplePrompts": [
6619
+ "Mask the context buildings in this view",
6620
+ "Show the neighboring proposals again in the placed view"
6621
+ ],
6622
+ "argsType": "string",
6623
+ "resultType": "void"
6624
+ },
6625
+ {
6626
+ "path": "presentation.placedViews.setOpacity",
6627
+ "namespace": "presentation.placedViews",
6628
+ "summary": "Set a Present-canvas shape's opacity (`0` transparent .. `1` opaque) — the sidebar's whole-shape opacity slider (distinct from the per-category fill opacity in `updateStyles`). Works for any top-level shape. Undoable. Requires Present mode to be open.",
6629
+ "examplePrompts": [
6630
+ "Fade the placed view to 50%",
6631
+ "Make the AI render semi-transparent"
6632
+ ],
6633
+ "argsType": "string",
6634
+ "resultType": "void"
6635
+ },
6636
+ {
6637
+ "path": "presentation.placedViews.setRotation",
6638
+ "namespace": "presentation.placedViews",
6639
+ "summary": "Set a placed view's rotation.",
6640
+ "examplePrompts": [
6641
+ "Rotate the placed plan 90 degrees",
6642
+ "Set this view's rotation to 45 degrees",
6643
+ "Straighten the placed view back to zero rotation\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.setRotation(shapeId, Math.PI / 2)\n```"
6644
+ ],
6645
+ "argsType": "string",
6646
+ "resultType": "PluginPlacedView"
6647
+ },
6648
+ {
6649
+ "path": "presentation.placedViews.setScale",
6650
+ "namespace": "presentation.placedViews",
6651
+ "summary": "Set a placed view's architectural scale.",
6652
+ "examplePrompts": [
6653
+ "Set the plan to 1:100",
6654
+ "Change the placed floor plan to 1:50 scale",
6655
+ "Make this view print at quarter-inch scale\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.setScale(shapeId, 100) // 1:100\n```"
6656
+ ],
6657
+ "argsType": "string",
6658
+ "resultType": "PluginPlacedView"
6659
+ },
6660
+ {
6661
+ "path": "presentation.placedViews.updateFontStyles",
6662
+ "namespace": "presentation.placedViews",
6663
+ "summary": "Update a category's label typography on a placed view (or sheet) — the configure panel's Text tab.",
6664
+ "examplePrompts": [
6665
+ "Set the space labels to Roboto 24px bold",
6666
+ "Hide the area values on this plan",
6667
+ "Make the department labels italic\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.updateFontStyles(shapeId, \"Space\", {\nobjectLabels: { fontFamily: \"Roboto\", fontWeight: \"700\", fontSize: 24 },\nvisibleTypes: [\"objectLabels\", \"areas\"],\n})\n```"
6668
+ ],
6669
+ "argsType": "string",
6670
+ "resultType": "void"
6671
+ },
6672
+ {
6673
+ "path": "presentation.placedViews.updateStyles",
6674
+ "namespace": "presentation.placedViews",
6675
+ "summary": "Update one style category on a placed view (or sheet) — the same writes the Present sidebar's per-category configure panel performs.",
6676
+ "examplePrompts": [
6677
+ "Set the Space cut line weight to 0.5 mm",
6678
+ "Make the Department lines dashed",
6679
+ "Color the plan by department",
6680
+ "Hide the dimension lines on this view",
6681
+ "Round the space corners with a 2 ft radius\n\n# Example\n```ts\nawait snaptrude.presentation.placedViews.updateStyles(shapeId, \"Space\", {\ncutWidth: 0.5,\nprojectionWidth: 0.18,\nlineStyle: \"dashed\",\ncolorMode: \"department\",\n})\n```"
6682
+ ],
6683
+ "argsType": "string",
6684
+ "resultType": "PluginPlacedViewCategoryStyles"
6685
+ },
6686
+ {
6687
+ "path": "presentation.shapes.list",
6688
+ "namespace": "presentation.shapes",
6689
+ "summary": "List the calling plugin's shapes.",
6690
+ "examplePrompts": [
6691
+ "Which annotations has my plugin placed on the sheets?",
6692
+ "List the plugin's shapes before refreshing them",
6693
+ "Check whether the FAR label already exists\n\n# Example\n```ts\nconst { shapes } = await snaptrude.presentation.shapes.list()\nconst hasLabel = shapes.some((s) => s.key === \"far-label\")\n```"
6694
+ ],
6695
+ "argsType": null,
6696
+ "resultType": "PluginPresentationShapesListResult"
6697
+ },
6698
+ {
6699
+ "path": "presentation.shapes.remove",
6700
+ "namespace": "presentation.shapes",
6701
+ "summary": "Delete the shape for a key.",
6702
+ "examplePrompts": [
6703
+ "Remove the FAR label from the sheet",
6704
+ "Delete the highlight the plugin added earlier",
6705
+ "Clear the \"far-label\" annotation\n\n# Example\n```ts\nconst removed = await snaptrude.presentation.shapes.remove(\"far-label\")\n```"
6706
+ ],
6707
+ "argsType": "string",
6708
+ "resultType": "boolean"
6709
+ },
6710
+ {
6711
+ "path": "presentation.shapes.removeAll",
6712
+ "namespace": "presentation.shapes",
6713
+ "summary": "Delete every shape owned by the calling plugin.",
6714
+ "examplePrompts": [
6715
+ "Clear all annotations my plugin added",
6716
+ "Reset the sheet output before rerunning the analysis",
6717
+ "Remove every plugin-drawn shape\n\n# Example\n```ts\nconst deleted = await snaptrude.presentation.shapes.removeAll()\n```"
6718
+ ],
6719
+ "argsType": null,
6720
+ "resultType": "number"
6721
+ },
6722
+ {
6723
+ "path": "presentation.shapes.upsert",
6724
+ "namespace": "presentation.shapes",
6725
+ "summary": "Create or update the shape for a key.",
6726
+ "examplePrompts": [
6727
+ "Update the analysis label on the sheet instead of adding another one",
6728
+ "Rerun the daylight report and refresh its annotations",
6729
+ "Keep one \"FAR: 2.4\" text on Sheet 1 that updates on each run",
6730
+ "Draw a highlight rectangle the plugin can move on the next run\n\n# Example\n```ts\nconst { shapeId, created } = await snaptrude.presentation.shapes.upsert(\"far-label\", {\ntype: \"text\",\ntext: \"FAR: 2.4\",\nposition: { x: 40, y: 40 },\ncolor: \"blue\",\n})\n```"
6731
+ ],
6732
+ "argsType": "string",
6733
+ "resultType": "PluginPresentationShapesUpsertResult"
6734
+ },
5897
6735
  {
5898
6736
  "path": "presentation.sheets.create",
5899
6737
  "namespace": "presentation.sheets",
@@ -5994,6 +6832,18 @@
5994
6832
  "argsType": "string",
5995
6833
  "resultType": "PluginPresentationSheet"
5996
6834
  },
6835
+ {
6836
+ "path": "presentation.sheets.setMargin",
6837
+ "namespace": "presentation.sheets",
6838
+ "summary": "Set a sheet's print margin.",
6839
+ "examplePrompts": [
6840
+ "Set the sheet margin to half an inch",
6841
+ "Remove the margins on sheet_1",
6842
+ "Give the cover sheet a 10mm margin\n\n# Example\n```ts\nconst sheet = await snaptrude.presentation.sheets.setMargin(\"sheet_1\", 0.5)\n```"
6843
+ ],
6844
+ "argsType": "string",
6845
+ "resultType": "PluginPresentationSheet"
6846
+ },
5997
6847
  {
5998
6848
  "path": "presentation.sheets.setSize",
5999
6849
  "namespace": "presentation.sheets",
@@ -6019,6 +6869,56 @@
6019
6869
  "argsType": "{\n sheetId?: string\n }",
6020
6870
  "resultType": "PluginPresentationSheetsUpdatePlacedViewResult"
6021
6871
  },
6872
+ {
6873
+ "path": "presentation.slideshow.getState",
6874
+ "namespace": "presentation.slideshow",
6875
+ "summary": "Read the slideshow state.",
6876
+ "examplePrompts": [
6877
+ "Is the slideshow running?",
6878
+ "Which slide is the presentation on?",
6879
+ "Check the slideshow state\n\n# Example\n```ts\nconst { running, index } = await snaptrude.presentation.slideshow.getState()\n```"
6880
+ ],
6881
+ "argsType": null,
6882
+ "resultType": "PluginPresentationSlideshowState"
6883
+ },
6884
+ {
6885
+ "path": "presentation.slideshow.start",
6886
+ "namespace": "presentation.slideshow",
6887
+ "summary": "Start the slideshow.",
6888
+ "examplePrompts": [
6889
+ "Start the slideshow",
6890
+ "Present the sheets from the beginning",
6891
+ "Start the slideshow on sheet 3",
6892
+ "Play the presentation starting at the cover sheet\n\n# Example\n```ts\nconst state = await snaptrude.presentation.slideshow.start({ startIndex: 2 })\nconsole.log(state.running, state.index) // true, 2\n```"
6893
+ ],
6894
+ "argsType": "{\n sheetIds?: string[]\n startIndex?: number\n }",
6895
+ "resultType": "PluginPresentationSlideshowState"
6896
+ },
6897
+ {
6898
+ "path": "presentation.slideshow.stop",
6899
+ "namespace": "presentation.slideshow",
6900
+ "summary": "Stop the slideshow.",
6901
+ "examplePrompts": [
6902
+ "Stop the slideshow",
6903
+ "Exit the presentation",
6904
+ "Close the slideshow and go back to the sheets\n\n# Example\n```ts\nawait snaptrude.presentation.slideshow.stop()\n```"
6905
+ ],
6906
+ "argsType": null,
6907
+ "resultType": "PluginPresentationSlideshowState"
6908
+ },
6909
+ {
6910
+ "path": "presentation.tables.place",
6911
+ "namespace": "presentation.tables",
6912
+ "summary": "Place a table on a sheet.",
6913
+ "examplePrompts": [
6914
+ "Put the area schedule as a table on Sheet 1",
6915
+ "Add a table of the room programs to the cover sheet",
6916
+ "Paste this data as a table on the sheet",
6917
+ "Place a two-column table of space names and areas\n\n# Example\n```ts\nconst shape = await snaptrude.presentation.tables.place(\"sheet_1\", {\nrows: [\n[\"Room\", \"Area\"],\n[\"Kitchen\", \"12.4 m²\"],\n[\"Living\", \"28.0 m²\"],\n],\n}, { position: { x: 40, y: 40 } })\n```"
6918
+ ],
6919
+ "argsType": "string",
6920
+ "resultType": "PluginCanvasShape"
6921
+ },
6022
6922
  {
6023
6923
  "path": "presentation.views.capture",
6024
6924
  "namespace": "presentation.views",
@@ -6533,6 +7433,44 @@
6533
7433
  "argsType": null,
6534
7434
  "resultType": "PluginProgramSiteNorthAngleResult"
6535
7435
  },
7436
+ {
7437
+ "path": "program.site.getTimezone",
7438
+ "namespace": "program.site",
7439
+ "summary": "Get the IANA timezone of the project's geographic location.",
7440
+ "examplePrompts": [
7441
+ "What timezone is this project in?",
7442
+ "Get the site's IANA timezone",
7443
+ "What's the local time zone at the project location?",
7444
+ "Which timezone should I use for the sun study schedule?\n\n# Example\n```ts\nconst timezone = await snaptrude.program.site.getTimezone()\nif (timezone) console.log(`Project timezone: ${timezone}`)\n```"
7445
+ ],
7446
+ "argsType": null,
7447
+ "resultType": "PluginProgramSiteTimezoneResult"
7448
+ },
7449
+ {
7450
+ "path": "program.site.getWeather",
7451
+ "namespace": "program.site",
7452
+ "summary": "Get the weather file resolved for the project site.",
7453
+ "examplePrompts": [
7454
+ "Which weather file is my project using?",
7455
+ "What EPW station was resolved for this site?",
7456
+ "Get the weather file id for the daylight analysis\n\n# Example\n```ts\nconst weather = await snaptrude.program.site.getWeather()\nif (weather) console.log(weather.station, weather.selectionMethod)\n```"
7457
+ ],
7458
+ "argsType": null,
7459
+ "resultType": "PluginProgramSiteWeatherResult"
7460
+ },
7461
+ {
7462
+ "path": "program.site.listEdges",
7463
+ "namespace": "program.site",
7464
+ "summary": "List each site parcel's boundary edges with their front / side / rear classification — the same per-edge roles the buildable-envelope setback pills show on canvas, so a plugin can pick up the user's edge tagging without asking them to set it up again.",
7465
+ "examplePrompts": [
7466
+ "Which edge of my site is the front?",
7467
+ "Read the front / side / rear edges of the plot",
7468
+ "What setback applies to each site edge?",
7469
+ "Get the site edges the way the setback pills show them\n\n# Example\n```ts\nconst { sites } = await snaptrude.program.site.listEdges()\nfor (const site of sites)\nfor (const e of site.edges)\nconsole.log(e.edgeIndex, e.role, e.roleSource, e.setbackMeters)\n```"
7470
+ ],
7471
+ "argsType": null,
7472
+ "resultType": "PluginProgramSiteListEdgesResult"
7473
+ },
6536
7474
  {
6537
7475
  "path": "program.site.listGeoPolygons",
6538
7476
  "namespace": "program.site",
@@ -6584,6 +7522,19 @@
6584
7522
  "argsType": "string",
6585
7523
  "resultType": "PluginProgramSpreadsheetAddConditionalFormattingResult"
6586
7524
  },
7525
+ {
7526
+ "path": "program.spreadsheet.addImage",
7527
+ "namespace": "program.spreadsheet",
7528
+ "summary": "Place a floating image on a workbook sheet from a base64 data URI.",
7529
+ "examplePrompts": [
7530
+ "Add my logo image to the report sheet",
7531
+ "Place a PNG at cell B2 on the Takeoff sheet",
7532
+ "Put an SVG diagram on a spreadsheet sheet",
7533
+ "Insert an image into the workbook\n\n# Example\n```ts\nconst { name } = await snaptrude.program.spreadsheet.addImage(\n\"Report\",\n{ dataUri: \"data:image/png;base64,iVBORw0...\" },\n{ anchorCell: \"B2\", size: { width: 240, height: 120 }, name: \"logo\" },\n)\n```"
7534
+ ],
7535
+ "argsType": "string",
7536
+ "resultType": "PluginProgramSpreadsheetAddImageResult"
7537
+ },
6587
7538
  {
6588
7539
  "path": "program.spreadsheet.bindings.create",
6589
7540
  "namespace": "program.spreadsheet.bindings",
@@ -6633,6 +7584,31 @@
6633
7584
  "argsType": "string",
6634
7585
  "resultType": "PluginProgramSpreadsheetCreateSheetResult"
6635
7586
  },
7587
+ {
7588
+ "path": "program.spreadsheet.datasets.list",
7589
+ "namespace": "program.spreadsheet.datasets",
7590
+ "summary": "List the stored plugin datasets.",
7591
+ "examplePrompts": [
7592
+ "List my plugin datasets",
7593
+ "What datasets are stored for the sheets?",
7594
+ "Show the data sets bindings can use\n\n# Example\n```ts\nconst { datasets } = await snaptrude.program.spreadsheet.datasets.list()\n```"
7595
+ ],
7596
+ "argsType": null,
7597
+ "resultType": "PluginProgramSpreadsheetDatasetsListResult"
7598
+ },
7599
+ {
7600
+ "path": "program.spreadsheet.datasets.set",
7601
+ "namespace": "program.spreadsheet.datasets",
7602
+ "summary": "Store (upsert) a named plugin dataset.",
7603
+ "examplePrompts": [
7604
+ "Store my plugin's rows as a named dataset",
7605
+ "Upload data the sheets can bind to and refresh",
7606
+ "Save a dataset for a live sheet binding",
7607
+ "Push my computed table so a binding keeps it fresh\n\n# Example\n```ts\nawait snaptrude.program.spreadsheet.datasets.set(\n\"costs\",\n[\n{ key: \"item\", header: \"Item\" },\n{ key: \"cost\", header: \"Cost\", align: \"right\" },\n],\n[{ item: \"Concrete\", cost: 120 }],\n)\n```"
7608
+ ],
7609
+ "argsType": "string",
7610
+ "resultType": "PluginProgramSpreadsheetDatasetsSetResult"
7611
+ },
6636
7612
  {
6637
7613
  "path": "program.spreadsheet.export",
6638
7614
  "namespace": "program.spreadsheet",
@@ -6901,5 +7877,127 @@
6901
7877
  ],
6902
7878
  "argsType": "PluginSpreadsheetTransactionOp[]",
6903
7879
  "resultType": "PluginProgramSpreadsheetTransactionResult"
7880
+ },
7881
+ {
7882
+ "path": "workspace.closePresentMode",
7883
+ "namespace": "workspace",
7884
+ "summary": "Close Present mode and return to the modeling canvas.",
7885
+ "examplePrompts": [
7886
+ "Close present mode",
7887
+ "Exit the presentation editor",
7888
+ "Go back to the modeling canvas\n\n# Example\n```ts\nawait snaptrude.workspace.closePresentMode()\n```"
7889
+ ],
7890
+ "argsType": null,
7891
+ "resultType": "void"
7892
+ },
7893
+ {
7894
+ "path": "workspace.openPresentMode",
7895
+ "namespace": "workspace",
7896
+ "summary": "Open Present mode — the documentation editor the `presentation.*` namespaces operate on.",
7897
+ "examplePrompts": [
7898
+ "Open present mode",
7899
+ "Switch to the presentation editor",
7900
+ "Open the sheets so I can lay out views\n\n# Example\n```ts\nawait snaptrude.workspace.openPresentMode()\nconst { sheets } = await snaptrude.presentation.sheets.list()\n```"
7901
+ ],
7902
+ "argsType": null,
7903
+ "resultType": "void"
7904
+ },
7905
+ {
7906
+ "path": "workspace.projects.copy",
7907
+ "namespace": "workspace.projects",
7908
+ "summary": "Copy the **current** project into a new project — the dashboard's \"Save As\".",
7909
+ "examplePrompts": [
7910
+ "Save this project as a new copy called Tower Study v2",
7911
+ "Duplicate the current project into the Acme team",
7912
+ "Make a copy of this project so I can try changes\n\n# Example\n```ts\nconst { projectId } = await snaptrude.workspace.projects.copy(\"Tower Study v2\")\n```"
7913
+ ],
7914
+ "argsType": "string",
7915
+ "resultType": "PluginWorkspaceProjectsCopyResult"
7916
+ },
7917
+ {
7918
+ "path": "workspace.projects.create",
7919
+ "namespace": "workspace.projects",
7920
+ "summary": "Create a new, empty BIM project.",
7921
+ "examplePrompts": [
7922
+ "Create a new project called Tower Study",
7923
+ "Start a new project in the Acme team",
7924
+ "Make a fresh project using millimeters",
7925
+ "Create an empty project for me to work in\n\n# Example\n```ts\nconst { projectId } = await snaptrude.workspace.projects.create(\"Tower Study\", {\nteamId: \"team_1\",\nunit: \"mm\",\n})\n```"
7926
+ ],
7927
+ "argsType": "string",
7928
+ "resultType": "PluginWorkspaceProjectsCreateResult"
7929
+ },
7930
+ {
7931
+ "path": "workspace.projects.get",
7932
+ "namespace": "workspace.projects",
7933
+ "summary": "Get a single project by id.",
7934
+ "examplePrompts": [
7935
+ "Get the project with this id",
7936
+ "Look up a project by its floorkey",
7937
+ "What is the name of this project?\n\n# Example\n```ts\nconst project = await snaptrude.workspace.projects.get(\"floorkey_123\")\nif (project) console.log(project.name)\n```"
7938
+ ],
7939
+ "argsType": "string",
7940
+ "resultType": "PluginWorkspaceProjectsGetResult"
7941
+ },
7942
+ {
7943
+ "path": "workspace.projects.list",
7944
+ "namespace": "workspace.projects",
7945
+ "summary": "List the projects the user can access.",
7946
+ "examplePrompts": [
7947
+ "List all my projects",
7948
+ "Show the projects in the Acme team",
7949
+ "How many projects do I have?",
7950
+ "What projects can I open?\n\n# Example\n```ts\nconst { projects } = await snaptrude.workspace.projects.list({ teamId: \"team_1\" })\nfor (const p of projects) console.log(p.id, p.name)\n```"
7951
+ ],
7952
+ "argsType": "{ teamId?: string }",
7953
+ "resultType": "PluginWorkspaceProjectsListResult"
7954
+ },
7955
+ {
7956
+ "path": "workspace.projects.rename",
7957
+ "namespace": "workspace.projects",
7958
+ "summary": "Rename a project.",
7959
+ "examplePrompts": [
7960
+ "Rename this project to Tower Study Final",
7961
+ "Change the name of project floorkey_123",
7962
+ "Give this project a new name\n\n# Example\n```ts\nconst { projectId } = await snaptrude.workspace.projects.rename(\n\"floorkey_123\",\n\"Tower Study Final\",\n)\n```"
7963
+ ],
7964
+ "argsType": "string",
7965
+ "resultType": "PluginWorkspaceProjectsRenameResult"
7966
+ },
7967
+ {
7968
+ "path": "workspace.teams.get",
7969
+ "namespace": "workspace.teams",
7970
+ "summary": "Get a single team by id.",
7971
+ "examplePrompts": [
7972
+ "Get the team with id team_1",
7973
+ "Look up a team by its id",
7974
+ "What is the name of this team?\n\n# Example\n```ts\nconst team = await snaptrude.workspace.teams.get(\"team_1\")\nif (team) console.log(team.name)\n```"
7975
+ ],
7976
+ "argsType": "string",
7977
+ "resultType": "PluginWorkspaceTeamsGetResult"
7978
+ },
7979
+ {
7980
+ "path": "workspace.teams.list",
7981
+ "namespace": "workspace.teams",
7982
+ "summary": "List the teams the user belongs to.",
7983
+ "examplePrompts": [
7984
+ "List all my teams",
7985
+ "Which teams am I a member of?",
7986
+ "Show every team I can access\n\n# Example\n```ts\nconst { teams } = await snaptrude.workspace.teams.list()\nfor (const t of teams) console.log(t.id, t.name)\n```"
7987
+ ],
7988
+ "argsType": null,
7989
+ "resultType": "PluginWorkspaceTeamsListResult"
7990
+ },
7991
+ {
7992
+ "path": "workspace.teams.listMembers",
7993
+ "namespace": "workspace.teams",
7994
+ "summary": "List the members of a team.",
7995
+ "examplePrompts": [
7996
+ "List the members of the Acme team",
7997
+ "Who is on team_1?",
7998
+ "How many people are in this team?\n\n# Example\n```ts\nconst { members } = await snaptrude.workspace.teams.listMembers(\"team_1\")\nfor (const m of members) console.log(m.name, m.email)\n```"
7999
+ ],
8000
+ "argsType": "string",
8001
+ "resultType": "PluginWorkspaceTeamsListMembersResult"
6904
8002
  }
6905
8003
  ]