@horizon36596/zenith-core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +18 -0
  3. package/README.md +16 -0
  4. package/dist/canonicalize.d.ts +25 -0
  5. package/dist/canonicalize.d.ts.map +1 -0
  6. package/dist/canonicalize.js +199 -0
  7. package/dist/canonicalize.js.map +1 -0
  8. package/dist/check.d.ts +26 -0
  9. package/dist/check.d.ts.map +1 -0
  10. package/dist/check.js +231 -0
  11. package/dist/check.js.map +1 -0
  12. package/dist/checks/heading.d.ts +17 -0
  13. package/dist/checks/heading.d.ts.map +1 -0
  14. package/dist/checks/heading.js +78 -0
  15. package/dist/checks/heading.js.map +1 -0
  16. package/dist/checks/intake.d.ts +28 -0
  17. package/dist/checks/intake.d.ts.map +1 -0
  18. package/dist/checks/intake.js +131 -0
  19. package/dist/checks/intake.js.map +1 -0
  20. package/dist/checks/motion.d.ts +28 -0
  21. package/dist/checks/motion.d.ts.map +1 -0
  22. package/dist/checks/motion.js +252 -0
  23. package/dist/checks/motion.js.map +1 -0
  24. package/dist/checks/schedule.d.ts +29 -0
  25. package/dist/checks/schedule.d.ts.map +1 -0
  26. package/dist/checks/schedule.js +166 -0
  27. package/dist/checks/schedule.js.map +1 -0
  28. package/dist/checks/season.d.ts +6 -0
  29. package/dist/checks/season.d.ts.map +1 -0
  30. package/dist/checks/season.js +126 -0
  31. package/dist/checks/season.js.map +1 -0
  32. package/dist/continuity.d.ts +38 -0
  33. package/dist/continuity.d.ts.map +1 -0
  34. package/dist/continuity.js +69 -0
  35. package/dist/continuity.js.map +1 -0
  36. package/dist/diff.d.ts +37 -0
  37. package/dist/diff.d.ts.map +1 -0
  38. package/dist/diff.js +258 -0
  39. package/dist/diff.js.map +1 -0
  40. package/dist/edit/command.d.ts +4 -0
  41. package/dist/edit/command.d.ts.map +1 -0
  42. package/dist/edit/command.js +16 -0
  43. package/dist/edit/command.js.map +1 -0
  44. package/dist/edit/errors.d.ts +9 -0
  45. package/dist/edit/errors.d.ts.map +1 -0
  46. package/dist/edit/errors.js +12 -0
  47. package/dist/edit/errors.js.map +1 -0
  48. package/dist/edit/fields.d.ts +40 -0
  49. package/dist/edit/fields.d.ts.map +1 -0
  50. package/dist/edit/fields.js +150 -0
  51. package/dist/edit/fields.js.map +1 -0
  52. package/dist/edit/finish.d.ts +15 -0
  53. package/dist/edit/finish.d.ts.map +1 -0
  54. package/dist/edit/finish.js +36 -0
  55. package/dist/edit/finish.js.map +1 -0
  56. package/dist/edit/groups.d.ts +66 -0
  57. package/dist/edit/groups.d.ts.map +1 -0
  58. package/dist/edit/groups.js +277 -0
  59. package/dist/edit/groups.js.map +1 -0
  60. package/dist/edit/ids.d.ts +39 -0
  61. package/dist/edit/ids.d.ts.map +1 -0
  62. package/dist/edit/ids.js +76 -0
  63. package/dist/edit/ids.js.map +1 -0
  64. package/dist/edit/index.d.ts +22 -0
  65. package/dist/edit/index.d.ts.map +1 -0
  66. package/dist/edit/index.js +22 -0
  67. package/dist/edit/index.js.map +1 -0
  68. package/dist/edit/meta.d.ts +15 -0
  69. package/dist/edit/meta.d.ts.map +1 -0
  70. package/dist/edit/meta.js +13 -0
  71. package/dist/edit/meta.js.map +1 -0
  72. package/dist/edit/path.d.ts +36 -0
  73. package/dist/edit/path.d.ts.map +1 -0
  74. package/dist/edit/path.js +135 -0
  75. package/dist/edit/path.js.map +1 -0
  76. package/dist/edit/steps.d.ts +53 -0
  77. package/dist/edit/steps.d.ts.map +1 -0
  78. package/dist/edit/steps.js +0 -0
  79. package/dist/edit/steps.js.map +1 -0
  80. package/dist/edit/template.d.ts +18 -0
  81. package/dist/edit/template.d.ts.map +1 -0
  82. package/dist/edit/template.js +30 -0
  83. package/dist/edit/template.js.map +1 -0
  84. package/dist/edit/timing.d.ts +11 -0
  85. package/dist/edit/timing.d.ts.map +1 -0
  86. package/dist/edit/timing.js +23 -0
  87. package/dist/edit/timing.js.map +1 -0
  88. package/dist/edit/tree.d.ts +32 -0
  89. package/dist/edit/tree.d.ts.map +1 -0
  90. package/dist/edit/tree.js +90 -0
  91. package/dist/edit/tree.js.map +1 -0
  92. package/dist/estimate.d.ts +48 -0
  93. package/dist/estimate.d.ts.map +1 -0
  94. package/dist/estimate.js +443 -0
  95. package/dist/estimate.js.map +1 -0
  96. package/dist/findingHelp.d.ts +18 -0
  97. package/dist/findingHelp.d.ts.map +1 -0
  98. package/dist/findingHelp.js +114 -0
  99. package/dist/findingHelp.js.map +1 -0
  100. package/dist/fix.d.ts +21 -0
  101. package/dist/fix.d.ts.map +1 -0
  102. package/dist/fix.js +180 -0
  103. package/dist/fix.js.map +1 -0
  104. package/dist/footprint.d.ts +33 -0
  105. package/dist/footprint.d.ts.map +1 -0
  106. package/dist/footprint.js +71 -0
  107. package/dist/footprint.js.map +1 -0
  108. package/dist/geometry/angle.d.ts +13 -0
  109. package/dist/geometry/angle.d.ts.map +1 -0
  110. package/dist/geometry/angle.js +21 -0
  111. package/dist/geometry/angle.js.map +1 -0
  112. package/dist/geometry/curve.d.ts +24 -0
  113. package/dist/geometry/curve.d.ts.map +1 -0
  114. package/dist/geometry/curve.js +78 -0
  115. package/dist/geometry/curve.js.map +1 -0
  116. package/dist/geometry/path.d.ts +29 -0
  117. package/dist/geometry/path.d.ts.map +1 -0
  118. package/dist/geometry/path.js +61 -0
  119. package/dist/geometry/path.js.map +1 -0
  120. package/dist/geometry/quadrature.d.ts +13 -0
  121. package/dist/geometry/quadrature.d.ts.map +1 -0
  122. package/dist/geometry/quadrature.js +57 -0
  123. package/dist/geometry/quadrature.js.map +1 -0
  124. package/dist/geometry/sat.d.ts +40 -0
  125. package/dist/geometry/sat.d.ts.map +1 -0
  126. package/dist/geometry/sat.js +86 -0
  127. package/dist/geometry/sat.js.map +1 -0
  128. package/dist/geometry/vec.d.ts +27 -0
  129. package/dist/geometry/vec.d.ts.map +1 -0
  130. package/dist/geometry/vec.js +30 -0
  131. package/dist/geometry/vec.js.map +1 -0
  132. package/dist/heading.d.ts +77 -0
  133. package/dist/heading.d.ts.map +1 -0
  134. package/dist/heading.js +164 -0
  135. package/dist/heading.js.map +1 -0
  136. package/dist/headingRanges.d.ts +48 -0
  137. package/dist/headingRanges.d.ts.map +1 -0
  138. package/dist/headingRanges.js +132 -0
  139. package/dist/headingRanges.js.map +1 -0
  140. package/dist/index.d.ts +41 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +41 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/kinematics.d.ts +63 -0
  145. package/dist/kinematics.d.ts.map +1 -0
  146. package/dist/kinematics.js +71 -0
  147. package/dist/kinematics.js.map +1 -0
  148. package/dist/ledger.d.ts +49 -0
  149. package/dist/ledger.d.ts.map +1 -0
  150. package/dist/ledger.js +136 -0
  151. package/dist/ledger.js.map +1 -0
  152. package/dist/load.d.ts +12 -0
  153. package/dist/load.d.ts.map +1 -0
  154. package/dist/load.js +12 -0
  155. package/dist/load.js.map +1 -0
  156. package/dist/mirror.d.ts +81 -0
  157. package/dist/mirror.d.ts.map +1 -0
  158. package/dist/mirror.js +282 -0
  159. package/dist/mirror.js.map +1 -0
  160. package/dist/plan.d.ts +29 -0
  161. package/dist/plan.d.ts.map +1 -0
  162. package/dist/plan.js +159 -0
  163. package/dist/plan.js.map +1 -0
  164. package/dist/prBody.d.ts +24 -0
  165. package/dist/prBody.d.ts.map +1 -0
  166. package/dist/prBody.js +112 -0
  167. package/dist/prBody.js.map +1 -0
  168. package/dist/provenance.d.ts +21 -0
  169. package/dist/provenance.d.ts.map +1 -0
  170. package/dist/provenance.js +46 -0
  171. package/dist/provenance.js.map +1 -0
  172. package/dist/render.d.ts +18 -0
  173. package/dist/render.d.ts.map +1 -0
  174. package/dist/render.js +464 -0
  175. package/dist/render.js.map +1 -0
  176. package/dist/resolve.d.ts +39 -0
  177. package/dist/resolve.d.ts.map +1 -0
  178. package/dist/resolve.js +172 -0
  179. package/dist/resolve.js.map +1 -0
  180. package/dist/season.d.ts +65 -0
  181. package/dist/season.d.ts.map +1 -0
  182. package/dist/season.js +16 -0
  183. package/dist/season.js.map +1 -0
  184. package/dist/sim/commands.d.ts +97 -0
  185. package/dist/sim/commands.d.ts.map +1 -0
  186. package/dist/sim/commands.js +185 -0
  187. package/dist/sim/commands.js.map +1 -0
  188. package/dist/sim/curves.d.ts +37 -0
  189. package/dist/sim/curves.d.ts.map +1 -0
  190. package/dist/sim/curves.js +187 -0
  191. package/dist/sim/curves.js.map +1 -0
  192. package/dist/sim/follower.d.ts +124 -0
  193. package/dist/sim/follower.d.ts.map +1 -0
  194. package/dist/sim/follower.js +472 -0
  195. package/dist/sim/follower.js.map +1 -0
  196. package/dist/sim/ideal.d.ts +103 -0
  197. package/dist/sim/ideal.d.ts.map +1 -0
  198. package/dist/sim/ideal.js +393 -0
  199. package/dist/sim/ideal.js.map +1 -0
  200. package/dist/sim/index.d.ts +11 -0
  201. package/dist/sim/index.d.ts.map +1 -0
  202. package/dist/sim/index.js +10 -0
  203. package/dist/sim/index.js.map +1 -0
  204. package/dist/sim/params.d.ts +91 -0
  205. package/dist/sim/params.d.ts.map +1 -0
  206. package/dist/sim/params.js +195 -0
  207. package/dist/sim/params.js.map +1 -0
  208. package/dist/sim/pedroPath.d.ts +41 -0
  209. package/dist/sim/pedroPath.d.ts.map +1 -0
  210. package/dist/sim/pedroPath.js +191 -0
  211. package/dist/sim/pedroPath.js.map +1 -0
  212. package/dist/sim/plant.d.ts +59 -0
  213. package/dist/sim/plant.d.ts.map +1 -0
  214. package/dist/sim/plant.js +128 -0
  215. package/dist/sim/plant.js.map +1 -0
  216. package/dist/sim/residuals.d.ts +36 -0
  217. package/dist/sim/residuals.d.ts.map +1 -0
  218. package/dist/sim/residuals.js +86 -0
  219. package/dist/sim/residuals.js.map +1 -0
  220. package/dist/sim/simulate.d.ts +27 -0
  221. package/dist/sim/simulate.d.ts.map +1 -0
  222. package/dist/sim/simulate.js +924 -0
  223. package/dist/sim/simulate.js.map +1 -0
  224. package/dist/sim/types.d.ts +209 -0
  225. package/dist/sim/types.d.ts.map +1 -0
  226. package/dist/sim/types.js +2 -0
  227. package/dist/sim/types.js.map +1 -0
  228. package/dist/tokens.d.ts +93 -0
  229. package/dist/tokens.d.ts.map +1 -0
  230. package/dist/tokens.js +93 -0
  231. package/dist/tokens.js.map +1 -0
  232. package/dist/trace.d.ts +89 -0
  233. package/dist/trace.d.ts.map +1 -0
  234. package/dist/trace.js +187 -0
  235. package/dist/trace.js.map +1 -0
  236. package/dist/types.d.ts +219 -0
  237. package/dist/types.d.ts.map +1 -0
  238. package/dist/types.js +2 -0
  239. package/dist/types.js.map +1 -0
  240. package/dist/unimplemented.d.ts +8 -0
  241. package/dist/unimplemented.d.ts.map +1 -0
  242. package/dist/unimplemented.js +11 -0
  243. package/dist/unimplemented.js.map +1 -0
  244. package/package.json +59 -0
@@ -0,0 +1,66 @@
1
+ import { type Auto, type ParallelStep, type Step, type Waypoints } from "@horizon36596/zenith-schema";
2
+ /**
3
+ * Wraps the steps named by `ids` in a new `sequence` or `parallel` group, in place.
4
+ *
5
+ * The steps must be siblings (members of one list: the top level, one group, or one branch arm)
6
+ * and must form one unbroken run in that list, in any order in `ids`; the group takes their
7
+ * document order. A `parallel` group takes `mode` (default `all`); a `deadline` group's deadline
8
+ * is the first member that drives the robot, or the first member when none does.
9
+ *
10
+ * The new group gets an explicit id (`sequence`, `parallel`, disambiguated with `-2`, `-3`, ...),
11
+ * which the result's `id` reports. When the run held the deadline of the parallel group around it,
12
+ * that deadline now names the new group, which is the member that contains it.
13
+ */
14
+ export declare function wrapSteps(auto: Auto, ids: readonly string[], kind: "sequence" | "parallel", mode?: ParallelStep["mode"]): Auto;
15
+ /** `wrapSteps`, also returning the id the new group was given. */
16
+ export declare function wrapStepsWithId(auto: Auto, ids: readonly string[], kind: "sequence" | "parallel", mode?: ParallelStep["mode"]): {
17
+ auto: Auto;
18
+ id: string;
19
+ };
20
+ /**
21
+ * Replaces the `sequence` or `parallel` group `id` with its members, in place, in the list that
22
+ * held it. A branch is refused: its two arms cannot both stand where it stood.
23
+ *
24
+ * The members keep the ids they had (a positional member is given its old id explicitly), and so
25
+ * do the siblings after it whose position shifts. When the group was the deadline of the parallel
26
+ * group around it, that deadline passes to the member that decided when the group ended: its own
27
+ * deadline for a deadline group, else its last member that drives, else its last member.
28
+ */
29
+ export declare function unwrapStep(auto: Auto, id: string): Auto;
30
+ /** What `insertStepAfter` did, and what it left for the editor to offer. */
31
+ export interface InsertResult {
32
+ auto: Auto;
33
+ /** The id the new step was given. */
34
+ id: string;
35
+ /**
36
+ * The path step after the new one that no longer starts where the robot now is, when there is
37
+ * one: the editor offers `repairContinuity` on it. Null when the insertion left no new gap.
38
+ */
39
+ continuityGapStepId: string | null;
40
+ /** How far that step starts from where the robot now is, in inches, when there is a gap. */
41
+ continuityGapIn: number | null;
42
+ }
43
+ /**
44
+ * Inserts `step` right after `afterId`, continuing from where that step ends
45
+ * (site/docs/editor.md, "The insert menu").
46
+ *
47
+ * When the new step is a path, its first segment starts at the pose the step at `afterId` ends
48
+ * at: `"current"` when the new step runs right after it (the top level, a sequence, a branch arm),
49
+ * or that pose written out when the two are members of one parallel group, where `"current"`
50
+ * would mean the pose the group started at. `waypoints` resolves any references on the way to
51
+ * that pose.
52
+ *
53
+ * The step after the insertion point used to follow `afterId` and now follows the new step, so it
54
+ * may no longer start where the robot is. The result names it (`continuityGapStepId`) when the
55
+ * insertion opened a CONTINUITY gap there that was not there before, and `repairContinuity` fixes
56
+ * it. A step without an explicit id is given one, as `addStep` does.
57
+ */
58
+ export declare function insertStepAfter(auto: Auto, afterId: string, step: Step, waypoints?: Waypoints): InsertResult;
59
+ /**
60
+ * Makes the path step `stepId` start wherever the robot is when it begins, by setting its first
61
+ * segment's `from` to `"current"`. This is the repair `insertStepAfter` offers for the gap it can
62
+ * leave; it removes a CONTINUITY finding between steps, and leaves any gap between one segment and
63
+ * the next inside the step alone.
64
+ */
65
+ export declare function repairContinuity(auto: Auto, stepId: string): Auto;
66
+ //# sourceMappingURL=groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../src/edit/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,IAAI,EACT,KAAK,YAAY,EAGjB,KAAK,IAAI,EACT,KAAK,SAAS,EACf,MAAM,6BAA6B,CAAC;AA+FrC;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,IAAI,EAAE,UAAU,GAAG,UAAU,EAC7B,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,GAC1B,IAAI,CAEN;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,IAAI,EAAE,UAAU,GAAG,UAAU,EAC7B,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,GAC1B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CA2D5B;AAaD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CA6BvD;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,4FAA4F;IAC5F,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,EACV,SAAS,CAAC,EAAE,SAAS,GACpB,YAAY,CA6Dd;AAYD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAcjE"}
@@ -0,0 +1,277 @@
1
+ import { childLists, withChildLists, } from "@horizon36596/zenith-schema";
2
+ import { continuityGaps } from "../continuity.js";
3
+ import { resolve } from "../resolve.js";
4
+ import { EditError } from "./errors.js";
5
+ import { finish } from "./finish.js";
6
+ import { childPrefix, collectIds, effectiveId, uniqueId } from "./ids.js";
7
+ import { findStep, insertAfter, updateStep } from "./tree.js";
8
+ /** Finds the list whose members include `targetId`, anywhere in the tree. */
9
+ function locate(steps, prefix, targetId, parent = null, parentId = null) {
10
+ for (const [index, step] of steps.entries()) {
11
+ const id = effectiveId(step, index, prefix);
12
+ if (id === targetId)
13
+ return { list: steps, prefix, parent, parentId };
14
+ const lists = childLists(step);
15
+ for (const [listIndex, list] of lists.entries()) {
16
+ const found = locate(list, childPrefix(id, lists.length, listIndex), targetId, step, id);
17
+ if (found !== null)
18
+ return found;
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Replaces the list that holds `targetId` with `transform(list, prefix)`, wherever it sits.
25
+ * Returns null when no list holds it.
26
+ */
27
+ function replaceList(steps, prefix, targetId, transform) {
28
+ for (const [index, step] of steps.entries()) {
29
+ if (effectiveId(step, index, prefix) === targetId)
30
+ return transform(steps, prefix);
31
+ }
32
+ for (const [index, step] of steps.entries()) {
33
+ const id = effectiveId(step, index, prefix);
34
+ const lists = childLists(step);
35
+ for (const [listIndex, list] of lists.entries()) {
36
+ const replaced = replaceList(list, childPrefix(id, lists.length, listIndex), targetId, transform);
37
+ if (replaced === null)
38
+ continue;
39
+ const rebuilt = lists.map((original, i) => (i === listIndex ? replaced : original));
40
+ return steps.map((sibling, i) => (i === index ? withChildLists(step, rebuilt) : sibling));
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /** The step with its effective id written out, so moving it cannot change what it is called. */
46
+ const pinned = (step, index, prefix) => step.id === undefined ? { ...step, id: effectiveId(step, index, prefix) } : step;
47
+ /** Every `parallel.deadline` equal to `oldId` renamed to `newId`, throughout the tree. */
48
+ function renameDeadline(steps, oldId, newId) {
49
+ return steps.map((step) => {
50
+ const lists = childLists(step);
51
+ if (lists.length === 0)
52
+ return step;
53
+ const updated = withChildLists(step, lists.map((list) => renameDeadline(list, oldId, newId)));
54
+ if (updated.kind === "parallel" && updated.deadline === oldId)
55
+ updated.deadline = newId;
56
+ return updated;
57
+ });
58
+ }
59
+ /**
60
+ * Wraps the steps named by `ids` in a new `sequence` or `parallel` group, in place.
61
+ *
62
+ * The steps must be siblings (members of one list: the top level, one group, or one branch arm)
63
+ * and must form one unbroken run in that list, in any order in `ids`; the group takes their
64
+ * document order. A `parallel` group takes `mode` (default `all`); a `deadline` group's deadline
65
+ * is the first member that drives the robot, or the first member when none does.
66
+ *
67
+ * The new group gets an explicit id (`sequence`, `parallel`, disambiguated with `-2`, `-3`, ...),
68
+ * which the result's `id` reports. When the run held the deadline of the parallel group around it,
69
+ * that deadline now names the new group, which is the member that contains it.
70
+ */
71
+ export function wrapSteps(auto, ids, kind, mode) {
72
+ return wrapStepsWithId(auto, ids, kind, mode).auto;
73
+ }
74
+ /** `wrapSteps`, also returning the id the new group was given. */
75
+ export function wrapStepsWithId(auto, ids, kind, mode) {
76
+ if (ids.length === 0)
77
+ throw new EditError("Name at least one step to wrap.");
78
+ if (kind === "sequence" && mode !== undefined) {
79
+ throw new EditError("A sequence has no mode; only a parallel group runs all, race or deadline.");
80
+ }
81
+ const first = ids[0];
82
+ const where = locate(auto.steps, "step", first);
83
+ if (where === null)
84
+ throw new EditError(`No step with id ${JSON.stringify(first)}.`);
85
+ const positions = ids.map((id) => {
86
+ const index = where.list.findIndex((step, i) => effectiveId(step, i, where.prefix) === id);
87
+ if (index < 0) {
88
+ throw new EditError(findStep(auto.steps, "step", id) === null
89
+ ? `No step with id ${JSON.stringify(id)}.`
90
+ : `Steps ${JSON.stringify(first)} and ${JSON.stringify(id)} are not in the same list; only siblings can be wrapped together.`);
91
+ }
92
+ return index;
93
+ });
94
+ const sorted = [...new Set(positions)].sort((a, b) => a - b);
95
+ const start = sorted[0];
96
+ const end = sorted[sorted.length - 1];
97
+ if (end - start + 1 !== sorted.length) {
98
+ throw new EditError("The steps to wrap have to be one unbroken run; wrapping steps with others between them would move those others.");
99
+ }
100
+ const groupId = uniqueId(kind, collectIds(auto.steps));
101
+ const steps = replaceList(auto.steps, "step", first, (list, prefix) => {
102
+ const frozen = list.map((step, index) => (index >= start ? pinned(step, index, prefix) : step));
103
+ const members = frozen.slice(start, end + 1);
104
+ let group;
105
+ if (kind === "sequence") {
106
+ const sequence = { id: groupId, kind: "sequence", steps: members };
107
+ group = sequence;
108
+ }
109
+ else {
110
+ const parallel = { id: groupId, kind: "parallel", mode: mode ?? "all", steps: members };
111
+ if (parallel.mode === "deadline") {
112
+ const driver = members.find((member) => stepDrives(member)) ?? members[0];
113
+ if (driver?.id !== undefined)
114
+ parallel.deadline = driver.id;
115
+ }
116
+ group = parallel;
117
+ }
118
+ return [...frozen.slice(0, start), group, ...frozen.slice(end + 1)];
119
+ });
120
+ if (steps === null)
121
+ throw new EditError(`No step with id ${JSON.stringify(first)}.`);
122
+ let result = steps;
123
+ if (where.parent?.kind === "parallel" && where.parent.deadline !== undefined) {
124
+ const wrappedIds = new Set(where.list.slice(start, end + 1).map((step, i) => effectiveId(step, start + i, where.prefix)));
125
+ if (wrappedIds.has(where.parent.deadline)) {
126
+ result = repointParentDeadline(result, where.parentId, groupId);
127
+ }
128
+ }
129
+ return { auto: finish({ ...auto, steps: result }), id: groupId };
130
+ }
131
+ /** Sets the `deadline` of the parallel group `parentId` to `deadline`. */
132
+ function repointParentDeadline(steps, parentId, deadline) {
133
+ return updateStep(steps, "step", parentId, (parent) => parent.kind === "parallel" ? { ...parent, deadline } : undefined).steps;
134
+ }
135
+ /** True for a path step, or a group with one somewhere inside it. */
136
+ const stepDrives = (step) => step.kind === "path" || childLists(step).some((list) => list.some(stepDrives));
137
+ /**
138
+ * Replaces the `sequence` or `parallel` group `id` with its members, in place, in the list that
139
+ * held it. A branch is refused: its two arms cannot both stand where it stood.
140
+ *
141
+ * The members keep the ids they had (a positional member is given its old id explicitly), and so
142
+ * do the siblings after it whose position shifts. When the group was the deadline of the parallel
143
+ * group around it, that deadline passes to the member that decided when the group ended: its own
144
+ * deadline for a deadline group, else its last member that drives, else its last member.
145
+ */
146
+ export function unwrapStep(auto, id) {
147
+ const where = locate(auto.steps, "step", id);
148
+ if (where === null)
149
+ throw new EditError(`No step with id ${JSON.stringify(id)}.`);
150
+ const index = where.list.findIndex((step, i) => effectiveId(step, i, where.prefix) === id);
151
+ const group = where.list[index];
152
+ if (group.kind !== "sequence" && group.kind !== "parallel") {
153
+ throw new EditError(`Step ${JSON.stringify(id)} is a ${group.kind} step; only a sequence or a parallel group can be unwrapped.`);
154
+ }
155
+ const memberPrefix = childPrefix(id, 1, 0);
156
+ const members = group.steps.map((member, i) => pinned(member, i, memberPrefix));
157
+ const successor = (group.kind === "parallel" && group.deadline !== undefined
158
+ ? members.find((member) => member.id === group.deadline)
159
+ : undefined) ??
160
+ [...members].reverse().find((member) => stepDrives(member)) ??
161
+ members[members.length - 1];
162
+ const steps = replaceList(auto.steps, "step", id, (list, prefix) => {
163
+ const frozen = list.map((step, i) => (i > index ? pinned(step, i, prefix) : step));
164
+ return [...frozen.slice(0, index), ...members, ...frozen.slice(index + 1)];
165
+ });
166
+ if (steps === null)
167
+ throw new EditError(`No step with id ${JSON.stringify(id)}.`);
168
+ const result = successor?.id === undefined ? steps : renameDeadline(steps, id, successor.id);
169
+ return finish({ ...auto, steps: result });
170
+ }
171
+ /**
172
+ * Inserts `step` right after `afterId`, continuing from where that step ends
173
+ * (site/docs/editor.md, "The insert menu").
174
+ *
175
+ * When the new step is a path, its first segment starts at the pose the step at `afterId` ends
176
+ * at: `"current"` when the new step runs right after it (the top level, a sequence, a branch arm),
177
+ * or that pose written out when the two are members of one parallel group, where `"current"`
178
+ * would mean the pose the group started at. `waypoints` resolves any references on the way to
179
+ * that pose.
180
+ *
181
+ * The step after the insertion point used to follow `afterId` and now follows the new step, so it
182
+ * may no longer start where the robot is. The result names it (`continuityGapStepId`) when the
183
+ * insertion opened a CONTINUITY gap there that was not there before, and `repairContinuity` fixes
184
+ * it. A step without an explicit id is given one, as `addStep` does.
185
+ */
186
+ export function insertStepAfter(auto, afterId, step, waypoints) {
187
+ const where = locate(auto.steps, "step", afterId);
188
+ if (where === null)
189
+ throw new EditError(`No step with id ${JSON.stringify(afterId)} to insert after.`);
190
+ const before = resolve(auto, waypoints);
191
+ const anchor = findResolved(before.steps, afterId);
192
+ if (anchor === null)
193
+ throw new EditError(`No step with id ${JSON.stringify(afterId)} to insert after.`);
194
+ let placed = step;
195
+ if (step.kind === "path") {
196
+ const concurrent = where.parent?.kind === "parallel";
197
+ const from = concurrent
198
+ ? {
199
+ xIn: anchor.endPose.xIn,
200
+ yIn: anchor.endPose.yIn,
201
+ headingRad: anchor.endPose.headingRad,
202
+ provenance: `SET FROM EDITOR: where ${afterId} ends`,
203
+ }
204
+ : "current";
205
+ const [firstSegment, ...rest] = step.segments;
206
+ if (firstSegment !== undefined) {
207
+ const path = { ...step, segments: [{ ...firstSegment, from }, ...rest] };
208
+ placed = path;
209
+ }
210
+ }
211
+ // Positional siblings after the insertion point shift by one; pin them first so they keep the
212
+ // ids the caller knows them by.
213
+ const frozen = replaceList(auto.steps, "step", afterId, (list, prefix) => {
214
+ const at = list.findIndex((sibling, i) => effectiveId(sibling, i, prefix) === afterId);
215
+ return list.map((sibling, i) => (i > at ? pinned(sibling, i, prefix) : sibling));
216
+ });
217
+ if (frozen === null)
218
+ throw new EditError(`No step with id ${JSON.stringify(afterId)} to insert after.`);
219
+ const PENDING = " inserting";
220
+ const inserted = insertAfter(frozen, "step", afterId, { ...placed, id: PENDING });
221
+ const taken = collectIds(inserted.steps);
222
+ taken.delete(PENDING);
223
+ let id;
224
+ if (step.id === undefined) {
225
+ id = uniqueId(step.kind, taken);
226
+ }
227
+ else {
228
+ if (taken.has(step.id)) {
229
+ throw new EditError(`A step with id ${JSON.stringify(step.id)} already exists.`);
230
+ }
231
+ id = step.id;
232
+ }
233
+ const named = updateStep(inserted.steps, "step", PENDING, (pending) => ({ ...pending, id }));
234
+ const result = finish({ ...auto, steps: named.steps });
235
+ const gapsBefore = new Map(continuityGaps(before.steps, before.startPose).map((gap) => [gap.stepId, gap.gapIn]));
236
+ const afterResolve = resolve(result, waypoints);
237
+ const opened = continuityGaps(afterResolve.steps, afterResolve.startPose).find((gap) => gap.stepId !== id && gap.gapIn > (gapsBefore.get(gap.stepId) ?? 0));
238
+ return {
239
+ auto: result,
240
+ id,
241
+ continuityGapStepId: opened?.stepId ?? null,
242
+ continuityGapIn: opened?.gapIn ?? null,
243
+ };
244
+ }
245
+ /** The resolved step with this id, anywhere in the tree. */
246
+ function findResolved(steps, id) {
247
+ for (const step of steps) {
248
+ if (step.id === id)
249
+ return step;
250
+ const nested = findResolved(step.children ?? [], id);
251
+ if (nested !== null)
252
+ return nested;
253
+ }
254
+ return null;
255
+ }
256
+ /**
257
+ * Makes the path step `stepId` start wherever the robot is when it begins, by setting its first
258
+ * segment's `from` to `"current"`. This is the repair `insertStepAfter` offers for the gap it can
259
+ * leave; it removes a CONTINUITY finding between steps, and leaves any gap between one segment and
260
+ * the next inside the step alone.
261
+ */
262
+ export function repairContinuity(auto, stepId) {
263
+ const result = updateStep(auto.steps, "step", stepId, (step) => {
264
+ if (step.kind !== "path") {
265
+ throw new EditError(`Step ${JSON.stringify(stepId)} is a ${step.kind} step; only a path step has a start to repair.`);
266
+ }
267
+ const [firstSegment, ...rest] = step.segments;
268
+ if (firstSegment === undefined)
269
+ return undefined;
270
+ const path = { ...step, segments: [{ ...firstSegment, from: "current" }, ...rest] };
271
+ return path;
272
+ });
273
+ if (!result.found)
274
+ throw new EditError(`No step with id ${JSON.stringify(stepId)}.`);
275
+ return finish({ ...auto, steps: result.steps });
276
+ }
277
+ //# sourceMappingURL=groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../src/edit/groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type Step } from "@horizon36596/zenith-schema";
2
+ /**
3
+ * The id a step is addressed by, whether or not it carries an explicit `id` field. This is the one
4
+ * definition: `resolve()`, `diff()` and the editor's step list all call it, so a `stepId` an edit
5
+ * primitive accepts, a `Finding.stepId` a check raises and the id the inspector shows are always
6
+ * the same string.
7
+ *
8
+ * A step with no explicit id is positional: removing or inserting a sibling before it in the same
9
+ * list changes its effective id. That is inherent to the file format, not something an edit
10
+ * primitive can paper over, which is why `addStep` always gives the new step an explicit id
11
+ * (`uniqueId` below) rather than leaving it positional.
12
+ */
13
+ export declare function effectiveId(step: Step, index: number, prefix: string): string;
14
+ /**
15
+ * The id prefix `resolve()` gives the children of a group step: `grp.` for the one list of a
16
+ * sequence or parallel group (so its members are `grp.1`, `grp.2`), and `br.1.` / `br.2.` for the
17
+ * two arms of a branch that has both. `branchCount` is how many child lists the group has, which
18
+ * `childLists` answers.
19
+ */
20
+ export declare function childPrefix(parentId: string, branchCount: number, branchIndex: number): string;
21
+ /**
22
+ * Every effective id in a step forest, depth first, in document order and with repeats kept.
23
+ *
24
+ * `collectIds` folds this into a set for the "is this id taken" question; `duplicateIds` is the
25
+ * other half, because an id that appears twice makes every finding, fix and edit primitive
26
+ * ambiguous and has to be reported rather than quietly collapsed.
27
+ */
28
+ export declare function listIds(steps: readonly Step[], prefix?: string, ids?: string[]): string[];
29
+ /** Every effective id in a step forest, depth first, for uniqueness checks. */
30
+ export declare function collectIds(steps: readonly Step[], prefix?: string): Set<string>;
31
+ /** The effective ids that appear more than once, in the order they are first seen. */
32
+ export declare function duplicateIds(steps: readonly Step[], prefix?: string): string[];
33
+ /**
34
+ * A deterministic id derived from `base` that is not already in `taken`: `base`, then `base-2`,
35
+ * `base-3`, and so on. No randomness and no clock (CLAUDE.md rule 1): the same inputs always
36
+ * choose the same id.
37
+ */
38
+ export declare function uniqueId(base: string, taken: ReadonlySet<string>): string;
39
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/edit/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9F;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,MAAM,SAAS,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAU7F;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAE/E;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,MAAM,SAAS,GAAG,MAAM,EAAE,CAW9E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAOzE"}
@@ -0,0 +1,76 @@
1
+ import { childLists } from "@horizon36596/zenith-schema";
2
+ /**
3
+ * The id a step is addressed by, whether or not it carries an explicit `id` field. This is the one
4
+ * definition: `resolve()`, `diff()` and the editor's step list all call it, so a `stepId` an edit
5
+ * primitive accepts, a `Finding.stepId` a check raises and the id the inspector shows are always
6
+ * the same string.
7
+ *
8
+ * A step with no explicit id is positional: removing or inserting a sibling before it in the same
9
+ * list changes its effective id. That is inherent to the file format, not something an edit
10
+ * primitive can paper over, which is why `addStep` always gives the new step an explicit id
11
+ * (`uniqueId` below) rather than leaving it positional.
12
+ */
13
+ export function effectiveId(step, index, prefix) {
14
+ return step.id ?? `${prefix}${String(index + 1)}`;
15
+ }
16
+ /**
17
+ * The id prefix `resolve()` gives the children of a group step: `grp.` for the one list of a
18
+ * sequence or parallel group (so its members are `grp.1`, `grp.2`), and `br.1.` / `br.2.` for the
19
+ * two arms of a branch that has both. `branchCount` is how many child lists the group has, which
20
+ * `childLists` answers.
21
+ */
22
+ export function childPrefix(parentId, branchCount, branchIndex) {
23
+ return `${parentId}.${branchCount > 1 ? `${String(branchIndex + 1)}.` : ""}`;
24
+ }
25
+ /**
26
+ * Every effective id in a step forest, depth first, in document order and with repeats kept.
27
+ *
28
+ * `collectIds` folds this into a set for the "is this id taken" question; `duplicateIds` is the
29
+ * other half, because an id that appears twice makes every finding, fix and edit primitive
30
+ * ambiguous and has to be reported rather than quietly collapsed.
31
+ */
32
+ export function listIds(steps, prefix = "step", ids = []) {
33
+ steps.forEach((step, index) => {
34
+ const id = effectiveId(step, index, prefix);
35
+ ids.push(id);
36
+ const lists = childLists(step);
37
+ lists.forEach((list, listIndex) => {
38
+ listIds(list, childPrefix(id, lists.length, listIndex), ids);
39
+ });
40
+ });
41
+ return ids;
42
+ }
43
+ /** Every effective id in a step forest, depth first, for uniqueness checks. */
44
+ export function collectIds(steps, prefix = "step") {
45
+ return new Set(listIds(steps, prefix));
46
+ }
47
+ /** The effective ids that appear more than once, in the order they are first seen. */
48
+ export function duplicateIds(steps, prefix = "step") {
49
+ const seen = new Set();
50
+ const repeated = [];
51
+ for (const id of listIds(steps, prefix)) {
52
+ if (seen.has(id)) {
53
+ if (!repeated.includes(id))
54
+ repeated.push(id);
55
+ continue;
56
+ }
57
+ seen.add(id);
58
+ }
59
+ return repeated;
60
+ }
61
+ /**
62
+ * A deterministic id derived from `base` that is not already in `taken`: `base`, then `base-2`,
63
+ * `base-3`, and so on. No randomness and no clock (CLAUDE.md rule 1): the same inputs always
64
+ * choose the same id.
65
+ */
66
+ export function uniqueId(base, taken) {
67
+ if (!taken.has(base))
68
+ return base;
69
+ for (let n = 2; n < 10000; n += 1) {
70
+ const candidate = `${base}-${String(n)}`;
71
+ if (!taken.has(candidate))
72
+ return candidate;
73
+ }
74
+ throw new Error(`Could not make a unique id from ${JSON.stringify(base)}.`);
75
+ }
76
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/edit/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,6BAA6B,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,KAAa,EAAE,MAAc;IACnE,OAAO,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,WAAmB,EAAE,WAAmB;IACpF,OAAO,GAAG,QAAQ,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAsB,EAAE,MAAM,GAAG,MAAM,EAAE,MAAgB,EAAE;IACjF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACb,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;YAChC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,KAAsB,EAAE,MAAM,GAAG,MAAM;IAChE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,YAAY,CAAC,KAAsB,EAAE,MAAM,GAAG,MAAM;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QACxC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAA0B;IAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Structural edit primitives for `*.auto.json`: pure functions
3
+ * that take an `Auto` and return a new one, never mutate their input, and always leave the result
4
+ * canonically valid — each one ends by parsing its candidate through `@horizon36596/zenith-schema`'s
5
+ * `parseAuto`, which throws `EditError` with a helpful message if the edit would not validate.
6
+ *
7
+ * These are what `packages/mcp`'s `zenith.edit.*` tools call, and what an editor's drag/drop and
8
+ * inspector panels would call too, so an agent or a human never hand-edits the JSON directly.
9
+ */
10
+ export * from "./errors.js";
11
+ export * from "./ids.js";
12
+ export * from "./tree.js";
13
+ export * from "./finish.js";
14
+ export * from "./steps.js";
15
+ export * from "./groups.js";
16
+ export * from "./path.js";
17
+ export * from "./fields.js";
18
+ export * from "./command.js";
19
+ export * from "./timing.js";
20
+ export * from "./meta.js";
21
+ export * from "./template.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/edit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Structural edit primitives for `*.auto.json`: pure functions
3
+ * that take an `Auto` and return a new one, never mutate their input, and always leave the result
4
+ * canonically valid — each one ends by parsing its candidate through `@horizon36596/zenith-schema`'s
5
+ * `parseAuto`, which throws `EditError` with a helpful message if the edit would not validate.
6
+ *
7
+ * These are what `packages/mcp`'s `zenith.edit.*` tools call, and what an editor's drag/drop and
8
+ * inspector panels would call too, so an agent or a human never hand-edits the JSON directly.
9
+ */
10
+ export * from "./errors.js";
11
+ export * from "./ids.js";
12
+ export * from "./tree.js";
13
+ export * from "./finish.js";
14
+ export * from "./steps.js";
15
+ export * from "./groups.js";
16
+ export * from "./path.js";
17
+ export * from "./fields.js";
18
+ export * from "./command.js";
19
+ export * from "./timing.js";
20
+ export * from "./meta.js";
21
+ export * from "./template.js";
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/edit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Auto } from "@horizon36596/zenith-schema";
2
+ /** Replaces the auto's `start` (pose and holds) outright. */
3
+ export declare function setStart(auto: Auto, start: Auto["start"]): Auto;
4
+ /** The auto-level fields `setMeta` may change. Passing `undefined` for a field clears it. */
5
+ export interface AutoMeta {
6
+ title?: string;
7
+ description?: string;
8
+ authors?: string[];
9
+ }
10
+ /**
11
+ * Merges `title`, `description` and `authors` into the auto. A field left out of `meta` is
12
+ * unchanged; a field present with an explicit `undefined` is cleared.
13
+ */
14
+ export declare function setMeta(auto: Auto, meta: AutoMeta): Auto;
15
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/edit/meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGxD,6DAA6D;AAC7D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAE/D;AAED,6FAA6F;AAC7F,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAExD"}
@@ -0,0 +1,13 @@
1
+ import { finish } from "./finish.js";
2
+ /** Replaces the auto's `start` (pose and holds) outright. */
3
+ export function setStart(auto, start) {
4
+ return finish({ ...auto, start });
5
+ }
6
+ /**
7
+ * Merges `title`, `description` and `authors` into the auto. A field left out of `meta` is
8
+ * unchanged; a field present with an explicit `undefined` is cleared.
9
+ */
10
+ export function setMeta(auto, meta) {
11
+ return finish({ ...auto, ...meta });
12
+ }
13
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/edit/meta.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,6DAA6D;AAC7D,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,KAAoB;IACvD,OAAO,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACpC,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,IAAc;IAChD,OAAO,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { Auto, Heading, Marker, MarkerAt, Segment } from "@horizon36596/zenith-schema";
2
+ /** A literal pose to write into a segment endpoint or a Bezier control point. */
3
+ export interface PoseInput {
4
+ xIn: number;
5
+ yIn: number;
6
+ headingRad?: number;
7
+ provenance?: string;
8
+ }
9
+ /** Which point of which segment `setPose` targets. */
10
+ export interface PoseTarget {
11
+ segmentIndex: number;
12
+ pointKind: "from" | "to" | "control";
13
+ /** Required, and only meaningful, when `pointKind` is `"control"`. */
14
+ controlIndex?: number;
15
+ }
16
+ /**
17
+ * Sets one point of one segment of a path step to a literal pose: a segment endpoint (`from` or
18
+ * `to`, replacing whatever pose source — inline pose, waypoint ref or `"current"` — was there) or
19
+ * one Bezier control point.
20
+ */
21
+ export declare function setPose(auto: Auto, stepId: string, target: PoseTarget, pose: PoseInput): Auto;
22
+ /** Replaces a path step's heading mode outright. */
23
+ export declare function setHeadingMode(auto: Auto, stepId: string, heading: Heading): Auto;
24
+ /** Sets a path step's `speedFraction` (0 exclusive, 1 inclusive; the schema enforces the range). */
25
+ export declare function setSpeed(auto: Auto, stepId: string, fraction: number): Auto;
26
+ /** Appends a segment to a path step. A path's segments must stay continuous; `validate` checks that. */
27
+ export declare function addSegment(auto: Auto, stepId: string, segment: Segment): Auto;
28
+ /** Removes the segment at `segmentIndex`. A path step needs at least one segment. */
29
+ export declare function removeSegment(auto: Auto, stepId: string, segmentIndex: number): Auto;
30
+ /** Adds a marker to a path step. */
31
+ export declare function addMarker(auto: Auto, stepId: string, marker: Marker): Auto;
32
+ /** Removes the marker at `markerIndex` from a path step. */
33
+ export declare function removeMarker(auto: Auto, stepId: string, markerIndex: number): Auto;
34
+ /** Moves a marker to a new `at` (path parameter, distance, or distance from the end). */
35
+ export declare function setMarkerAt(auto: Auto, stepId: string, markerIndex: number, at: MarkerAt): Auto;
36
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/edit/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAY,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAKtG,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAQD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAoC7F;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAOjF;AAED,oGAAoG;AACpG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAO3E;AAED,wGAAwG;AACxG,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAO7E;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAiBpF;AAED,oCAAoC;AACpC,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAO1E;AAED,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAalF;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAgB/F"}