@snaptrude/plugin-core 0.0.0-dev-20260708130115 → 0.0.0-dev-20260827135706

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 (261) hide show
  1. package/CHANGELOG.md +152 -1
  2. package/api-manifest.json +3620 -276
  3. package/dist/api/analysis/daylight.d.ts +603 -0
  4. package/dist/api/analysis/daylight.d.ts.map +1 -0
  5. package/dist/api/analysis/heatmaps.d.ts +658 -0
  6. package/dist/api/analysis/heatmaps.d.ts.map +1 -0
  7. package/dist/api/analysis/illuminance.d.ts +145 -0
  8. package/dist/api/analysis/illuminance.d.ts.map +1 -0
  9. package/dist/api/analysis/index.d.ts +59 -0
  10. package/dist/api/analysis/index.d.ts.map +1 -0
  11. package/dist/api/analysis/shadows.d.ts +165 -0
  12. package/dist/api/analysis/shadows.d.ts.map +1 -0
  13. package/dist/api/analysis/solar.d.ts +249 -0
  14. package/dist/api/analysis/solar.d.ts.map +1 -0
  15. package/dist/api/analysis/sunlightHours.d.ts +208 -0
  16. package/dist/api/analysis/sunlightHours.d.ts.map +1 -0
  17. package/dist/api/analysis/sunpath.d.ts +80 -0
  18. package/dist/api/analysis/sunpath.d.ts.map +1 -0
  19. package/dist/api/analysis/weather.d.ts +193 -0
  20. package/dist/api/analysis/weather.d.ts.map +1 -0
  21. package/dist/api/core/camera/index.d.ts +261 -0
  22. package/dist/api/core/camera/index.d.ts.map +1 -0
  23. package/dist/api/core/comment/index.d.ts +105 -2
  24. package/dist/api/core/comment/index.d.ts.map +1 -1
  25. package/dist/api/core/geom/create/index.d.ts +840 -14
  26. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  27. package/dist/api/core/geom/delete/index.d.ts +8 -2
  28. package/dist/api/core/geom/delete/index.d.ts.map +1 -1
  29. package/dist/api/core/geom/query/arc.d.ts +5 -5
  30. package/dist/api/core/geom/query/brep.d.ts +130 -18
  31. package/dist/api/core/geom/query/brep.d.ts.map +1 -1
  32. package/dist/api/core/geom/query/circle.d.ts +18 -18
  33. package/dist/api/core/geom/query/contour.d.ts +20 -20
  34. package/dist/api/core/geom/query/curve.d.ts +49 -49
  35. package/dist/api/core/geom/query/edge.d.ts +5 -5
  36. package/dist/api/core/geom/query/face.d.ts +16 -16
  37. package/dist/api/core/geom/query/halfedge.d.ts +8 -8
  38. package/dist/api/core/geom/query/profile.d.ts +19 -19
  39. package/dist/api/core/geom/query/vertex.d.ts +8 -8
  40. package/dist/api/core/geom/update/contour.d.ts +14 -14
  41. package/dist/api/core/geom/update/curve.d.ts +7 -7
  42. package/dist/api/core/geom/update/profile.d.ts +16 -16
  43. package/dist/api/core/handles/index.d.ts +210 -0
  44. package/dist/api/core/handles/index.d.ts.map +1 -0
  45. package/dist/api/core/index.d.ts +34 -0
  46. package/dist/api/core/index.d.ts.map +1 -1
  47. package/dist/api/core/io/export/index.d.ts +134 -0
  48. package/dist/api/core/io/export/index.d.ts.map +1 -0
  49. package/dist/api/core/io/import/index.d.ts +453 -0
  50. package/dist/api/core/io/import/index.d.ts.map +1 -0
  51. package/dist/api/core/io/index.d.ts +40 -0
  52. package/dist/api/core/io/index.d.ts.map +1 -0
  53. package/dist/api/core/io/job/index.d.ts +139 -0
  54. package/dist/api/core/io/job/index.d.ts.map +1 -0
  55. package/dist/api/core/io/query/index.d.ts +74 -0
  56. package/dist/api/core/io/query/index.d.ts.map +1 -0
  57. package/dist/api/core/io/terrain/index.d.ts +341 -0
  58. package/dist/api/core/io/terrain/index.d.ts.map +1 -0
  59. package/dist/api/core/io/underlay/index.d.ts +805 -0
  60. package/dist/api/core/io/underlay/index.d.ts.map +1 -0
  61. package/dist/api/core/layers.d.ts +7 -7
  62. package/dist/api/core/mode/index.d.ts +99 -0
  63. package/dist/api/core/mode/index.d.ts.map +1 -0
  64. package/dist/api/core/project/index.d.ts +68 -1
  65. package/dist/api/core/project/index.d.ts.map +1 -1
  66. package/dist/api/core/proposals/index.d.ts +531 -0
  67. package/dist/api/core/proposals/index.d.ts.map +1 -0
  68. package/dist/api/core/storeys/index.d.ts +265 -0
  69. package/dist/api/core/storeys/index.d.ts.map +1 -0
  70. package/dist/api/core/tags.d.ts +24 -0
  71. package/dist/api/core/tags.d.ts.map +1 -1
  72. package/dist/api/core/user.d.ts +44 -0
  73. package/dist/api/core/user.d.ts.map +1 -0
  74. package/dist/api/core/zoom/index.d.ts +4 -0
  75. package/dist/api/core/zoom/index.d.ts.map +1 -1
  76. package/dist/api/design/boolean/index.d.ts +4 -4
  77. package/dist/api/design/create/index.d.ts +568 -45
  78. package/dist/api/design/create/index.d.ts.map +1 -1
  79. package/dist/api/design/delete/index.d.ts +3 -0
  80. package/dist/api/design/delete/index.d.ts.map +1 -1
  81. package/dist/api/design/doors/index.d.ts +195 -0
  82. package/dist/api/design/doors/index.d.ts.map +1 -1
  83. package/dist/api/design/edit/index.d.ts +1 -1
  84. package/dist/api/design/erase/index.d.ts +2 -2
  85. package/dist/api/design/family.d.ts +349 -0
  86. package/dist/api/design/family.d.ts.map +1 -0
  87. package/dist/api/design/furniture/index.d.ts +181 -8
  88. package/dist/api/design/furniture/index.d.ts.map +1 -1
  89. package/dist/api/design/index.d.ts +98 -0
  90. package/dist/api/design/index.d.ts.map +1 -1
  91. package/dist/api/design/lock.d.ts +26 -0
  92. package/dist/api/design/lock.d.ts.map +1 -1
  93. package/dist/api/design/materials/index.d.ts +270 -16
  94. package/dist/api/design/materials/index.d.ts.map +1 -1
  95. package/dist/api/design/query/geometry/index.d.ts +112 -0
  96. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  97. package/dist/api/design/query/index.d.ts +282 -11
  98. package/dist/api/design/query/index.d.ts.map +1 -1
  99. package/dist/api/design/query/referenceLines.d.ts +45 -0
  100. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  101. package/dist/api/design/query/spaces.d.ts +181 -8
  102. package/dist/api/design/query/spaces.d.ts.map +1 -1
  103. package/dist/api/design/selection/index.d.ts +144 -0
  104. package/dist/api/design/selection/index.d.ts.map +1 -1
  105. package/dist/api/design/transform/index.d.ts +172 -10
  106. package/dist/api/design/transform/index.d.ts.map +1 -1
  107. package/dist/api/design/types/index.d.ts +181 -0
  108. package/dist/api/design/types/index.d.ts.map +1 -0
  109. package/dist/api/design/update/index.d.ts +553 -2
  110. package/dist/api/design/update/index.d.ts.map +1 -1
  111. package/dist/api/design/visibility.d.ts +126 -0
  112. package/dist/api/design/visibility.d.ts.map +1 -0
  113. package/dist/api/design/windows/index.d.ts +113 -2
  114. package/dist/api/design/windows/index.d.ts.map +1 -1
  115. package/dist/api/entity/buildableEnvelope.d.ts +4 -0
  116. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
  117. package/dist/api/entity/referenceLine.d.ts +10 -2
  118. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  119. package/dist/api/entity/space.d.ts +21 -21
  120. package/dist/api/entity/story.d.ts +242 -15
  121. package/dist/api/entity/story.d.ts.map +1 -1
  122. package/dist/api/index.d.ts +10 -0
  123. package/dist/api/index.d.ts.map +1 -1
  124. package/dist/api/presentation/aiInspiration.d.ts +25 -25
  125. package/dist/api/presentation/annotate.d.ts +467 -0
  126. package/dist/api/presentation/annotate.d.ts.map +1 -0
  127. package/dist/api/presentation/diagrams.d.ts +111 -8
  128. package/dist/api/presentation/diagrams.d.ts.map +1 -1
  129. package/dist/api/presentation/export.d.ts +108 -0
  130. package/dist/api/presentation/export.d.ts.map +1 -0
  131. package/dist/api/presentation/import.d.ts +55 -4
  132. package/dist/api/presentation/import.d.ts.map +1 -1
  133. package/dist/api/presentation/index.d.ts +58 -1
  134. package/dist/api/presentation/index.d.ts.map +1 -1
  135. package/dist/api/presentation/placedViews.d.ts +1139 -0
  136. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  137. package/dist/api/presentation/shapes.d.ts +481 -0
  138. package/dist/api/presentation/shapes.d.ts.map +1 -0
  139. package/dist/api/presentation/sheets.d.ts +452 -13
  140. package/dist/api/presentation/sheets.d.ts.map +1 -1
  141. package/dist/api/presentation/slideshow.d.ts +125 -0
  142. package/dist/api/presentation/slideshow.d.ts.map +1 -0
  143. package/dist/api/presentation/tables.d.ts +81 -0
  144. package/dist/api/presentation/tables.d.ts.map +1 -0
  145. package/dist/api/presentation/views.d.ts +367 -7
  146. package/dist/api/presentation/views.d.ts.map +1 -1
  147. package/dist/api/program/areas.d.ts +102 -12
  148. package/dist/api/program/areas.d.ts.map +1 -1
  149. package/dist/api/program/cores.d.ts +3 -99
  150. package/dist/api/program/cores.d.ts.map +1 -1
  151. package/dist/api/program/index.d.ts +7 -15
  152. package/dist/api/program/index.d.ts.map +1 -1
  153. package/dist/api/program/layout.d.ts +346 -11
  154. package/dist/api/program/layout.d.ts.map +1 -1
  155. package/dist/api/program/site.d.ts +469 -13
  156. package/dist/api/program/site.d.ts.map +1 -1
  157. package/dist/api/program/spreadsheet.d.ts +365 -41
  158. package/dist/api/program/spreadsheet.d.ts.map +1 -1
  159. package/dist/api/workspace/index.d.ts +505 -0
  160. package/dist/api/workspace/index.d.ts.map +1 -0
  161. package/dist/errors/codes.d.ts +34 -0
  162. package/dist/errors/codes.d.ts.map +1 -0
  163. package/dist/errors/envelope.d.ts +56 -0
  164. package/dist/errors/envelope.d.ts.map +1 -0
  165. package/dist/errors/index.d.ts +6 -0
  166. package/dist/errors/index.d.ts.map +1 -0
  167. package/dist/errors/plugin-error.d.ts +69 -0
  168. package/dist/errors/plugin-error.d.ts.map +1 -0
  169. package/dist/handles.d.ts +97 -25
  170. package/dist/handles.d.ts.map +1 -1
  171. package/dist/host-utils.d.ts +4 -0
  172. package/dist/host-utils.d.ts.map +1 -1
  173. package/dist/index.cjs +4582 -1422
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.d.ts +1 -0
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +4171 -1411
  178. package/dist/index.js.map +1 -1
  179. package/package.json +4 -2
  180. package/scripts/generate-manifest.mjs +45 -0
  181. package/scripts/generate-manifest.test.mjs +103 -4
  182. package/src/api/analysis/daylight.ts +470 -0
  183. package/src/api/analysis/heatmaps.ts +683 -0
  184. package/src/api/analysis/illuminance.ts +155 -0
  185. package/src/api/analysis/index.ts +61 -0
  186. package/src/api/analysis/shadows.ts +183 -0
  187. package/src/api/analysis/solar.ts +237 -0
  188. package/src/api/analysis/sunlightHours.ts +211 -0
  189. package/src/api/analysis/sunpath.ts +83 -0
  190. package/src/api/analysis/weather.ts +179 -0
  191. package/src/api/core/camera/index.ts +268 -0
  192. package/src/api/core/comment/index.ts +120 -2
  193. package/src/api/core/geom/create/index.ts +912 -1
  194. package/src/api/core/geom/delete/index.ts +6 -0
  195. package/src/api/core/geom/query/brep.ts +119 -0
  196. package/src/api/core/handles/index.ts +233 -0
  197. package/src/api/core/index.ts +34 -0
  198. package/src/api/core/io/export/index.ts +126 -0
  199. package/src/api/core/io/import/index.ts +496 -0
  200. package/src/api/core/io/index.ts +42 -0
  201. package/src/api/core/io/job/index.ts +140 -0
  202. package/src/api/core/io/query/index.ts +71 -0
  203. package/src/api/core/io/terrain/index.ts +360 -0
  204. package/src/api/core/io/underlay/index.ts +705 -0
  205. package/src/api/core/mode/index.ts +96 -0
  206. package/src/api/core/project/index.ts +62 -1
  207. package/src/api/core/proposals/index.ts +569 -0
  208. package/src/api/core/storeys/index.ts +294 -0
  209. package/src/api/core/tags.ts +27 -0
  210. package/src/api/core/user.ts +46 -0
  211. package/src/api/core/zoom/index.ts +4 -0
  212. package/src/api/design/create/index.ts +670 -30
  213. package/src/api/design/delete/index.ts +3 -0
  214. package/src/api/design/doors/index.ts +208 -0
  215. package/src/api/design/erase/index.ts +1 -1
  216. package/src/api/design/family.ts +388 -0
  217. package/src/api/design/furniture/index.ts +197 -8
  218. package/src/api/design/index.ts +102 -0
  219. package/src/api/design/lock.ts +27 -0
  220. package/src/api/design/materials/index.ts +334 -27
  221. package/src/api/design/query/geometry/index.ts +125 -3
  222. package/src/api/design/query/index.ts +217 -7
  223. package/src/api/design/query/referenceLines.ts +52 -0
  224. package/src/api/design/query/spaces.ts +143 -0
  225. package/src/api/design/selection/index.ts +129 -0
  226. package/src/api/design/transform/index.ts +170 -9
  227. package/src/api/design/types/index.ts +156 -0
  228. package/src/api/design/update/index.ts +631 -3
  229. package/src/api/design/visibility.ts +143 -0
  230. package/src/api/design/windows/index.ts +128 -2
  231. package/src/api/entity/buildableEnvelope.ts +4 -0
  232. package/src/api/entity/referenceLine.ts +8 -0
  233. package/src/api/entity/story.ts +259 -15
  234. package/src/api/index.ts +10 -0
  235. package/src/api/presentation/annotate.ts +385 -0
  236. package/src/api/presentation/diagrams.ts +118 -8
  237. package/src/api/presentation/export.ts +108 -0
  238. package/src/api/presentation/import.ts +51 -4
  239. package/src/api/presentation/index.ts +66 -1
  240. package/src/api/presentation/placedViews.ts +1120 -0
  241. package/src/api/presentation/shapes.ts +274 -0
  242. package/src/api/presentation/sheets.ts +400 -13
  243. package/src/api/presentation/slideshow.ts +134 -0
  244. package/src/api/presentation/tables.ts +84 -0
  245. package/src/api/presentation/views.ts +376 -8
  246. package/src/api/program/areas.ts +88 -15
  247. package/src/api/program/cores.ts +3 -91
  248. package/src/api/program/index.ts +7 -15
  249. package/src/api/program/layout.ts +365 -11
  250. package/src/api/program/site.ts +435 -13
  251. package/src/api/program/spreadsheet.ts +376 -35
  252. package/src/api/workspace/index.ts +563 -0
  253. package/src/errors/codes.ts +136 -0
  254. package/src/errors/envelope.ts +75 -0
  255. package/src/errors/index.ts +21 -0
  256. package/src/errors/plugin-error.ts +134 -0
  257. package/src/handles.ts +123 -13
  258. package/src/host-utils.ts +4 -0
  259. package/src/index.ts +1 -0
  260. package/test/errors.test.mjs +184 -0
  261. package/tsconfig.json +7 -2
@@ -0,0 +1,84 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import type { PluginCanvasShape } from "./placedViews"
4
+
5
+ /**
6
+ * Presentation tables — place data tables on Present-mode sheets.
7
+ *
8
+ * The scriptable counterpart of the Present canvas's table paste (the flow
9
+ * that turns a Program-mode / Google Sheets / Excel paste into a table
10
+ * shape): {@linkcode PluginPresentationTablesApi.place} takes plain string
11
+ * rows and creates one table shape on a sheet. Requires Present mode to be
12
+ * open.
13
+ *
14
+ * Accessed via `snaptrude.presentation.tables`.
15
+ */
16
+ export abstract class PluginPresentationTablesApi {
17
+ constructor() {}
18
+
19
+ /**
20
+ * Place a table on a sheet.
21
+ *
22
+ * Creates one table shape from `table.rows` — the same shape the Present
23
+ * canvas creates when a spreadsheet table is pasted — and returns the
24
+ * created shape as a canvas-shape record. Cells are plain strings; rows may
25
+ * be ragged (each row needs at least one cell), capped at 10000 cells
26
+ * total. `options.position` is sheet-local (relative to the sheet's
27
+ * top-left, in canvas units — the same convention as `annotate.*`); when
28
+ * omitted the table lands where the paste flow would auto-place it (the
29
+ * center of the current viewport). One undo step. Requires Present mode to
30
+ * be open.
31
+ *
32
+ * @param sheetId - The sheet to place the table on.
33
+ * @param table - The table content: `rows`, an array of string-cell rows.
34
+ * @param options - Optional `position` (`{ x, y }`, relative to the sheet's
35
+ * top-left — defaults to the paste flow's auto-placement).
36
+ * @returns The created table shape as a {@linkcode PluginCanvasShape}.
37
+ * @throws If Present mode is not open, the sheet id is invalid, or the
38
+ * table is empty / exceeds the 10000-cell cap.
39
+ *
40
+ * @examplePrompt Put the area schedule as a table on Sheet 1
41
+ * @examplePrompt Add a table of the room programs to the cover sheet
42
+ * @examplePrompt Paste this data as a table on the sheet
43
+ * @examplePrompt Place a two-column table of space names and areas
44
+ *
45
+ * # Example
46
+ * ```ts
47
+ * const shape = await snaptrude.presentation.tables.place("sheet_1", {
48
+ * rows: [
49
+ * ["Room", "Area"],
50
+ * ["Kitchen", "12.4 m²"],
51
+ * ["Living", "28.0 m²"],
52
+ * ],
53
+ * }, { position: { x: 40, y: 40 } })
54
+ * ```
55
+ */
56
+ public abstract place(
57
+ sheetId: string,
58
+ table: { rows: string[][] },
59
+ options?: { position?: { x: number; y: number } },
60
+ ): PluginApiReturn<PluginCanvasShape>
61
+ }
62
+
63
+ /**
64
+ * Arguments for {@linkcode PluginPresentationTablesApi.place}.
65
+ *
66
+ * | Property | Type | Description |
67
+ * |---|---|---|
68
+ * | `sheetId` | `string` | The sheet to place the table on |
69
+ * | `rows` | `string[][]` | Table cells as string rows (non-empty; ≤ 10000 cells total) |
70
+ * | `position` | `{ x: number; y: number } \| undefined` | Sheet-local position (default: paste auto-placement) |
71
+ */
72
+ export const PluginPresentationTablesPlaceArgs = z.object({
73
+ sheetId: z.string().min(1),
74
+ rows: z
75
+ .array(z.array(z.string()).min(1))
76
+ .min(1)
77
+ .refine((rows) => rows.reduce((n, r) => n + r.length, 0) <= 10000, {
78
+ message: "table exceeds the 10000-cell cap",
79
+ }),
80
+ position: z.object({ x: z.number(), y: z.number() }).optional(),
81
+ })
82
+ export type PluginPresentationTablesPlaceArgs = z.infer<
83
+ typeof PluginPresentationTablesPlaceArgs
84
+ >
@@ -6,12 +6,14 @@ import { PluginApiReturn } from "../../types"
6
6
  *
7
7
  * A **view** is a saved camera/plan: a sheet-ready 2D plan or a saved 3D view.
8
8
  * A plugin can list and read views, capture them to images, activate one (move
9
- * the camera to it), and save the current camera as a new view.
9
+ * the camera to it), save the current camera as a new view, rename or delete a
10
+ * saved view, and read/update a view's display settings (background, color
11
+ * mode, view mode, axis, edges, labels). Each view carries the `storey` it was
12
+ * saved on.
10
13
  *
11
- * `list`/`get`/`getActive`/`capture` are reads; `setActive`/`create` are writes
12
- * (a view is a camera bookmark — not geometry). Members typed optional (`?`) are
13
- * authored ahead of the host: declared for plugins/codegen but not yet on the
14
- * live discovery surface until the host lands them.
14
+ * `list`/`get`/`getActive`/`capture`/`getSettings` are reads;
15
+ * `setActive`/`create`/`rename`/`delete`/`updateSettings` are writes (a view is
16
+ * a camera bookmark not geometry).
15
17
  *
16
18
  * Accessed via `snaptrude.presentation.views`.
17
19
  */
@@ -135,24 +137,179 @@ export abstract class PluginPresentationViewsApi {
135
137
  * Creates a camera bookmark (not geometry) from where the camera is now.
136
138
  *
137
139
  * @param name - Name for the new view (a default is used when omitted).
138
- * @param options - Optional `kind`: what kind of view to save (default `"view"`).
140
+ * @param options - Optional `kind` (what kind of view to save, default
141
+ * `"view"`) and `storey` (save the view on a specific storey — the storey is
142
+ * activated first, matching the storey the view is captured on; when omitted
143
+ * the current active storey is used).
139
144
  * @returns The newly created {@linkcode PluginPresentationView}.
140
- * @throws If the view could not be saved.
145
+ * @throws If `storey` is given but no such storey exists, or the view could
146
+ * not be saved.
141
147
  *
142
148
  * @examplePrompt Save the current view as Lobby Perspective
143
149
  * @examplePrompt Create a new saved view from where I'm looking
144
150
  * @examplePrompt Bookmark this camera angle
145
151
  * @examplePrompt Save the current 2D plan as a view
152
+ * @examplePrompt Save a view on the second storey
146
153
  *
147
154
  * # Example
148
155
  * ```ts
149
156
  * const view = await snaptrude.presentation.views.create("Lobby")
157
+ * // …or capture the view on a specific storey
158
+ * const level2 = await snaptrude.presentation.views.create("Level 2", { storey: 2 })
150
159
  * ```
151
160
  */
152
161
  public abstract create(
153
162
  name?: string,
154
- options?: { kind?: "view" | "sitePlan" },
163
+ options?: { kind?: "view" | "sitePlan"; storey?: number },
155
164
  ): PluginApiReturn<PluginPresentationViewsCreateResult>
165
+
166
+ /**
167
+ * Read a saved view's display settings (background, color mode, view mode,
168
+ * axis, edges, labels).
169
+ *
170
+ * @param viewId - The id of the view to read settings for.
171
+ * @returns The view's {@linkcode PluginPresentationViewSettings}, or `null` if
172
+ * no view has that id.
173
+ *
174
+ * @examplePrompt What color mode is the Ground Floor view using?
175
+ * @examplePrompt Get the display settings for this view
176
+ * @examplePrompt Does the site plan view show axes and labels?
177
+ * @examplePrompt Read the background color of the active view
178
+ *
179
+ * # Example
180
+ * ```ts
181
+ * const settings = await snaptrude.presentation.views.getSettings("view_123")
182
+ * if (settings) console.log(settings.colorMode, settings.backgroundColor)
183
+ * ```
184
+ */
185
+ public abstract getSettings(
186
+ viewId: string,
187
+ ): PluginApiReturn<PluginPresentationViewsGetSettingsResult>
188
+
189
+ /**
190
+ * Update a saved view's display settings (partial patch — only the fields you
191
+ * pass change).
192
+ *
193
+ * Persists and broadcasts the change; if the view is currently active, the
194
+ * scene updates live. **Not Ctrl+Z-undoable** — view-metadata edits publish
195
+ * directly and do not land on the local undo stack; this matches how the
196
+ * product's own view-settings UI behaves.
197
+ *
198
+ * Label patch semantics (mirroring the product, which stores no label
199
+ * selection while labels are off):
200
+ *
201
+ * - `{ showLabels: true }` alone turns labels on; if the view has no stored
202
+ * selection, the product defaults (`objectLabels`, `areas`) are applied —
203
+ * labels are never "on" with an empty selection (the product has no such
204
+ * state; labels render only while the selection is non-empty).
205
+ * - `{ labels: [...] }` alone sets the selection **and turns labels on**.
206
+ * - `{ showLabels: false }` turns labels off and **clears the stored
207
+ * selection** — a later read returns `labels: []`.
208
+ * - `{ showLabels: false, labels: [...] }` with a non-empty list is
209
+ * contradictory and **rejected** (nothing is silently discarded).
210
+ * - `{ showLabels: true, labels: [] }` is likewise contradictory and
211
+ * **rejected** — pass a non-empty list, or omit `labels` to get the
212
+ * defaults.
213
+ *
214
+ * `colorMode` accepts the `tag:<categoryId>` scheme strings returned by
215
+ * {@linkcode PluginPresentationViewsApi.getSettings}, so read-then-write
216
+ * round-trips a tag-based color scheme unchanged.
217
+ *
218
+ * `viewMode` (`"perspective"` | `"isometric"`) applies to **3D views only** —
219
+ * a 2D plan is always orthographic, so a `viewMode: "perspective"` patch on a
220
+ * 2D view is rejected. `"isometric"` on a 2D plan is accepted as a no-op (the
221
+ * plan is already orthographic), so writing back exactly what
222
+ * {@linkcode PluginPresentationViewsApi.getSettings} returned is always a
223
+ * no-op. On the active view the camera switches projection live (the same
224
+ * toggle the view-settings modal runs); on other views the mode is applied
225
+ * the next time the view is activated.
226
+ *
227
+ * @param viewId - The id of the view to update.
228
+ * @param settings - A partial {@linkcode PluginPresentationViewSettings}; any
229
+ * omitted field is left unchanged.
230
+ * @returns The updated view's `id`.
231
+ * @throws If writes are disabled, no view has the given id, the patch is
232
+ * contradictory (`showLabels: false` with a non-empty `labels`, or
233
+ * `showLabels: true` with an explicitly empty `labels` list), or
234
+ * `viewMode: "perspective"` is patched on a 2D plan view.
235
+ *
236
+ * @examplePrompt Switch this view to monochrome color mode
237
+ * @examplePrompt Turn off the axis in the Ground Floor view
238
+ * @examplePrompt Set the background of the active view to white
239
+ * @examplePrompt Show area labels on this view
240
+ * @examplePrompt Enable hidden-line mode for the section view
241
+ * @examplePrompt Make the 3D view orthographic instead of perspective
242
+ *
243
+ * # Example
244
+ * ```ts
245
+ * await snaptrude.presentation.views.updateSettings("view_123", {
246
+ * colorMode: "monochrome",
247
+ * showAxis: false,
248
+ * })
249
+ * // switch a 3D view to an isometric (orthographic) projection
250
+ * await snaptrude.presentation.views.updateSettings("view_123", {
251
+ * viewMode: "isometric",
252
+ * })
253
+ * ```
254
+ */
255
+ public abstract updateSettings(
256
+ viewId: string,
257
+ settings: Partial<PluginPresentationViewSettings>,
258
+ ): PluginApiReturn<PluginPresentationViewsUpdateSettingsResult>
259
+
260
+ /**
261
+ * Rename a saved view.
262
+ *
263
+ * Sets the view's display name — the same label the views panel shows and
264
+ * that `list`/`get` read back. Names must be unique within the proposal and
265
+ * cannot contain the characters `\ : { } [ ] | ; < > ? ~`.
266
+ *
267
+ * @param viewId - The id of the view to rename.
268
+ * @param name - The new display name (non-empty after trimming).
269
+ * @returns The updated {@linkcode PluginPresentationView}.
270
+ * @throws If writes are disabled, no view has the given id, the name is
271
+ * empty/invalid, or another view in the proposal already has that name.
272
+ *
273
+ * @examplePrompt Rename the view Lobby to Entrance Lobby
274
+ * @examplePrompt Call this view Ground Floor Plan
275
+ * @examplePrompt Change the active view's name to Final
276
+ *
277
+ * # Example
278
+ * ```ts
279
+ * const view = await snaptrude.presentation.views.rename("view_123", "Entrance")
280
+ * ```
281
+ */
282
+ public abstract rename(
283
+ viewId: string,
284
+ name: string,
285
+ ): PluginApiReturn<PluginPresentationViewsRenameResult>
286
+
287
+ /**
288
+ * Delete a saved view.
289
+ *
290
+ * Removes the view from the project and the views panel (the panel's own
291
+ * delete action). If the deleted view was active, the product falls back to
292
+ * the default plan/3D view. Default views (the built-in plan/3D/site-plan
293
+ * entries) cannot be deleted.
294
+ *
295
+ * @param viewId - The id of the view to delete.
296
+ * @returns The id of the deleted view
297
+ * (a {@linkcode PluginPresentationViewsDeleteResult}).
298
+ * @throws If writes are disabled, no view has the given id, or the view is a
299
+ * default view.
300
+ *
301
+ * @examplePrompt Delete the view named Old Draft
302
+ * @examplePrompt Remove this saved view
303
+ * @examplePrompt Get rid of the Lobby camera bookmark
304
+ *
305
+ * # Example
306
+ * ```ts
307
+ * const { id } = await snaptrude.presentation.views.delete("view_123")
308
+ * ```
309
+ */
310
+ public abstract delete(
311
+ viewId: string,
312
+ ): PluginApiReturn<PluginPresentationViewsDeleteResult>
156
313
  }
157
314
 
158
315
  /**
@@ -172,12 +329,14 @@ export type PluginPresentationViewType = z.infer<
172
329
  * | `name` | `string` | Display name |
173
330
  * | `type` | `"2d" \| "3d"` | Whether this is a 2D plan view or a 3D view |
174
331
  * | `isActive` | `boolean` | Whether this view is the currently active view |
332
+ * | `storey` | `number \| null` | The storey this view was saved on (`null` on older views saved without one) |
175
333
  */
176
334
  export const PluginPresentationView = z.object({
177
335
  id: z.string(),
178
336
  name: z.string(),
179
337
  type: PluginPresentationViewType,
180
338
  isActive: z.boolean(),
339
+ storey: z.number().nullable(),
181
340
  })
182
341
  export type PluginPresentationView = z.infer<typeof PluginPresentationView>
183
342
 
@@ -287,10 +446,12 @@ export type PluginPresentationViewsSetActiveResult = z.infer<
287
446
  * |---|---|---|
288
447
  * | `name` | `string \| undefined` | Name for the new view (a default is used when omitted) |
289
448
  * | `kind` | `"view" \| "sitePlan" \| undefined` | What kind of view to save (default `"view"`). `"plan"` is not offered — the host cannot create a plan view without a `planId` this API does not carry. |
449
+ * | `storey` | `number \| undefined` | Save the view on this storey (activated before capture); defaults to the current active storey |
290
450
  */
291
451
  export const PluginPresentationViewsCreateArgs = z.object({
292
452
  name: z.string().optional(),
293
453
  kind: z.enum(["view", "sitePlan"]).optional(),
454
+ storey: z.number().optional(),
294
455
  })
295
456
  export type PluginPresentationViewsCreateArgs = z.infer<
296
457
  typeof PluginPresentationViewsCreateArgs
@@ -301,3 +462,210 @@ export const PluginPresentationViewsCreateResult = PluginPresentationView
301
462
  export type PluginPresentationViewsCreateResult = z.infer<
302
463
  typeof PluginPresentationViewsCreateResult
303
464
  >
465
+
466
+ /**
467
+ * How the scene is colored in a view.
468
+ *
469
+ * | Value | Meaning |
470
+ * |---|---|
471
+ * | `monochrome` | Flat single-tone shading |
472
+ * | `texture` | Material textures/colors |
473
+ * | `department` | Colored by department |
474
+ * | `tag:<categoryId>` | Colored by a project tag category (e.g. `tag:ZONE`) |
475
+ *
476
+ * The `tag:<categoryId>` form carries the product's tag-based color schemes
477
+ * losslessly — reading a view that uses one returns the `tag:` string as-is,
478
+ * and writing it back preserves the scheme (read-then-write is safe).
479
+ */
480
+ export const PluginPresentationViewColorMode = z.union([
481
+ z.enum(["monochrome", "texture", "department"]),
482
+ z.templateLiteral(["tag:", z.string()]),
483
+ ])
484
+ export type PluginPresentationViewColorMode = z.infer<
485
+ typeof PluginPresentationViewColorMode
486
+ >
487
+
488
+ /**
489
+ * A category of on-canvas labels a view can show.
490
+ *
491
+ * | Value | Meaning |
492
+ * |---|---|
493
+ * | `objectLabels` | Per-object name labels |
494
+ * | `areas` | Area/room labels |
495
+ * | `department` | Department labels |
496
+ */
497
+ export const PluginPresentationViewLabel = z.enum([
498
+ "objectLabels",
499
+ "areas",
500
+ "department",
501
+ ])
502
+ export type PluginPresentationViewLabel = z.infer<
503
+ typeof PluginPresentationViewLabel
504
+ >
505
+
506
+ /**
507
+ * A view's camera projection: perspective, or isometric (orthographic).
508
+ *
509
+ * | Value | Meaning |
510
+ * |---|---|
511
+ * | `perspective` | Perspective projection (vanishing points) |
512
+ * | `isometric` | Orthographic projection (no perspective distortion) |
513
+ *
514
+ * Applies to 3D views; a 2D plan view is always orthographic and reads
515
+ * `"isometric"`.
516
+ */
517
+ export const PluginPresentationViewMode = z.enum(["perspective", "isometric"])
518
+ export type PluginPresentationViewMode = z.infer<
519
+ typeof PluginPresentationViewMode
520
+ >
521
+
522
+ /**
523
+ * A view's display settings.
524
+ *
525
+ * | Property | Type | Description |
526
+ * |---|---|---|
527
+ * | `backgroundColor` | `string` | Canvas background as a hex color (e.g. `#ffffff`) |
528
+ * | `colorMode` | {@linkcode PluginPresentationViewColorMode} | How the scene is colored (including `tag:<categoryId>` schemes) |
529
+ * | `viewMode` | {@linkcode PluginPresentationViewMode} | Camera projection — `"perspective"` or `"isometric"` (orthographic). Writable on 3D views only; a 2D plan always reads `"isometric"` and accepts only `"isometric"` (a no-op) |
530
+ * | `showAxis` | `boolean` | Whether the X/Y/Z axes are shown |
531
+ * | `showEdges` | `boolean` | Whether edges are shown; `false` = hidden-line rendering |
532
+ * | `showLabels` | `boolean` | Master label switch — whether on-canvas labels are shown at all. `true` always pairs with a non-empty `labels` selection (labels render only while the selection is non-empty; there is no labels-on-with-empty-selection state) |
533
+ * | `labels` | {@linkcode PluginPresentationViewLabel}`[]` | Which label categories are selected. When `showLabels` is `false` the view stores no selection and this reads `[]` |
534
+ */
535
+ export const PluginPresentationViewSettings = z.object({
536
+ backgroundColor: z.string(),
537
+ colorMode: PluginPresentationViewColorMode,
538
+ viewMode: PluginPresentationViewMode,
539
+ showAxis: z.boolean(),
540
+ showEdges: z.boolean(),
541
+ showLabels: z.boolean(),
542
+ labels: z.array(PluginPresentationViewLabel),
543
+ })
544
+ export type PluginPresentationViewSettings = z.infer<
545
+ typeof PluginPresentationViewSettings
546
+ >
547
+
548
+ /**
549
+ * Arguments for {@linkcode PluginPresentationViewsApi.getSettings}.
550
+ *
551
+ * | Property | Type | Description |
552
+ * |---|---|---|
553
+ * | `id` | `string` | The id of the view to read settings for |
554
+ */
555
+ export const PluginPresentationViewsGetSettingsArgs = z.object({
556
+ id: z.string(),
557
+ })
558
+ export type PluginPresentationViewsGetSettingsArgs = z.infer<
559
+ typeof PluginPresentationViewsGetSettingsArgs
560
+ >
561
+
562
+ /**
563
+ * Result of {@linkcode PluginPresentationViewsApi.getSettings} — the settings,
564
+ * or `null` when no view has that id.
565
+ */
566
+ export const PluginPresentationViewsGetSettingsResult =
567
+ PluginPresentationViewSettings.nullable()
568
+ export type PluginPresentationViewsGetSettingsResult = z.infer<
569
+ typeof PluginPresentationViewsGetSettingsResult
570
+ >
571
+
572
+ /**
573
+ * Arguments for {@linkcode PluginPresentationViewsApi.updateSettings}. The
574
+ * `settings` patch is partial — any omitted field is left unchanged. A patch
575
+ * pairing `showLabels: false` with a non-empty `labels` list, or
576
+ * `showLabels: true` with an explicitly empty `labels` list, is rejected as
577
+ * contradictory (see the method JSDoc for the full label patch semantics).
578
+ *
579
+ * | Property | Type | Description |
580
+ * |---|---|---|
581
+ * | `id` | `string` | The id of the view to update |
582
+ * | `settings` | `Partial<`{@linkcode PluginPresentationViewSettings}`>` | The fields to change |
583
+ */
584
+ export const PluginPresentationViewsUpdateSettingsArgs = z
585
+ .object({
586
+ id: z.string(),
587
+ settings: PluginPresentationViewSettings.partial(),
588
+ })
589
+ .refine(
590
+ (v) =>
591
+ !(
592
+ v.settings.showLabels === false && (v.settings.labels?.length ?? 0) > 0
593
+ ),
594
+ {
595
+ message:
596
+ "Contradictory patch: labels cannot be set while showLabels is false",
597
+ },
598
+ )
599
+ .refine(
600
+ (v) =>
601
+ !(
602
+ v.settings.showLabels === true &&
603
+ v.settings.labels !== undefined &&
604
+ v.settings.labels.length === 0
605
+ ),
606
+ {
607
+ message:
608
+ "Contradictory patch: showLabels cannot be true with an explicitly empty labels list — pass a non-empty list, or omit labels to apply the defaults",
609
+ },
610
+ )
611
+ export type PluginPresentationViewsUpdateSettingsArgs = z.infer<
612
+ typeof PluginPresentationViewsUpdateSettingsArgs
613
+ >
614
+
615
+ /** Result of {@linkcode PluginPresentationViewsApi.updateSettings} — the updated view's id. */
616
+ export const PluginPresentationViewsUpdateSettingsResult = z.object({
617
+ id: z.string(),
618
+ })
619
+ export type PluginPresentationViewsUpdateSettingsResult = z.infer<
620
+ typeof PluginPresentationViewsUpdateSettingsResult
621
+ >
622
+
623
+ /**
624
+ * Arguments for {@linkcode PluginPresentationViewsApi.rename}.
625
+ *
626
+ * | Property | Type | Description |
627
+ * |---|---|---|
628
+ * | `id` | `string` | The id of the view to rename |
629
+ * | `name` | `string` | New display name (non-empty after trimming) |
630
+ */
631
+ export const PluginPresentationViewsRenameArgs = z.object({
632
+ id: z.string(),
633
+ name: z.string().trim().min(1),
634
+ })
635
+ export type PluginPresentationViewsRenameArgs = z.infer<
636
+ typeof PluginPresentationViewsRenameArgs
637
+ >
638
+
639
+ /** Result of {@linkcode PluginPresentationViewsApi.rename} — the renamed view. */
640
+ export const PluginPresentationViewsRenameResult = PluginPresentationView
641
+ export type PluginPresentationViewsRenameResult = z.infer<
642
+ typeof PluginPresentationViewsRenameResult
643
+ >
644
+
645
+ /**
646
+ * Arguments for {@linkcode PluginPresentationViewsApi.delete}.
647
+ *
648
+ * | Property | Type | Description |
649
+ * |---|---|---|
650
+ * | `id` | `string` | The id of the view to delete |
651
+ */
652
+ export const PluginPresentationViewsDeleteArgs = z.object({
653
+ id: z.string(),
654
+ })
655
+ export type PluginPresentationViewsDeleteArgs = z.infer<
656
+ typeof PluginPresentationViewsDeleteArgs
657
+ >
658
+
659
+ /**
660
+ * Result of {@linkcode PluginPresentationViewsApi.delete}.
661
+ *
662
+ * | Property | Type | Description |
663
+ * |---|---|---|
664
+ * | `id` | `string` | Id of the deleted view |
665
+ */
666
+ export const PluginPresentationViewsDeleteResult = z.object({
667
+ id: z.string(),
668
+ })
669
+ export type PluginPresentationViewsDeleteResult = z.infer<
670
+ typeof PluginPresentationViewsDeleteResult
671
+ >