@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,521 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import { ComponentHandle, Vec3Components } from "../../handles"
4
+
5
+ /**
6
+ * Groups — read and edit the group hierarchy of the active project.
7
+ *
8
+ * A **group** is a named, lockable container that bundles components (and other
9
+ * groups) so they can be selected and transformed as one. This is the
10
+ * plugin-facing view of that hierarchy: a group's identity, name, member count,
11
+ * lock state, and parent — never the underlying meshes.
12
+ *
13
+ * Reads return plain records and never throw for a missing group (`get` returns
14
+ * `null`, `list` returns `[]`, `isLocked` returns `false`). Ids are stable public
15
+ * strings, never engine mesh handles.
16
+ *
17
+ * Members are moved and copied through the design operations by group id — use
18
+ * {@linkcode PluginDesignApi.transform}`.move` and `design.create.copy`, not a method here.
19
+ * Locking likewise routes through `design.lock`.
20
+ *
21
+ * Sub-namespace members typed as optional (`?`) are **authored ahead of the
22
+ * host** — declared so plugins and codegen can see the shape, but kept out of the
23
+ * discovery manifest until the host lands them (at which point they are promoted
24
+ * to required `abstract` members).
25
+ *
26
+ * Accessed via `snaptrude.core.groups`.
27
+ */
28
+ export abstract class PluginCoreGroupsApi {
29
+ constructor() {}
30
+
31
+ /**
32
+ * List every group in the active project.
33
+ *
34
+ * Returns each group's identity, member count, lock state, and parent group
35
+ * (when nested), for the whole project.
36
+ *
37
+ * @returns A {@linkcode PluginCoreGroupsListResult} with a `groups` array
38
+ * (empty when the project has none).
39
+ *
40
+ * @examplePrompt List all the groups in my project
41
+ * @examplePrompt What groups do I have and how many things are in each?
42
+ * @examplePrompt Show every group with its lock state
43
+ * @examplePrompt How many groups are in this model?
44
+ *
45
+ * # Example
46
+ * ```ts
47
+ * const { groups } = await snaptrude.core.groups.list()
48
+ * for (const g of groups) console.log(g.name, g.memberCount, g.isLocked)
49
+ * ```
50
+ */
51
+ public abstract list(): PluginApiReturn<PluginCoreGroupsListResult>
52
+
53
+ /**
54
+ * Get a single group by id.
55
+ *
56
+ * @param groupId - The id of the group to read.
57
+ * @returns The matching {@linkcode PluginCoreGroupRef}, or `null` if no group
58
+ * has that id.
59
+ *
60
+ * @examplePrompt Get the group with id group-12
61
+ * @examplePrompt Look up a single group by its id
62
+ * @examplePrompt Is group-3 locked and how many members does it have?
63
+ *
64
+ * # Example
65
+ * ```ts
66
+ * const group = await snaptrude.core.groups.get("group-12")
67
+ * if (group) console.log(group.name, group.memberCount)
68
+ * ```
69
+ */
70
+ public abstract get(
71
+ groupId: string,
72
+ ): PluginApiReturn<PluginCoreGroupsGetResult>
73
+
74
+ /**
75
+ * Get the group a component belongs to.
76
+ *
77
+ * Returns the **innermost** group directly containing the component, or `null`
78
+ * if the component is ungrouped or does not exist.
79
+ *
80
+ * @param componentId - The `Component.id` of the component to look up.
81
+ * @returns The innermost {@linkcode PluginCoreGroupRef} containing the
82
+ * component, or `null`.
83
+ *
84
+ * @examplePrompt Which group is this wall in?
85
+ * @examplePrompt Find the group that contains component cmp_42
86
+ * @examplePrompt Is this element grouped, and if so which group?
87
+ *
88
+ * # Example
89
+ * ```ts
90
+ * const group = await snaptrude.core.groups.getForComponent("cmp_42")
91
+ * console.log(group ? group.name : "ungrouped")
92
+ * ```
93
+ */
94
+ public abstract getForComponent(
95
+ componentId: ComponentHandle,
96
+ ): PluginApiReturn<PluginCoreGroupsGetForComponentResult>
97
+
98
+ /**
99
+ * List the direct members of a group.
100
+ *
101
+ * Returns each direct child as an id + kind (`component` or a nested `group`).
102
+ * Nested groups are returned as members, not flattened.
103
+ *
104
+ * @param groupId - The id of the group whose members to read.
105
+ * @returns A {@linkcode PluginCoreGroupsListMembersResult} with a `members`
106
+ * array (empty when the group is empty or missing).
107
+ *
108
+ * @examplePrompt What's inside group-12?
109
+ * @examplePrompt List the members of this group
110
+ * @examplePrompt Show the components and subgroups in group-3
111
+ *
112
+ * # Example
113
+ * ```ts
114
+ * const { members } = await snaptrude.core.groups.listMembers("group-12")
115
+ * for (const m of members) console.log(m.type, m.id)
116
+ * ```
117
+ */
118
+ public abstract listMembers(
119
+ groupId: string,
120
+ ): PluginApiReturn<PluginCoreGroupsListMembersResult>
121
+
122
+ /**
123
+ * Report whether a group is locked.
124
+ *
125
+ * A predicate: it never mutates and never throws — an unknown group id returns
126
+ * `false`.
127
+ *
128
+ * @param groupId - The id of the group to test.
129
+ * @returns `true` if the group exists and is locked, otherwise `false`.
130
+ *
131
+ * @examplePrompt Is group-12 locked?
132
+ * @examplePrompt Check whether this group is locked before editing it
133
+ * @examplePrompt Tell me if the group is locked
134
+ *
135
+ * # Example
136
+ * ```ts
137
+ * if (await snaptrude.core.groups.isLocked("group-12")) {
138
+ * console.log("locked — unlock it first")
139
+ * }
140
+ * ```
141
+ */
142
+ public abstract isLocked(
143
+ groupId: string,
144
+ ): PluginApiReturn<PluginCoreGroupsIsLockedResult>
145
+
146
+ /**
147
+ * Get the axis-aligned bounds of a group.
148
+ *
149
+ * Returns the world-space bounding box of everything in the group — its `min`
150
+ * and `max` corners and the `center` — in internal units, or `null` when the
151
+ * group is empty (has no meshes) or does not exist. `null` is distinct from a
152
+ * real group at the origin, whose box is centered on `{0,0,0}`.
153
+ *
154
+ * @param groupId - The id of the group to measure.
155
+ * @returns A {@linkcode PluginCoreGroupsGetBoundsResult} with `min`, `max`, and
156
+ * `center` points, or `null` if the group is empty or gone.
157
+ *
158
+ * @examplePrompt How big is this group?
159
+ * @examplePrompt Get the bounding box of group-12
160
+ * @examplePrompt Where is the center of this group?
161
+ *
162
+ * # Example
163
+ * ```ts
164
+ * const bounds = await snaptrude.core.groups.getBounds("group-12")
165
+ * if (bounds) console.log(bounds.center.x, bounds.center.y, bounds.center.z)
166
+ * ```
167
+ */
168
+ public abstract getBounds(
169
+ groupId: string,
170
+ ): PluginApiReturn<PluginCoreGroupsGetBoundsResult>
171
+
172
+ /**
173
+ * Group components into a new group.
174
+ *
175
+ * Bundles the given components under a new group. Pass a `name` to label it;
176
+ * otherwise it gets an auto-generated fallback name that you can change later
177
+ * with {@linkcode PluginCoreGroupsApi.update}.
178
+ *
179
+ * @param componentIds - The ids of the components to group (at least one).
180
+ * @param name - Display name for the new group (auto-generated if omitted).
181
+ * @returns The new group's id (read the full record back with
182
+ * {@linkcode PluginCoreGroupsApi.get}).
183
+ * @throws If a component id is invalid or the group could not be created.
184
+ *
185
+ * @examplePrompt Group the selected components
186
+ * @examplePrompt Make a group called Kitchen from these elements
187
+ * @examplePrompt Bundle components cmp_1 and cmp_2 into a group
188
+ *
189
+ * # Example
190
+ * ```ts
191
+ * const { groupId } = await snaptrude.core.groups.create(["cmp_1", "cmp_2"], "Kitchen")
192
+ * ```
193
+ */
194
+ public abstract create(
195
+ componentIds: ComponentHandle[],
196
+ name?: string,
197
+ ): PluginApiReturn<PluginCoreGroupsCreateResult>
198
+
199
+ /**
200
+ * Update a group's name and/or membership.
201
+ *
202
+ * A **sparse** update: omitted fields are left unchanged. `addComponentIds`
203
+ * and `removeComponentIds` are applied as membership deltas (add before
204
+ * remove); `name` renames the group.
205
+ *
206
+ * @param groupId - The id of the group to update.
207
+ * @param options - Any of `name`, `addComponentIds`, `removeComponentIds`;
208
+ * omitted fields are left unchanged.
209
+ * @returns The updated {@linkcode PluginCoreGroupRef}.
210
+ * @throws If no group has the given id, or a component id is invalid.
211
+ *
212
+ * @examplePrompt Rename group-12 to Kitchen
213
+ * @examplePrompt Add these two walls to the group
214
+ * @examplePrompt Remove cmp_7 from group-3
215
+ *
216
+ * # Example
217
+ * ```ts
218
+ * const group = await snaptrude.core.groups.update("group-12", {
219
+ * name: "Kitchen",
220
+ * addComponentIds: ["cmp_9"],
221
+ * })
222
+ * ```
223
+ */
224
+ public abstract update(
225
+ groupId: string,
226
+ options?: {
227
+ name?: string
228
+ addComponentIds?: ComponentHandle[]
229
+ removeComponentIds?: ComponentHandle[]
230
+ },
231
+ ): PluginApiReturn<PluginCoreGroupsUpdateResult>
232
+
233
+ /**
234
+ * Delete (dissolve) a group.
235
+ *
236
+ * Dissolves the group container. The member elements are **not** deleted —
237
+ * they are returned to the group's parent (or ungrouped at the top level).
238
+ *
239
+ * @param groupId - The id of the group to dissolve.
240
+ * @returns Confirmation that the group was dissolved.
241
+ * @throws If no group has the given id.
242
+ *
243
+ * @examplePrompt Ungroup group-12
244
+ * @examplePrompt Dissolve this group but keep its contents
245
+ * @examplePrompt Delete the group without deleting its members
246
+ *
247
+ * # Example
248
+ * ```ts
249
+ * await snaptrude.core.groups.delete("group-12")
250
+ * ```
251
+ */
252
+ public abstract delete(
253
+ groupId: string,
254
+ ): PluginApiReturn<PluginCoreGroupsDeleteResult>
255
+ }
256
+
257
+ /**
258
+ * A group in the active project.
259
+ *
260
+ * | Property | Type | Description |
261
+ * |---|---|---|
262
+ * | `id` | `string` | Stable public group id (e.g. `"group-12"`) — never a mesh handle |
263
+ * | `name` | `string` | Display name (auto-generated fallback until the user sets one) |
264
+ * | `memberCount` | `number` | Number of direct members (components + nested groups) |
265
+ * | `isLocked` | `boolean` | Whether the group is locked against edits |
266
+ * | `parentId` | `string \| undefined` | Parent group id when this group is nested, else absent |
267
+ */
268
+ export const PluginCoreGroupRef = z.object({
269
+ id: z.string(),
270
+ name: z.string(),
271
+ memberCount: z.number().int(),
272
+ isLocked: z.boolean(),
273
+ parentId: z.string().optional(),
274
+ })
275
+ export type PluginCoreGroupRef = z.infer<typeof PluginCoreGroupRef>
276
+
277
+ /**
278
+ * A direct member of a group.
279
+ *
280
+ * | Property | Type | Description |
281
+ * |---|---|---|
282
+ * | `id` | `string` | `Component.id` for a component member, or the group id for a nested group |
283
+ * | `type` | `"component" \| "group"` | Whether this member is a component or a nested group |
284
+ */
285
+ export const PluginCoreGroupMember = z.object({
286
+ id: z.string(),
287
+ type: z.enum(["component", "group"]),
288
+ })
289
+ export type PluginCoreGroupMember = z.infer<typeof PluginCoreGroupMember>
290
+
291
+ /**
292
+ * Result of {@linkcode PluginCoreGroupsApi.list}.
293
+ *
294
+ * | Property | Type | Description |
295
+ * |---|---|---|
296
+ * | `groups` | {@linkcode PluginCoreGroupRef}`[]` | Every group in the active project |
297
+ */
298
+ export const PluginCoreGroupsListResult = z.object({
299
+ groups: z.array(PluginCoreGroupRef),
300
+ })
301
+ export type PluginCoreGroupsListResult = z.infer<
302
+ typeof PluginCoreGroupsListResult
303
+ >
304
+
305
+ /**
306
+ * Arguments for {@linkcode PluginCoreGroupsApi.get}.
307
+ *
308
+ * | Property | Type | Description |
309
+ * |---|---|---|
310
+ * | `groupId` | `string` | The id of the group to read |
311
+ */
312
+ export const PluginCoreGroupsGetArgs = z.object({
313
+ groupId: z.string(),
314
+ })
315
+ export type PluginCoreGroupsGetArgs = z.infer<typeof PluginCoreGroupsGetArgs>
316
+
317
+ /**
318
+ * Result of {@linkcode PluginCoreGroupsApi.get} — the group, or `null` when no
319
+ * group has the given id.
320
+ */
321
+ export const PluginCoreGroupsGetResult = PluginCoreGroupRef.nullable()
322
+ export type PluginCoreGroupsGetResult = z.infer<
323
+ typeof PluginCoreGroupsGetResult
324
+ >
325
+
326
+ /**
327
+ * Arguments for {@linkcode PluginCoreGroupsApi.getForComponent}.
328
+ *
329
+ * | Property | Type | Description |
330
+ * |---|---|---|
331
+ * | `componentId` | `ComponentHandle` | The `Component.id` to look up |
332
+ */
333
+ export const PluginCoreGroupsGetForComponentArgs = z.object({
334
+ componentId: ComponentHandle,
335
+ })
336
+ export type PluginCoreGroupsGetForComponentArgs = z.infer<
337
+ typeof PluginCoreGroupsGetForComponentArgs
338
+ >
339
+
340
+ /**
341
+ * Result of {@linkcode PluginCoreGroupsApi.getForComponent} — the innermost
342
+ * group containing the component, or `null`.
343
+ */
344
+ export const PluginCoreGroupsGetForComponentResult =
345
+ PluginCoreGroupRef.nullable()
346
+ export type PluginCoreGroupsGetForComponentResult = z.infer<
347
+ typeof PluginCoreGroupsGetForComponentResult
348
+ >
349
+
350
+ /**
351
+ * Arguments for {@linkcode PluginCoreGroupsApi.listMembers}.
352
+ *
353
+ * | Property | Type | Description |
354
+ * |---|---|---|
355
+ * | `groupId` | `string` | The id of the group whose members to read |
356
+ */
357
+ export const PluginCoreGroupsListMembersArgs = z.object({
358
+ groupId: z.string(),
359
+ })
360
+ export type PluginCoreGroupsListMembersArgs = z.infer<
361
+ typeof PluginCoreGroupsListMembersArgs
362
+ >
363
+
364
+ /**
365
+ * Result of {@linkcode PluginCoreGroupsApi.listMembers}.
366
+ *
367
+ * | Property | Type | Description |
368
+ * |---|---|---|
369
+ * | `members` | {@linkcode PluginCoreGroupMember}`[]` | The group's direct members (empty when the group is empty or missing) |
370
+ */
371
+ export const PluginCoreGroupsListMembersResult = z.object({
372
+ members: z.array(PluginCoreGroupMember),
373
+ })
374
+ export type PluginCoreGroupsListMembersResult = z.infer<
375
+ typeof PluginCoreGroupsListMembersResult
376
+ >
377
+
378
+ /**
379
+ * Arguments for {@linkcode PluginCoreGroupsApi.isLocked}.
380
+ *
381
+ * | Property | Type | Description |
382
+ * |---|---|---|
383
+ * | `groupId` | `string` | The id of the group to test |
384
+ */
385
+ export const PluginCoreGroupsIsLockedArgs = z.object({
386
+ groupId: z.string(),
387
+ })
388
+ export type PluginCoreGroupsIsLockedArgs = z.infer<
389
+ typeof PluginCoreGroupsIsLockedArgs
390
+ >
391
+
392
+ /**
393
+ * Result of {@linkcode PluginCoreGroupsApi.isLocked} — `true` when the group
394
+ * exists and is locked, else `false`.
395
+ */
396
+ export const PluginCoreGroupsIsLockedResult = z.boolean()
397
+ export type PluginCoreGroupsIsLockedResult = z.infer<
398
+ typeof PluginCoreGroupsIsLockedResult
399
+ >
400
+
401
+ /**
402
+ * Arguments for {@linkcode PluginCoreGroupsApi.getBounds}.
403
+ *
404
+ * | Property | Type | Description |
405
+ * |---|---|---|
406
+ * | `groupId` | `string` | The id of the group to measure |
407
+ */
408
+ export const PluginCoreGroupsGetBoundsArgs = z.object({
409
+ groupId: z.string(),
410
+ })
411
+ export type PluginCoreGroupsGetBoundsArgs = z.infer<
412
+ typeof PluginCoreGroupsGetBoundsArgs
413
+ >
414
+
415
+ /**
416
+ * Result of {@linkcode PluginCoreGroupsApi.getBounds} — the group's world-space
417
+ * axis-aligned bounds in internal units, or `null` when the group is empty (has
418
+ * no meshes) or does not exist.
419
+ *
420
+ * | Property | Type | Description |
421
+ * |---|---|---|
422
+ * | `min` | {@linkcode Vec3Components} | The minimum corner (`x`, `y`, `z`) |
423
+ * | `max` | {@linkcode Vec3Components} | The maximum corner (`x`, `y`, `z`) |
424
+ * | `center` | {@linkcode Vec3Components} | The box center (`x`, `y`, `z`) |
425
+ */
426
+ export const PluginCoreGroupsGetBoundsResult = z
427
+ .object({
428
+ min: Vec3Components,
429
+ max: Vec3Components,
430
+ center: Vec3Components,
431
+ })
432
+ .nullable()
433
+ export type PluginCoreGroupsGetBoundsResult = z.infer<
434
+ typeof PluginCoreGroupsGetBoundsResult
435
+ >
436
+
437
+ /**
438
+ * Arguments for {@linkcode PluginCoreGroupsApi.create}.
439
+ *
440
+ * | Property | Type | Description |
441
+ * |---|---|---|
442
+ * | `componentIds` | `ComponentHandle[]` | The ids of the components to group (at least one) |
443
+ * | `name` | `string \| undefined` | Display name for the new group (auto-generated if omitted) |
444
+ */
445
+ export const PluginCoreGroupsCreateArgs = z.object({
446
+ componentIds: z.array(ComponentHandle).min(1),
447
+ name: z.string().optional(),
448
+ })
449
+ export type PluginCoreGroupsCreateArgs = z.infer<
450
+ typeof PluginCoreGroupsCreateArgs
451
+ >
452
+
453
+ /**
454
+ * Result of {@linkcode PluginCoreGroupsApi.create} — the id of the new group.
455
+ *
456
+ * | Property | Type | Description |
457
+ * |---|---|---|
458
+ * | `groupId` | `string` | The id of the newly created group |
459
+ */
460
+ export const PluginCoreGroupsCreateResult = z.object({
461
+ groupId: z.string(),
462
+ })
463
+ export type PluginCoreGroupsCreateResult = z.infer<
464
+ typeof PluginCoreGroupsCreateResult
465
+ >
466
+
467
+ /**
468
+ * Arguments for {@linkcode PluginCoreGroupsApi.update}. Sparse — only the
469
+ * provided fields are changed.
470
+ *
471
+ * | Property | Type | Description |
472
+ * |---|---|---|
473
+ * | `groupId` | `string` | The id of the group to update |
474
+ * | `name` | `string \| undefined` | New display name (unchanged if omitted) |
475
+ * | `addComponentIds` | `ComponentHandle[] \| undefined` | Components to add to the group |
476
+ * | `removeComponentIds` | `ComponentHandle[] \| undefined` | Components to remove from the group |
477
+ */
478
+ export const PluginCoreGroupsUpdateArgs = z.object({
479
+ groupId: z.string(),
480
+ name: z.string().optional(),
481
+ addComponentIds: z.array(ComponentHandle).optional(),
482
+ removeComponentIds: z.array(ComponentHandle).optional(),
483
+ })
484
+ export type PluginCoreGroupsUpdateArgs = z.infer<
485
+ typeof PluginCoreGroupsUpdateArgs
486
+ >
487
+
488
+ /** Result of {@linkcode PluginCoreGroupsApi.update} — the updated group record. */
489
+ export const PluginCoreGroupsUpdateResult = PluginCoreGroupRef
490
+ export type PluginCoreGroupsUpdateResult = z.infer<
491
+ typeof PluginCoreGroupsUpdateResult
492
+ >
493
+
494
+ /**
495
+ * Arguments for {@linkcode PluginCoreGroupsApi.delete}.
496
+ *
497
+ * | Property | Type | Description |
498
+ * |---|---|---|
499
+ * | `groupId` | `string` | The id of the group to dissolve |
500
+ */
501
+ export const PluginCoreGroupsDeleteArgs = z.object({
502
+ groupId: z.string(),
503
+ })
504
+ export type PluginCoreGroupsDeleteArgs = z.infer<
505
+ typeof PluginCoreGroupsDeleteArgs
506
+ >
507
+
508
+ /**
509
+ * Result of {@linkcode PluginCoreGroupsApi.delete} — confirmation that the group
510
+ * was dissolved (its members are preserved).
511
+ *
512
+ * | Property | Type | Description |
513
+ * |---|---|---|
514
+ * | `deleted` | `true` | Always `true` on success |
515
+ */
516
+ export const PluginCoreGroupsDeleteResult = z.object({
517
+ deleted: z.literal(true),
518
+ })
519
+ export type PluginCoreGroupsDeleteResult = z.infer<
520
+ typeof PluginCoreGroupsDeleteResult
521
+ >
@@ -0,0 +1,84 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../../types"
3
+
4
+ /**
5
+ * Undo / redo of committed history entries.
6
+ *
7
+ * History steps operate on Snaptrude's command stack: {@linkcode PluginHistoryApi.undo}
8
+ * steps back over committed entries, {@linkcode PluginHistoryApi.redo} re-applies
9
+ * undone ones. Both take an optional step count (default 1) and report how many
10
+ * steps were actually applied — fewer than requested when the stack runs out.
11
+ *
12
+ * Accessed via `snaptrude.core.history`.
13
+ */
14
+ export abstract class PluginHistoryApi {
15
+ constructor() {}
16
+
17
+ /**
18
+ * Step back over committed history entries.
19
+ *
20
+ * @param steps - (Optional) The number of entries to undo (default 1).
21
+ * @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
22
+ * entries actually undone (≤ `steps`; fewer if the undo stack ran out).
23
+ *
24
+ * @examplePrompt Undo my last change
25
+ * @examplePrompt Undo the last 3 actions
26
+ * @examplePrompt Revert what I just did to the model
27
+ * @examplePrompt Step back one change
28
+ * @examplePrompt Take back that last edit
29
+ *
30
+ * # Example
31
+ * ```ts
32
+ * await snaptrude.core.history.undo() // one step
33
+ * await snaptrude.core.history.undo(3) // up to three steps
34
+ * ```
35
+ */
36
+ public abstract undo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
37
+
38
+ /**
39
+ * Step forward over previously undone entries. Symmetric with
40
+ * {@linkcode PluginHistoryApi.undo}.
41
+ *
42
+ * @param steps - (Optional) The number of entries to redo (default 1).
43
+ * @returns A {@linkcode PluginHistoryStepResult} with `stepsApplied` — the
44
+ * entries actually redone (≤ `steps`; fewer if the redo stack ran out).
45
+ *
46
+ * @examplePrompt Redo the change I just undid
47
+ * @examplePrompt Redo the last two undone actions
48
+ * @examplePrompt Bring back the edit I reverted
49
+ * @examplePrompt Step forward again in the history
50
+ *
51
+ * # Example
52
+ * ```ts
53
+ * await snaptrude.core.history.redo()
54
+ * await snaptrude.core.history.redo(2)
55
+ * ```
56
+ */
57
+ public abstract redo(steps?: number): PluginApiReturn<PluginHistoryStepResult>
58
+ }
59
+
60
+ /**
61
+ * Arguments for {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
62
+ *
63
+ * | Property | Type | Description |
64
+ * |---|---|---|
65
+ * | `steps` | `number?` | Number of history entries to step (positive integer). Defaults to 1. |
66
+ */
67
+ export const PluginHistoryStepArgs = z.object({
68
+ steps: z.number().int().positive().optional(),
69
+ })
70
+
71
+ export type PluginHistoryStepArgs = z.infer<typeof PluginHistoryStepArgs>
72
+
73
+ /**
74
+ * Result of {@linkcode PluginHistoryApi.undo} / {@linkcode PluginHistoryApi.redo}.
75
+ *
76
+ * | Property | Type | Description |
77
+ * |---|---|---|
78
+ * | `stepsApplied` | `number` | History entries actually stepped — `≤ steps`, fewer when the stack ran out. |
79
+ */
80
+ export const PluginHistoryStepResult = z.object({
81
+ stepsApplied: z.number().int().nonnegative(),
82
+ })
83
+
84
+ export type PluginHistoryStepResult = z.infer<typeof PluginHistoryStepResult>
@@ -1,20 +1,65 @@
1
1
  import { PluginMathApi } from "./math"
2
2
  import { PluginGeomApi } from "./geom"
3
+ import { PluginHistoryApi } from "./history"
4
+ import { PluginUnitsApi } from "./units"
5
+ import { PluginZoomApi } from "./zoom"
6
+ import { PluginProjectApi } from "./project"
7
+ import { PluginCommentApi } from "./comment"
8
+ import { PluginCoreGroupsApi } from "./groups"
9
+ import { PluginCoreBuildingsApi } from "./buildings"
10
+ import { PluginCoreLayersApi } from "./layers"
11
+ import { PluginCoreTagsApi } from "./tags"
3
12
 
4
13
  /**
5
- * Core primitives used across the plugin API.
14
+ * Core primitives and infrastructure used across the plugin API.
6
15
  *
7
16
  * - {@linkcode PluginCoreApi.math} — Vector and quaternion operations
8
17
  * - {@linkcode PluginCoreApi.geom} — Geometry primitives (lines, arcs, curves, profiles)
18
+ * - {@linkcode PluginCoreApi.history} — Undo / redo of committed history entries
19
+ * - {@linkcode PluginCoreApi.units} — Unit-type queries and conversion
20
+ * - {@linkcode PluginCoreApi.zoom} — Camera zoom controls (extents / selection)
21
+ * - {@linkcode PluginCoreApi.project} — Project-level settings and info
22
+ * - {@linkcode PluginCoreApi.comment} — Comments: create, edit, resolve, tag, list
23
+ * - {@linkcode PluginCoreApi.groups} — Read & edit the group hierarchy
24
+ * - {@linkcode PluginCoreApi.buildings} — Read & edit buildings and their storeys
25
+ * - {@linkcode PluginCoreApi.layers} — Read & toggle storey drawing/reference layers
26
+ * - {@linkcode PluginCoreApi.tags} — Tag catalog + assignment
9
27
  */
10
28
  export abstract class PluginCoreApi {
11
29
  /** Vector and quaternion math utilities. See {@linkcode PluginMathApi}. */
12
30
  public abstract math: PluginMathApi
13
31
  /** Geometry primitives and constructors. See {@linkcode PluginGeomApi}. */
14
32
  public abstract geom: PluginGeomApi
33
+ /** Undo / redo of committed history entries. See {@linkcode PluginHistoryApi}. */
34
+ public abstract history: PluginHistoryApi
35
+ /** Unit-type queries and conversion. See {@linkcode PluginUnitsApi}. */
36
+ public abstract units: PluginUnitsApi
37
+ /** Camera zoom controls. See {@linkcode PluginZoomApi}. */
38
+ public abstract zoom: PluginZoomApi
39
+ /** Project-level settings and info. See {@linkcode PluginProjectApi}. */
40
+ public abstract project: PluginProjectApi
41
+ /** Comments — create, edit, resolve, tag, list. See {@linkcode PluginCommentApi}. */
42
+ public abstract comment: PluginCommentApi
43
+ /** Groups — read & edit the group hierarchy. See {@linkcode PluginCoreGroupsApi}. */
44
+ public abstract groups: PluginCoreGroupsApi
45
+ /** Buildings — read & edit buildings and their storeys. See {@linkcode PluginCoreBuildingsApi}. */
46
+ public abstract buildings: PluginCoreBuildingsApi
47
+ /** Layers — read & toggle storey drawing/reference layers. See {@linkcode PluginCoreLayersApi}. */
48
+ public abstract layers: PluginCoreLayersApi
49
+ /** Tags — tag catalog + assignment. See {@linkcode PluginCoreTagsApi}. */
50
+ public abstract tags: PluginCoreTagsApi
15
51
 
16
52
  constructor() {}
17
53
  }
18
54
 
19
55
  export * from "./math"
20
56
  export * from "./geom"
57
+ export * from "./history"
58
+ export * from "./units"
59
+ export * from "./zoom"
60
+ export * from "./project"
61
+ export * from "./comment"
62
+ export * from "./groups"
63
+ export * from "./buildings"
64
+ export * from "./layers"
65
+ export * from "./tags"