@snaptrude/plugin-core 0.3.0 → 0.5.0

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 (266) hide show
  1. package/AGENTS.md +130 -48
  2. package/CHANGELOG.md +111 -0
  3. package/api-manifest.full.json +3999 -0
  4. package/api-manifest.json +3845 -0
  5. package/dist/api/core/buildings.d.ts +427 -0
  6. package/dist/api/core/buildings.d.ts.map +1 -0
  7. package/dist/api/core/comment/index.d.ts +230 -0
  8. package/dist/api/core/comment/index.d.ts.map +1 -0
  9. package/dist/api/core/geom/create/index.d.ts +247 -0
  10. package/dist/api/core/geom/create/index.d.ts.map +1 -0
  11. package/dist/api/core/geom/delete/index.d.ts +72 -0
  12. package/dist/api/core/geom/delete/index.d.ts.map +1 -0
  13. package/dist/api/core/geom/index.d.ts +24 -23
  14. package/dist/api/core/geom/index.d.ts.map +1 -1
  15. package/dist/api/core/geom/query/arc.d.ts +169 -0
  16. package/dist/api/core/geom/query/arc.d.ts.map +1 -0
  17. package/dist/api/core/geom/query/brep.d.ts +402 -0
  18. package/dist/api/core/geom/query/brep.d.ts.map +1 -0
  19. package/dist/api/core/geom/query/circle.d.ts +378 -0
  20. package/dist/api/core/geom/query/circle.d.ts.map +1 -0
  21. package/dist/api/core/geom/query/contour.d.ts +450 -0
  22. package/dist/api/core/geom/query/contour.d.ts.map +1 -0
  23. package/dist/api/core/geom/query/curve.d.ts +918 -0
  24. package/dist/api/core/geom/query/curve.d.ts.map +1 -0
  25. package/dist/api/core/geom/query/edge.d.ts +128 -0
  26. package/dist/api/core/geom/query/edge.d.ts.map +1 -0
  27. package/dist/api/core/geom/query/face.d.ts +363 -0
  28. package/dist/api/core/geom/query/face.d.ts.map +1 -0
  29. package/dist/api/core/geom/query/halfedge.d.ts +206 -0
  30. package/dist/api/core/geom/query/halfedge.d.ts.map +1 -0
  31. package/dist/api/core/geom/query/index.d.ts +61 -0
  32. package/dist/api/core/geom/query/index.d.ts.map +1 -0
  33. package/dist/api/core/geom/query/profile.d.ts +410 -0
  34. package/dist/api/core/geom/query/profile.d.ts.map +1 -0
  35. package/dist/api/core/geom/query/vertex.d.ts +187 -0
  36. package/dist/api/core/geom/query/vertex.d.ts.map +1 -0
  37. package/dist/api/core/geom/update/contour.d.ts +272 -0
  38. package/dist/api/core/geom/update/contour.d.ts.map +1 -0
  39. package/dist/api/core/geom/update/curve.d.ts +180 -0
  40. package/dist/api/core/geom/update/curve.d.ts.map +1 -0
  41. package/dist/api/core/geom/update/index.d.ts +27 -0
  42. package/dist/api/core/geom/update/index.d.ts.map +1 -0
  43. package/dist/api/core/geom/update/profile.d.ts +329 -0
  44. package/dist/api/core/geom/update/profile.d.ts.map +1 -0
  45. package/dist/api/core/groups.d.ts +485 -0
  46. package/dist/api/core/groups.d.ts.map +1 -0
  47. package/dist/api/core/history/index.d.ts +78 -0
  48. package/dist/api/core/history/index.d.ts.map +1 -0
  49. package/dist/api/core/index.d.ts +46 -1
  50. package/dist/api/core/index.d.ts.map +1 -1
  51. package/dist/api/core/layers.d.ts +402 -0
  52. package/dist/api/core/layers.d.ts.map +1 -0
  53. package/dist/api/core/math/quat.d.ts +111 -128
  54. package/dist/api/core/math/quat.d.ts.map +1 -1
  55. package/dist/api/core/math/vec3.d.ts +120 -102
  56. package/dist/api/core/math/vec3.d.ts.map +1 -1
  57. package/dist/api/core/project/index.d.ts +399 -0
  58. package/dist/api/core/project/index.d.ts.map +1 -0
  59. package/dist/api/core/tags.d.ts +755 -0
  60. package/dist/api/core/tags.d.ts.map +1 -0
  61. package/dist/api/core/units/index.d.ts +175 -0
  62. package/dist/api/core/units/index.d.ts.map +1 -0
  63. package/dist/api/core/zoom/index.d.ts +45 -0
  64. package/dist/api/core/zoom/index.d.ts.map +1 -0
  65. package/dist/api/design/boolean/index.d.ts +168 -0
  66. package/dist/api/design/boolean/index.d.ts.map +1 -0
  67. package/dist/api/design/create/index.d.ts +828 -0
  68. package/dist/api/design/create/index.d.ts.map +1 -0
  69. package/dist/api/design/delete/index.d.ts +63 -0
  70. package/dist/api/design/delete/index.d.ts.map +1 -0
  71. package/dist/api/design/doors/index.d.ts +268 -0
  72. package/dist/api/design/doors/index.d.ts.map +1 -0
  73. package/dist/api/design/edit/index.d.ts +49 -0
  74. package/dist/api/design/edit/index.d.ts.map +1 -0
  75. package/dist/api/design/erase/index.d.ts +160 -0
  76. package/dist/api/design/erase/index.d.ts.map +1 -0
  77. package/dist/api/design/furniture/index.d.ts +123 -0
  78. package/dist/api/design/furniture/index.d.ts.map +1 -0
  79. package/dist/api/design/index.d.ts +153 -0
  80. package/dist/api/design/index.d.ts.map +1 -0
  81. package/dist/api/design/lock.d.ts +41 -0
  82. package/dist/api/design/lock.d.ts.map +1 -0
  83. package/dist/api/design/materials/index.d.ts +297 -0
  84. package/dist/api/design/materials/index.d.ts.map +1 -0
  85. package/dist/api/design/query/geometry/index.d.ts +140 -0
  86. package/dist/api/design/query/geometry/index.d.ts.map +1 -0
  87. package/dist/api/design/query/index.d.ts +1011 -0
  88. package/dist/api/design/query/index.d.ts.map +1 -0
  89. package/dist/api/design/query/spaces.d.ts +221 -0
  90. package/dist/api/design/query/spaces.d.ts.map +1 -0
  91. package/dist/api/design/selection/index.d.ts +138 -0
  92. package/dist/api/design/selection/index.d.ts.map +1 -0
  93. package/dist/api/design/shared.d.ts +38 -0
  94. package/dist/api/design/shared.d.ts.map +1 -0
  95. package/dist/api/design/transform/index.d.ts +87 -0
  96. package/dist/api/design/transform/index.d.ts.map +1 -0
  97. package/dist/api/design/update/index.d.ts +178 -0
  98. package/dist/api/design/update/index.d.ts.map +1 -0
  99. package/dist/api/design/windows/index.d.ts +189 -0
  100. package/dist/api/design/windows/index.d.ts.map +1 -0
  101. package/dist/api/entity/buildableEnvelope.d.ts +261 -0
  102. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -0
  103. package/dist/api/entity/department.d.ts +0 -98
  104. package/dist/api/entity/department.d.ts.map +1 -1
  105. package/dist/api/entity/index.d.ts +9 -9
  106. package/dist/api/entity/index.d.ts.map +1 -1
  107. package/dist/api/entity/referenceLine.d.ts +49 -106
  108. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  109. package/dist/api/entity/space.d.ts +482 -249
  110. package/dist/api/entity/space.d.ts.map +1 -1
  111. package/dist/api/entity/story.d.ts +49 -39
  112. package/dist/api/entity/story.d.ts.map +1 -1
  113. package/dist/api/index.d.ts +17 -12
  114. package/dist/api/index.d.ts.map +1 -1
  115. package/dist/api/presentation/aiInspiration.d.ts +440 -0
  116. package/dist/api/presentation/aiInspiration.d.ts.map +1 -0
  117. package/dist/api/presentation/diagrams.d.ts +81 -0
  118. package/dist/api/presentation/diagrams.d.ts.map +1 -0
  119. package/dist/api/presentation/import.d.ts +113 -0
  120. package/dist/api/presentation/import.d.ts.map +1 -0
  121. package/dist/api/presentation/index.d.ts +46 -0
  122. package/dist/api/presentation/index.d.ts.map +1 -0
  123. package/dist/api/presentation/sheets.d.ts +176 -0
  124. package/dist/api/presentation/sheets.d.ts.map +1 -0
  125. package/dist/api/presentation/views.d.ts +296 -0
  126. package/dist/api/presentation/views.d.ts.map +1 -0
  127. package/dist/api/program/adjacency.d.ts +155 -0
  128. package/dist/api/program/adjacency.d.ts.map +1 -0
  129. package/dist/api/program/areas.d.ts +360 -0
  130. package/dist/api/program/areas.d.ts.map +1 -0
  131. package/dist/api/program/classification.d.ts +135 -0
  132. package/dist/api/program/classification.d.ts.map +1 -0
  133. package/dist/api/program/cores.d.ts +174 -0
  134. package/dist/api/program/cores.d.ts.map +1 -0
  135. package/dist/api/program/departments.d.ts +431 -0
  136. package/dist/api/program/departments.d.ts.map +1 -0
  137. package/dist/api/program/index.d.ts +69 -0
  138. package/dist/api/program/index.d.ts.map +1 -0
  139. package/dist/api/program/layout.d.ts +63 -0
  140. package/dist/api/program/layout.d.ts.map +1 -0
  141. package/dist/api/program/metrics.d.ts +108 -0
  142. package/dist/api/program/metrics.d.ts.map +1 -0
  143. package/dist/api/program/site.d.ts +367 -0
  144. package/dist/api/program/site.d.ts.map +1 -0
  145. package/dist/api/program/spreadsheet.d.ts +2041 -0
  146. package/dist/api/program/spreadsheet.d.ts.map +1 -0
  147. package/dist/handles.d.ts +138 -0
  148. package/dist/handles.d.ts.map +1 -0
  149. package/dist/host-utils.d.ts +7 -5
  150. package/dist/host-utils.d.ts.map +1 -1
  151. package/dist/index.cjs +4001 -904
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.d.ts +1 -0
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +3392 -870
  156. package/dist/index.js.map +1 -1
  157. package/package.json +6 -2
  158. package/scripts/generate-manifest.mjs +193 -0
  159. package/scripts/generate-manifest.test.mjs +193 -0
  160. package/src/api/core/buildings.ts +485 -0
  161. package/src/api/core/comment/index.ts +258 -0
  162. package/src/api/core/geom/create/index.ts +293 -0
  163. package/src/api/core/geom/delete/index.ts +78 -0
  164. package/src/api/core/geom/index.ts +24 -23
  165. package/src/api/core/geom/query/arc.ts +169 -0
  166. package/src/api/core/geom/query/brep.ts +444 -0
  167. package/src/api/core/geom/query/circle.ts +404 -0
  168. package/src/api/core/geom/query/contour.ts +540 -0
  169. package/src/api/core/geom/query/curve.ts +1078 -0
  170. package/src/api/core/geom/query/edge.ts +130 -0
  171. package/src/api/core/geom/query/face.ts +403 -0
  172. package/src/api/core/geom/query/halfedge.ts +210 -0
  173. package/src/api/core/geom/query/index.ts +63 -0
  174. package/src/api/core/geom/query/profile.ts +473 -0
  175. package/src/api/core/geom/query/vertex.ts +205 -0
  176. package/src/api/core/geom/update/contour.ts +315 -0
  177. package/src/api/core/geom/update/curve.ts +209 -0
  178. package/src/api/core/geom/update/index.ts +29 -0
  179. package/src/api/core/geom/update/profile.ts +377 -0
  180. package/src/api/core/groups.ts +521 -0
  181. package/src/api/core/history/index.ts +84 -0
  182. package/src/api/core/index.ts +46 -1
  183. package/src/api/core/layers.ts +333 -0
  184. package/src/api/core/math/quat.ts +112 -235
  185. package/src/api/core/math/vec3.ts +124 -159
  186. package/src/api/core/project/index.ts +418 -0
  187. package/src/api/core/tags.ts +808 -0
  188. package/src/api/core/units/index.ts +164 -0
  189. package/src/api/core/zoom/index.ts +47 -0
  190. package/src/api/design/boolean/index.ts +179 -0
  191. package/src/api/design/create/index.ts +886 -0
  192. package/src/api/design/delete/index.ts +67 -0
  193. package/src/api/design/doors/index.ts +285 -0
  194. package/src/api/design/edit/index.ts +54 -0
  195. package/src/api/design/erase/index.ts +151 -0
  196. package/src/api/design/furniture/index.ts +130 -0
  197. package/src/api/design/index.ts +162 -0
  198. package/src/api/design/lock.ts +42 -0
  199. package/src/api/design/materials/index.ts +301 -0
  200. package/src/api/design/query/geometry/index.ts +166 -0
  201. package/src/api/design/query/index.ts +937 -0
  202. package/src/api/design/query/spaces.ts +132 -0
  203. package/src/api/design/selection/index.ts +144 -0
  204. package/src/api/design/shared.ts +40 -0
  205. package/src/api/design/transform/index.ts +93 -0
  206. package/src/api/design/update/index.ts +117 -0
  207. package/src/api/design/windows/index.ts +207 -0
  208. package/src/api/entity/buildableEnvelope.ts +318 -0
  209. package/src/api/entity/department.ts +0 -113
  210. package/src/api/entity/index.ts +9 -9
  211. package/src/api/entity/referenceLine.ts +50 -38
  212. package/src/api/entity/space.ts +285 -226
  213. package/src/api/entity/story.ts +53 -42
  214. package/src/api/index.ts +17 -12
  215. package/src/api/presentation/aiInspiration.ts +362 -0
  216. package/src/api/presentation/diagrams.ts +84 -0
  217. package/src/api/presentation/import.ts +112 -0
  218. package/src/api/presentation/index.ts +48 -0
  219. package/src/api/presentation/sheets.ts +198 -0
  220. package/src/api/presentation/views.ts +303 -0
  221. package/src/api/program/adjacency.ts +164 -0
  222. package/src/api/program/areas.ts +335 -0
  223. package/src/api/program/classification.ts +138 -0
  224. package/src/api/program/cores.ts +171 -0
  225. package/src/api/program/departments.ts +465 -0
  226. package/src/api/program/index.ts +71 -0
  227. package/src/api/program/layout.ts +68 -0
  228. package/src/api/program/metrics.ts +120 -0
  229. package/src/api/program/site.ts +326 -0
  230. package/src/api/program/spreadsheet.ts +2075 -0
  231. package/src/handles.ts +148 -0
  232. package/src/host-utils.ts +10 -6
  233. package/src/index.ts +1 -0
  234. package/dist/api/core/geom/arc.d.ts +0 -81
  235. package/dist/api/core/geom/arc.d.ts.map +0 -1
  236. package/dist/api/core/geom/curve.d.ts +0 -70
  237. package/dist/api/core/geom/curve.d.ts.map +0 -1
  238. package/dist/api/core/geom/line.d.ts +0 -56
  239. package/dist/api/core/geom/line.d.ts.map +0 -1
  240. package/dist/api/core/geom/profile.d.ts +0 -121
  241. package/dist/api/core/geom/profile.d.ts.map +0 -1
  242. package/dist/api/tools/copy.d.ts +0 -59
  243. package/dist/api/tools/copy.d.ts.map +0 -1
  244. package/dist/api/tools/index.d.ts +0 -33
  245. package/dist/api/tools/index.d.ts.map +0 -1
  246. package/dist/api/tools/material.d.ts +0 -51
  247. package/dist/api/tools/material.d.ts.map +0 -1
  248. package/dist/api/tools/offset.d.ts +0 -43
  249. package/dist/api/tools/offset.d.ts.map +0 -1
  250. package/dist/api/tools/selection.d.ts +0 -48
  251. package/dist/api/tools/selection.d.ts.map +0 -1
  252. package/dist/api/tools/transform.d.ts +0 -114
  253. package/dist/api/tools/transform.d.ts.map +0 -1
  254. package/dist/api/units/index.d.ts +0 -163
  255. package/dist/api/units/index.d.ts.map +0 -1
  256. package/src/api/core/geom/arc.ts +0 -70
  257. package/src/api/core/geom/curve.ts +0 -41
  258. package/src/api/core/geom/line.ts +0 -53
  259. package/src/api/core/geom/profile.ts +0 -94
  260. package/src/api/tools/copy.ts +0 -55
  261. package/src/api/tools/index.ts +0 -39
  262. package/src/api/tools/material.ts +0 -49
  263. package/src/api/tools/offset.ts +0 -43
  264. package/src/api/tools/selection.ts +0 -51
  265. package/src/api/tools/transform.ts +0 -117
  266. package/src/api/units/index.ts +0 -163
@@ -0,0 +1,207 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../../types"
3
+ import { ComponentHandle } from "../../../handles"
4
+ import { PluginDesignChangeResult } from "../lock"
5
+
6
+ /**
7
+ * `snaptrude.design.windows` — window-specific reads. Creation lives at
8
+ * `design.create.window`; generic reads (`listWindows`/`getHost`/`getProperties`) live
9
+ * at `design.query.*`. Window targets are {@linkcode ComponentHandle}s.
10
+ *
11
+ * `listTypes` (UI-const catalog), `getSillHeight` (bounds-derived), and the
12
+ * command-wired `mirror` land in a later pass.
13
+ */
14
+ export abstract class PluginDesignWindowsApi {
15
+ constructor() {}
16
+
17
+ /**
18
+ * Get the type name of a window — the label that identifies which kind of
19
+ * window the instance is, as shown in its properties.
20
+ *
21
+ * @param window The window to query
22
+ * @returns The type as a `string`, or `null`
23
+ *
24
+ * @examplePrompt What type of window is this?
25
+ * @examplePrompt Is the selected window a casement or a slider?
26
+ * @examplePrompt Tell me the window type used on this wall
27
+ * @examplePrompt Check what kind of window the living room has
28
+ *
29
+ * # Example
30
+ * ```ts
31
+ * const [win] = await snaptrude.design.query.listWindows({ isSelected: true })
32
+ * const type = await snaptrude.design.windows.getType(win)
33
+ * if (type) console.log("window type:", type)
34
+ * ```
35
+ */
36
+ public abstract getType(window: ComponentHandle): PluginApiReturn<string | null>
37
+
38
+ /**
39
+ * Get the width of a window — how wide its opening is along the host wall.
40
+ *
41
+ * @param window The window to query
42
+ * @returns The width as a `number`, or `null`
43
+ *
44
+ * @examplePrompt How wide is this window?
45
+ * @examplePrompt What's the width of the selected window?
46
+ * @examplePrompt Measure the width of the kitchen window
47
+ * @examplePrompt Check whether this window is 1200mm wide
48
+ *
49
+ * # Example
50
+ * ```ts
51
+ * const [win] = await snaptrude.design.query.listWindows()
52
+ * const width = await snaptrude.design.windows.getWidth(win)
53
+ * if (width !== null) console.log("window width:", width)
54
+ * ```
55
+ */
56
+ public abstract getWidth(window: ComponentHandle): PluginApiReturn<number | null>
57
+
58
+ /**
59
+ * Get the height of a window — how tall its opening is on the host wall.
60
+ *
61
+ * @param window The window to query
62
+ * @returns The height as a `number`, or `null`
63
+ *
64
+ * @examplePrompt How tall is this window?
65
+ * @examplePrompt What's the height of the selected window?
66
+ * @examplePrompt Check the window height on this wall
67
+ * @examplePrompt Is the bedroom window 1.5m high?
68
+ *
69
+ * # Example
70
+ * ```ts
71
+ * const [win] = await snaptrude.design.query.listWindows()
72
+ * const height = await snaptrude.design.windows.getHeight(win)
73
+ * if (height !== null) console.log("window height:", height)
74
+ * ```
75
+ */
76
+ public abstract getHeight(window: ComponentHandle): PluginApiReturn<number | null>
77
+
78
+ /**
79
+ * Get a window's full dimensions in one call — width along the wall, vertical
80
+ * height, and thickness through the wall — measured in the window's local
81
+ * oriented space.
82
+ *
83
+ * @param window The window to query
84
+ * @returns The dimensions, or `null`
85
+ *
86
+ * @examplePrompt What are the dimensions of this window?
87
+ * @examplePrompt How big is the selected window?
88
+ * @examplePrompt Give me the width, height and depth of this window
89
+ * @examplePrompt Measure the living room window
90
+ * @examplePrompt Get the window size including its thickness through the wall
91
+ *
92
+ * # Example
93
+ * ```ts
94
+ * const [win] = await snaptrude.design.query.listWindows({ isSelected: true })
95
+ * const dims = await snaptrude.design.windows.getDimensions(win)
96
+ * if (dims) console.log(dims.width, dims.height, dims.thickness)
97
+ * ```
98
+ */
99
+ public abstract getDimensions(
100
+ window: ComponentHandle
101
+ ): PluginApiReturn<PluginWindowDimensions | null>
102
+
103
+ /**
104
+ * Set the width of a window, resizing its opening and re-cutting the host
105
+ * wall. Width is in engine units; the change is undoable.
106
+ *
107
+ * @param window The window to resize
108
+ * @param width New width (engine units)
109
+ * @returns The affected window
110
+ *
111
+ * @examplePrompt Make this window 1200mm wide
112
+ * @examplePrompt Widen the selected window to 4 feet
113
+ * @examplePrompt Change the window width to 1.5m
114
+ * @examplePrompt Resize the kitchen window to 900 wide
115
+ *
116
+ * # Example
117
+ * ```ts
118
+ * // Takes a single window (unlike design.doors.setWidth, which takes an array)
119
+ * const [win] = await snaptrude.design.query.listWindows({ isSelected: true })
120
+ * const { affected } = await snaptrude.design.windows.setWidth(win, 1200)
121
+ * ```
122
+ */
123
+ public abstract setWidth(
124
+ window: ComponentHandle,
125
+ width: number
126
+ ): PluginApiReturn<PluginDesignChangeResult>
127
+
128
+ /**
129
+ * Set the height of a window, resizing its opening and re-cutting the host
130
+ * wall. Height is in engine units; the change is undoable.
131
+ *
132
+ * @param window The window to resize
133
+ * @param height New height (engine units)
134
+ * @returns The affected window
135
+ *
136
+ * @examplePrompt Make this window 1.5m tall
137
+ * @examplePrompt Change the window height to 4 feet
138
+ * @examplePrompt Shorten the selected window to 900mm high
139
+ * @examplePrompt Set the bedroom window height to 1200
140
+ *
141
+ * # Example
142
+ * ```ts
143
+ * const [win] = await snaptrude.design.query.listWindows({ isSelected: true })
144
+ * await snaptrude.design.windows.setHeight(win, 1500)
145
+ * ```
146
+ */
147
+ public abstract setHeight(
148
+ window: ComponentHandle,
149
+ height: number
150
+ ): PluginApiReturn<PluginDesignChangeResult>
151
+ }
152
+
153
+ /**
154
+ * Arguments for the single-window read methods.
155
+ *
156
+ * | Property | Type | Description |
157
+ * |---|---|---|
158
+ * | `window` | {@linkcode ComponentHandle} | The window to query |
159
+ */
160
+ export const PluginDesignWindowArgs = z.object({
161
+ window: ComponentHandle,
162
+ })
163
+ export type PluginDesignWindowArgs = z.infer<typeof PluginDesignWindowArgs>
164
+
165
+ /**
166
+ * A window's dimensions.
167
+ *
168
+ * | Property | Type | Description |
169
+ * |---|---|---|
170
+ * | `width` | `number` | Along the wall |
171
+ * | `height` | `number` | Vertical |
172
+ * | `thickness` | `number` | Through the wall (engine `length` axis) |
173
+ */
174
+ export const PluginWindowDimensions = z.object({
175
+ width: z.number(),
176
+ height: z.number(),
177
+ thickness: z.number(),
178
+ })
179
+ export type PluginWindowDimensions = z.infer<typeof PluginWindowDimensions>
180
+
181
+ /**
182
+ * Arguments for {@linkcode PluginDesignWindowsApi.setWidth}.
183
+ *
184
+ * | Property | Type | Description |
185
+ * |---|---|---|
186
+ * | `window` | {@linkcode ComponentHandle} | The window to resize |
187
+ * | `width` | `number` | New width (engine units) |
188
+ */
189
+ export const PluginDesignWindowSetWidthArgs = z.object({
190
+ window: ComponentHandle,
191
+ width: z.number(),
192
+ })
193
+ export type PluginDesignWindowSetWidthArgs = z.infer<typeof PluginDesignWindowSetWidthArgs>
194
+
195
+ /**
196
+ * Arguments for {@linkcode PluginDesignWindowsApi.setHeight}.
197
+ *
198
+ * | Property | Type | Description |
199
+ * |---|---|---|
200
+ * | `window` | {@linkcode ComponentHandle} | The window to resize |
201
+ * | `height` | `number` | New height (engine units) |
202
+ */
203
+ export const PluginDesignWindowSetHeightArgs = z.object({
204
+ window: ComponentHandle,
205
+ height: z.number(),
206
+ })
207
+ export type PluginDesignWindowSetHeightArgs = z.infer<typeof PluginDesignWindowSetHeightArgs>
@@ -0,0 +1,318 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+
4
+ /**
5
+ * Buildable Envelope management — create and update parametric zoning envelopes.
6
+ *
7
+ * A **buildable envelope** is the regulated volume inside which a building may
8
+ * be massed. The host owns envelope identity: {@linkcode PluginBuildableEnvelopeApi.create create}
9
+ * mints a `buildableEnvelopeId` and returns it; {@linkcode PluginBuildableEnvelopeApi.update update}
10
+ * requires that id to target the existing envelope.
11
+ *
12
+ * Accessed via `snaptrude.entity.buildableEnvelope`.
13
+ */
14
+ export abstract class PluginBuildableEnvelopeApi {
15
+ constructor() {}
16
+
17
+ /**
18
+ * Create a new parametric buildable envelope — the zoning-regulated volume a
19
+ * building may occupy — generated from a site polygon, tiered setbacks, a
20
+ * height or floor-count cap, and optional FAR and lot-coverage limits.
21
+ *
22
+ * @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
23
+ * @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
24
+ * @param setbacks - Setback profile, ground tier first; minimum 1 tier.
25
+ * @param verticalCap - Maximum height or floor count.
26
+ * @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
27
+ * @param farRatio - Optional FAR value, positive when provided.
28
+ * @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
29
+ * @returns A {@linkcode PluginBuildableEnvelopeCreateResult} with the
30
+ * `buildableEnvelopeId` of the created envelope.
31
+ * @throws If validation fails or generation produces no renderable geometry.
32
+ *
33
+ * @examplePrompt Create a buildable envelope for my site
34
+ * @examplePrompt Generate the zoning envelope with 10ft front setbacks
35
+ * @examplePrompt Show the maximum buildable volume with a 150ft height limit
36
+ * @examplePrompt Model the allowable massing from the setback rules
37
+ * @examplePrompt Create a zoning envelope capped at 12 floors with FAR 3
38
+ *
39
+ * # Example
40
+ * ```ts
41
+ * const { buildableEnvelopeId } = await snaptrude.entity.buildableEnvelope.create(
42
+ * [
43
+ * { x: 0, z: 0 },
44
+ * { x: 100, z: 0 },
45
+ * { x: 100, z: 80 },
46
+ * { x: 0, z: 80 },
47
+ * ],
48
+ * "ft",
49
+ * [
50
+ * { aboveHeight: 0, front: 10, side: 5, rear: 10 },
51
+ * { aboveHeight: 100, front: 20, side: 10, rear: 20 },
52
+ * ],
53
+ * { kind: "max_height", maxHeight: 150 },
54
+ * 12,
55
+ * )
56
+ * ```
57
+ */
58
+ public abstract create(
59
+ sitePolygon: PluginBuildableEnvelopePolygonVertex[],
60
+ lengthUnit: "ft" | "m",
61
+ setbacks: PluginBuildableEnvelopeSetbackTier[],
62
+ verticalCap: PluginBuildableEnvelopeVerticalCap,
63
+ floorToFloor: number,
64
+ farRatio?: number,
65
+ lotCoverageMaxPct?: number
66
+ ): PluginApiReturn<PluginBuildableEnvelopeCreateResult>
67
+
68
+ /**
69
+ * Update an existing parametric buildable envelope — regenerate the zoning
70
+ * volume from a revised site polygon, setbacks, vertical cap, or FAR and
71
+ * lot-coverage limits, keeping the same envelope id.
72
+ *
73
+ * @param buildableEnvelopeId - Existing envelope ID to update; non-empty and
74
+ * must match an existing envelope on the canvas.
75
+ * @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
76
+ * @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
77
+ * @param setbacks - Setback profile, ground tier first; minimum 1 tier.
78
+ * @param verticalCap - Maximum height or floor count.
79
+ * @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
80
+ * @param farRatio - Optional FAR value, positive when provided.
81
+ * @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
82
+ * @returns A {@linkcode PluginBuildableEnvelopeUpdateResult} with the
83
+ * `buildableEnvelopeId` of the updated envelope.
84
+ * @throws If validation fails, the envelope does not exist, or generation
85
+ * produces no renderable geometry.
86
+ *
87
+ * @examplePrompt Change the envelope's height limit to 175 feet
88
+ * @examplePrompt Update the setbacks on the buildable envelope
89
+ * @examplePrompt Regenerate the zoning envelope with a new site boundary
90
+ * @examplePrompt Increase the FAR on the buildable volume
91
+ * @examplePrompt Modify the envelope to allow 15 storeys instead
92
+ *
93
+ * # Example
94
+ * ```ts
95
+ * const { buildableEnvelopeId } = await snaptrude.entity.buildableEnvelope.update(
96
+ * existingId,
97
+ * [
98
+ * { x: 0, z: 0 },
99
+ * { x: 100, z: 0 },
100
+ * { x: 100, z: 80 },
101
+ * { x: 0, z: 80 },
102
+ * ],
103
+ * "ft",
104
+ * [{ aboveHeight: 0, front: 10, side: 5, rear: 10 }],
105
+ * { kind: "max_height", maxHeight: 175 },
106
+ * 12,
107
+ * )
108
+ * ```
109
+ */
110
+ public abstract update(
111
+ buildableEnvelopeId: string,
112
+ sitePolygon: PluginBuildableEnvelopePolygonVertex[],
113
+ lengthUnit: "ft" | "m",
114
+ setbacks: PluginBuildableEnvelopeSetbackTier[],
115
+ verticalCap: PluginBuildableEnvelopeVerticalCap,
116
+ floorToFloor: number,
117
+ farRatio?: number,
118
+ lotCoverageMaxPct?: number
119
+ ): PluginApiReturn<PluginBuildableEnvelopeUpdateResult>
120
+ }
121
+
122
+ /**
123
+ * Site polygon vertex in the request `lengthUnit`.
124
+ *
125
+ * Vertices may be passed as `{x, z}` objects or `[x, z]` tuples. Numeric
126
+ * values must be finite (no `NaN` or `±Infinity`).
127
+ */
128
+ export const PluginBuildableEnvelopePolygonVertex = z.union([
129
+ z.object({ x: z.number().finite(), z: z.number().finite() }).strict(),
130
+ z.tuple([z.number().finite(), z.number().finite()]),
131
+ ])
132
+
133
+ export type PluginBuildableEnvelopePolygonVertex = z.infer<
134
+ typeof PluginBuildableEnvelopePolygonVertex
135
+ >
136
+
137
+ /**
138
+ * Vertical cap for a buildable envelope.
139
+ *
140
+ * Use exactly one shape:
141
+ * - `{ kind: "max_height", maxHeight }`
142
+ * - `{ kind: "max_floors", maxFloors }`
143
+ *
144
+ * Floor-to-floor height is not nested here; it is always supplied as the
145
+ * top-level `floorToFloor` argument.
146
+ */
147
+ export const PluginBuildableEnvelopeVerticalCap = z.discriminatedUnion("kind", [
148
+ z.object({
149
+ kind: z.literal("max_height"),
150
+ maxHeight: z.number().finite().positive(),
151
+ }).strict(),
152
+ z.object({
153
+ kind: z.literal("max_floors"),
154
+ maxFloors: z.number().finite().int().positive(),
155
+ }).strict(),
156
+ ])
157
+
158
+ export type PluginBuildableEnvelopeVerticalCap = z.infer<
159
+ typeof PluginBuildableEnvelopeVerticalCap
160
+ >
161
+
162
+ /**
163
+ * One tier of a buildable envelope's setback profile.
164
+ *
165
+ * Tiers are ordered by `aboveHeight`. The first tier (index 0) must have
166
+ * `aboveHeight: 0` and describes the ground footprint; each subsequent tier
167
+ * describes the complete setback at a strictly greater height. Each tier
168
+ * carries its own `front`, `side`, and `rear` values — there is no
169
+ * inheritance from earlier tiers.
170
+ *
171
+ * All numeric values must be finite and nonnegative, in the request
172
+ * `lengthUnit`.
173
+ *
174
+ * | Property | Type | Description |
175
+ * |---|---|---|
176
+ * | `aboveHeight` | `number` | Height at or above which this tier applies; the ground tier uses `0` |
177
+ * | `front` | `number` | Front setback for this tier |
178
+ * | `side` | `number` | Side setback for this tier |
179
+ * | `rear` | `number` | Rear setback for this tier |
180
+ */
181
+ export const PluginBuildableEnvelopeSetbackTier = z.object({
182
+ aboveHeight: z.number().finite().nonnegative(),
183
+ front: z.number().finite().nonnegative(),
184
+ side: z.number().finite().nonnegative(),
185
+ rear: z.number().finite().nonnegative(),
186
+ }).strict()
187
+
188
+ export type PluginBuildableEnvelopeSetbackTier = z.infer<
189
+ typeof PluginBuildableEnvelopeSetbackTier
190
+ >
191
+
192
+ // Enforces setback tier ordering invariants on the parsed args shape:
193
+ // - setbacks[0].aboveHeight === 0
194
+ // - aboveHeight strictly increasing thereafter
195
+ // Length >= 1 is enforced earlier by z.array(...).min(1).
196
+ function refineSetbackTiers(
197
+ args: { setbacks: PluginBuildableEnvelopeSetbackTier[] },
198
+ ctx: z.RefinementCtx
199
+ ): void {
200
+ const tiers = args.setbacks
201
+ if (tiers.length === 0) return
202
+ if (tiers[0].aboveHeight !== 0) {
203
+ ctx.addIssue({
204
+ code: z.ZodIssueCode.custom,
205
+ path: ["setbacks", 0, "aboveHeight"],
206
+ message: "Ground tier required: setbacks[0].aboveHeight must be 0.",
207
+ })
208
+ }
209
+ for (let i = 1; i < tiers.length; i++) {
210
+ if (!(tiers[i].aboveHeight > tiers[i - 1].aboveHeight)) {
211
+ ctx.addIssue({
212
+ code: z.ZodIssueCode.custom,
213
+ path: ["setbacks", i, "aboveHeight"],
214
+ message:
215
+ "Setback tiers must be ordered by strictly increasing aboveHeight.",
216
+ })
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Arguments for {@linkcode PluginBuildableEnvelopeApi.create}.
223
+ *
224
+ * Strict schema. The host owns identity — no `buildableEnvelopeId` is accepted
225
+ * on create; the id is minted by the host and returned in
226
+ * {@linkcode PluginBuildableEnvelopeCreateResult}.
227
+ *
228
+ * | Property | Type | Description |
229
+ * |---|---|---|
230
+ * | `sitePolygon` | {@linkcode PluginBuildableEnvelopePolygonVertex}`[]` | Site polygon vertices in `lengthUnit`; minimum 3 vertices |
231
+ * | `lengthUnit` | `"ft" \| "m"` | Unit used by all length fields |
232
+ * | `setbacks` | {@linkcode PluginBuildableEnvelopeSetbackTier}`[]` | Setback profile, ground tier first; minimum 1 tier |
233
+ * | `verticalCap` | {@linkcode PluginBuildableEnvelopeVerticalCap} | Maximum height or floor count |
234
+ * | `floorToFloor` | `number` | Required floor-to-floor height in `lengthUnit` |
235
+ * | `farRatio` | `number?` | Optional FAR value, positive when provided |
236
+ * | `lotCoverageMaxPct` | `number?` | Optional lot coverage cap, `0..100` |
237
+ */
238
+ export const PluginBuildableEnvelopeCreateArgs = z
239
+ .object({
240
+ sitePolygon: z.array(PluginBuildableEnvelopePolygonVertex).min(3),
241
+ lengthUnit: z.union([z.literal("ft"), z.literal("m")]),
242
+ setbacks: z.array(PluginBuildableEnvelopeSetbackTier).min(1),
243
+ verticalCap: PluginBuildableEnvelopeVerticalCap,
244
+ floorToFloor: z.number().finite().positive(),
245
+ farRatio: z.number().finite().positive().optional(),
246
+ lotCoverageMaxPct: z.number().finite().min(0).max(100).optional(),
247
+ })
248
+ .strict()
249
+ .superRefine(refineSetbackTiers)
250
+
251
+ export type PluginBuildableEnvelopeCreateArgs = z.infer<
252
+ typeof PluginBuildableEnvelopeCreateArgs
253
+ >
254
+
255
+ /**
256
+ * Result of {@linkcode PluginBuildableEnvelopeApi.create}.
257
+ *
258
+ * | Property | Type | Description |
259
+ * |---|---|---|
260
+ * | `buildableEnvelopeId` | `string` | Non-empty unique ID of the created buildable envelope |
261
+ */
262
+ export const PluginBuildableEnvelopeCreateResult = z.object({
263
+ buildableEnvelopeId: z.string().min(1),
264
+ }).strict()
265
+
266
+ export type PluginBuildableEnvelopeCreateResult = z.infer<
267
+ typeof PluginBuildableEnvelopeCreateResult
268
+ >
269
+
270
+ /**
271
+ * Arguments for {@linkcode PluginBuildableEnvelopeApi.update}.
272
+ *
273
+ * Strict schema. `buildableEnvelopeId` is required and identifies the prior
274
+ * envelope on the canvas to update.
275
+ *
276
+ * | Property | Type | Description |
277
+ * |---|---|---|
278
+ * | `buildableEnvelopeId` | `string` | Existing envelope ID to update; non-empty |
279
+ * | `sitePolygon` | {@linkcode PluginBuildableEnvelopePolygonVertex}`[]` | Site polygon vertices in `lengthUnit`; minimum 3 vertices |
280
+ * | `lengthUnit` | `"ft" \| "m"` | Unit used by all length fields |
281
+ * | `setbacks` | {@linkcode PluginBuildableEnvelopeSetbackTier}`[]` | Setback profile, ground tier first; minimum 1 tier |
282
+ * | `verticalCap` | {@linkcode PluginBuildableEnvelopeVerticalCap} | Maximum height or floor count |
283
+ * | `floorToFloor` | `number` | Required floor-to-floor height in `lengthUnit` |
284
+ * | `farRatio` | `number?` | Optional FAR value, positive when provided |
285
+ * | `lotCoverageMaxPct` | `number?` | Optional lot coverage cap, `0..100` |
286
+ */
287
+ export const PluginBuildableEnvelopeUpdateArgs = z
288
+ .object({
289
+ buildableEnvelopeId: z.string().min(1),
290
+ sitePolygon: z.array(PluginBuildableEnvelopePolygonVertex).min(3),
291
+ lengthUnit: z.union([z.literal("ft"), z.literal("m")]),
292
+ setbacks: z.array(PluginBuildableEnvelopeSetbackTier).min(1),
293
+ verticalCap: PluginBuildableEnvelopeVerticalCap,
294
+ floorToFloor: z.number().finite().positive(),
295
+ farRatio: z.number().finite().positive().optional(),
296
+ lotCoverageMaxPct: z.number().finite().min(0).max(100).optional(),
297
+ })
298
+ .strict()
299
+ .superRefine(refineSetbackTiers)
300
+
301
+ export type PluginBuildableEnvelopeUpdateArgs = z.infer<
302
+ typeof PluginBuildableEnvelopeUpdateArgs
303
+ >
304
+
305
+ /**
306
+ * Result of {@linkcode PluginBuildableEnvelopeApi.update}.
307
+ *
308
+ * | Property | Type | Description |
309
+ * |---|---|---|
310
+ * | `buildableEnvelopeId` | `string` | Non-empty unique ID of the updated buildable envelope |
311
+ */
312
+ export const PluginBuildableEnvelopeUpdateResult = z.object({
313
+ buildableEnvelopeId: z.string().min(1),
314
+ }).strict()
315
+
316
+ export type PluginBuildableEnvelopeUpdateResult = z.infer<
317
+ typeof PluginBuildableEnvelopeUpdateResult
318
+ >
@@ -1,113 +0,0 @@
1
- import * as z from "zod"
2
- import { PluginApiReturn } from "../../types"
3
-
4
- /**
5
- * Department management — create and query departments.
6
- *
7
- * A **department** is a named, colored grouping applied to spaces.
8
- * Departments are used to categorize spaces by function (e.g. "FOH",
9
- * "Emergency", "Residential") and control their visual appearance.
10
- *
11
- * Accessed via `snaptrude.entity.department`.
12
- */
13
- export abstract class PluginDepartmentApi {
14
- constructor() {}
15
-
16
- /**
17
- * Create a new department.
18
- *
19
- * @param args - An object containing:
20
- * - {@linkcode PluginDepartmentCreateArgs.name args.name} — Display name
21
- * - {@linkcode PluginDepartmentCreateArgs.color args.color} — CSS hex color string (e.g. `"#b5e1dc"`)
22
- * @returns A {@linkcode PluginDepartmentCreateResult} with the `departmentId`
23
- * of the created department
24
- * @throws If department creation fails
25
- *
26
- * # Example
27
- * ```ts
28
- * const { departmentId } = await snaptrude.entity.department.create({
29
- * name: "Emergency",
30
- * color: "#f5e68b",
31
- * })
32
- * ```
33
- */
34
- public abstract create(
35
- args: PluginDepartmentCreateArgs
36
- ): PluginApiReturn<PluginDepartmentCreateResult>
37
-
38
- /**
39
- * Get all departments in the current project.
40
- *
41
- * Returns every department including well-known ones (Default, Site, etc.)
42
- * and user-created departments.
43
- *
44
- * @returns A {@linkcode PluginDepartmentGetAllResult} with a `departments` array
45
- *
46
- * # Example
47
- * ```ts
48
- * const { departments } = await snaptrude.entity.department.getAll()
49
- * for (const dept of departments) {
50
- * console.log(dept.id, dept.name, dept.color)
51
- * }
52
- * ```
53
- */
54
- public abstract getAll(): PluginApiReturn<PluginDepartmentGetAllResult>
55
- }
56
-
57
- /**
58
- * Arguments for {@linkcode PluginDepartmentApi.create}.
59
- *
60
- * | Property | Type | Description |
61
- * |---|---|---|
62
- * | `name` | `string` | Display name of the department |
63
- * | `color` | `string` | CSS hex color string (e.g. `"#b5e1dc"`) |
64
- */
65
- export const PluginDepartmentCreateArgs = z.object({
66
- name: z.string(),
67
- color: z.string(),
68
- })
69
-
70
- export type PluginDepartmentCreateArgs = z.infer<
71
- typeof PluginDepartmentCreateArgs
72
- >
73
-
74
- /**
75
- * Result of {@linkcode PluginDepartmentApi.create}.
76
- *
77
- * | Property | Type | Description |
78
- * |---|---|---|
79
- * | `departmentId` | `string` | Unique ID of the created department |
80
- */
81
- export const PluginDepartmentCreateResult = z.object({
82
- departmentId: z.string(),
83
- })
84
-
85
- export type PluginDepartmentCreateResult = z.infer<
86
- typeof PluginDepartmentCreateResult
87
- >
88
-
89
- /**
90
- * A single department entry returned by {@linkcode PluginDepartmentApi.getAll}.
91
- */
92
- export const PluginDepartmentEntry = z.object({
93
- id: z.string(),
94
- name: z.string(),
95
- color: z.string(),
96
- })
97
-
98
- export type PluginDepartmentEntry = z.infer<typeof PluginDepartmentEntry>
99
-
100
- /**
101
- * Result of {@linkcode PluginDepartmentApi.getAll}.
102
- *
103
- * | Property | Type | Description |
104
- * |---|---|---|
105
- * | `departments` | {@linkcode PluginDepartmentEntry}`[]` | All departments in the project |
106
- */
107
- export const PluginDepartmentGetAllResult = z.object({
108
- departments: z.array(PluginDepartmentEntry),
109
- })
110
-
111
- export type PluginDepartmentGetAllResult = z.infer<
112
- typeof PluginDepartmentGetAllResult
113
- >
@@ -1,30 +1,30 @@
1
- import { PluginDepartmentApi } from "./department"
1
+ import { PluginBuildableEnvelopeApi } from "./buildableEnvelope"
2
2
  import { PluginReferenceLineApi } from "./referenceLine"
3
- import { PluginSpaceApi } from "./space"
4
3
  import { PluginStoryApi } from "./story"
5
4
 
6
5
  /**
7
6
  * CRUD operations on Snaptrude building entities.
8
7
  *
9
- * - {@linkcode PluginEntityApi.space} — Create, query, and delete spaces (rooms/masses)
10
8
  * - {@linkcode PluginEntityApi.story} — Create, query, and update stories (floors)
11
9
  * - {@linkcode PluginEntityApi.referenceLine} — Create, query, and delete reference lines
12
- * - {@linkcode PluginEntityApi.department} — Create and query departments
10
+ * - {@linkcode PluginEntityApi.buildableEnvelope} — Create or update parametric buildable envelopes
11
+ *
12
+ * Space operations moved to `design.create.spaces` / `design.update.*` /
13
+ * `design.query.*` / `design.delete.entities` (the `entity.space` API was removed);
14
+ * `./space` still exports the shared space value types.
13
15
  */
14
16
  export abstract class PluginEntityApi {
15
- /** Space (room/mass) operations. See {@linkcode PluginSpaceApi}. */
16
- public abstract space: PluginSpaceApi
17
17
  /** Story (floor/storey) operations. See {@linkcode PluginStoryApi}. */
18
18
  public abstract story: PluginStoryApi
19
19
  /** Reference line operations. See {@linkcode PluginReferenceLineApi}. */
20
20
  public abstract referenceLine: PluginReferenceLineApi
21
- /** Department operations. See {@linkcode PluginDepartmentApi}. */
22
- public abstract department: PluginDepartmentApi
21
+ /** Buildable Envelope operations. See {@linkcode PluginBuildableEnvelopeApi}. */
22
+ public abstract buildableEnvelope: PluginBuildableEnvelopeApi
23
23
 
24
24
  constructor() {}
25
25
  }
26
26
 
27
- export * from "./department"
27
+ export * from "./buildableEnvelope"
28
28
  export * from "./referenceLine"
29
29
  export * from "./space"
30
30
  export * from "./story"