@horizon36596/zenith-mcp 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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +18 -0
  3. package/README.md +129 -0
  4. package/dist/editIo.d.ts +15 -0
  5. package/dist/editIo.d.ts.map +1 -0
  6. package/dist/editIo.js +33 -0
  7. package/dist/editIo.js.map +1 -0
  8. package/dist/findings.d.ts +35 -0
  9. package/dist/findings.d.ts.map +1 -0
  10. package/dist/findings.js +76 -0
  11. package/dist/findings.js.map +1 -0
  12. package/dist/index.d.ts +11 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +21 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/project.d.ts +46 -0
  17. package/dist/project.d.ts.map +1 -0
  18. package/dist/project.js +106 -0
  19. package/dist/project.js.map +1 -0
  20. package/dist/resources.d.ts +3 -0
  21. package/dist/resources.d.ts.map +1 -0
  22. package/dist/resources.js +37 -0
  23. package/dist/resources.js.map +1 -0
  24. package/dist/result.d.ts +14 -0
  25. package/dist/result.d.ts.map +1 -0
  26. package/dist/result.js +27 -0
  27. package/dist/result.js.map +1 -0
  28. package/dist/schemas.d.ts +576 -0
  29. package/dist/schemas.d.ts.map +1 -0
  30. package/dist/schemas.js +197 -0
  31. package/dist/schemas.js.map +1 -0
  32. package/dist/server.d.ts +13 -0
  33. package/dist/server.d.ts.map +1 -0
  34. package/dist/server.js +27 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/spawnCli.d.ts +28 -0
  37. package/dist/spawnCli.d.ts.map +1 -0
  38. package/dist/spawnCli.js +57 -0
  39. package/dist/spawnCli.js.map +1 -0
  40. package/dist/tools/analysis.d.ts +4 -0
  41. package/dist/tools/analysis.d.ts.map +1 -0
  42. package/dist/tools/analysis.js +128 -0
  43. package/dist/tools/analysis.js.map +1 -0
  44. package/dist/tools/auto.d.ts +4 -0
  45. package/dist/tools/auto.d.ts.map +1 -0
  46. package/dist/tools/auto.js +43 -0
  47. package/dist/tools/auto.js.map +1 -0
  48. package/dist/tools/edit.d.ts +3 -0
  49. package/dist/tools/edit.d.ts.map +1 -0
  50. package/dist/tools/edit.js +346 -0
  51. package/dist/tools/edit.js.map +1 -0
  52. package/dist/tools/project.d.ts +4 -0
  53. package/dist/tools/project.d.ts.map +1 -0
  54. package/dist/tools/project.js +58 -0
  55. package/dist/tools/project.js.map +1 -0
  56. package/dist/version.d.ts +3 -0
  57. package/dist/version.d.ts.map +1 -0
  58. package/dist/version.js +4 -0
  59. package/dist/version.js.map +1 -0
  60. package/package.json +67 -0
  61. package/spec/checks.md +313 -0
  62. package/spec/file-format.md +672 -0
package/spec/checks.md ADDED
@@ -0,0 +1,313 @@
1
+ # Checks and findings
2
+
3
+ Zenith checks every auto each time it changes. Each problem it finds is a **finding**: a code, a
4
+ severity, the step it belongs to, and a message. Where it can, a finding also says where along the
5
+ path it happened, and the editor marks that spot on the field.
6
+
7
+ The editor, the CLI and the MCP server run the same checks on the same files, so they always agree.
8
+
9
+ ## Severities
10
+
11
+ | severity | meaning |
12
+ |---|---|
13
+ | **error** | The auto is wrong: the robot would refuse the file, crash, break a rule or run out of time. `zenith validate` exits non-zero on any error. |
14
+ | **warning** | The auto will run, but probably not the way you want. Fix it or accept it knowingly. |
15
+ | **info** | Something worth knowing. Nothing needs to change. |
16
+
17
+ ## Reading findings
18
+
19
+ In the editor, click a finding's code chip to see what it means and how to fix it. Some findings
20
+ have a one-click fix.
21
+
22
+ On the command line, `--explain` prints the same help under each finding:
23
+
24
+ ```bash
25
+ zenith validate autos/first-auto.auto.json --explain
26
+ ```
27
+
28
+ `--json` prints the findings as JSON for scripts and agents.
29
+
30
+ ## All codes
31
+
32
+ | code | severity | what it means |
33
+ |---|---|---|
34
+ | [`SCHEMA`](#schema) | error | Something in a file is not allowed: a misspelled command, a missing value, a waypoint that does not exist. |
35
+ | [`CONTINUITY`](#continuity) | error | A path starts somewhere other than where the robot is. |
36
+ | [`HEADING_MISSING`](#heading_missing) | error | A path does not say which way the robot faces. |
37
+ | [`HEADING`](#heading) | warning or info | The robot will not face the way this path asks. |
38
+ | [`HEADING_RANGES`](#heading_ranges) | error | A piecewise heading's ranges do not cover the path from 0 to 1. |
39
+ | [`PERIMETER`](#perimeter) | error | Part of the robot would go past the field wall. |
40
+ | [`STRUCTURE`](#structure) | error | The robot's outline overlaps something solid on the field. |
41
+ | [`KEEPOUT`](#keepout) | warning | The robot drives into a zone the rules restrict during auto. |
42
+ | [`START_ILLEGAL`](#start_illegal) | error | The starting pose breaks a game rule. |
43
+ | [`LEGAL_APPROACH`](#legal_approach) | error | The robot shoots from a place the rules do not allow for its target. |
44
+ | [`TURRET_RANGE`](#turret_range) | warning | The turret cannot turn far enough to aim at the target. |
45
+ | [`CAPACITY`](#capacity) | error | The robot would hold more pieces than it can carry or the rules allow. |
46
+ | [`EMPTY_SHOT`](#empty_shot) | warning | A shoot step runs with nothing, or too little, to shoot. |
47
+ | [`STRAFE_FRACTION`](#strafe_fraction) | warning | Much of a path is driven sideways, which is slow on mecanum. |
48
+ | [`MOUTH_LEADING`](#mouth_leading) | warning | The intake is running but not facing the way the robot drives. |
49
+ | [`SWEEP_SPEED`](#sweep_speed) | warning | The robot drives too fast while its intake runs. |
50
+ | [`TIME_BUDGET`](#time_budget) | error, warning or info | The routine may not fit in the autonomous period. |
51
+ | [`TIMEOUT_TIGHT`](#timeout_tight) | info | A step's timeout is close to how long it should take. |
52
+ | [`STATIONARY_MARKER`](#stationary_marker) | warning | A stand-still command is set to fire while the robot moves. |
53
+ | [`MOVES_ROBOT`](#moves_robot) | error | A path assumes a fixed start after a command that moves the robot by itself. |
54
+ | [`PROVENANCE`](#provenance) | info | A pose has no note saying where its numbers came from. |
55
+
56
+ ## Codes in detail
57
+
58
+ ### `SCHEMA`
59
+
60
+ **File problem.** Error.
61
+
62
+ Something in the file is not allowed. The robot would refuse to load it. This covers:
63
+
64
+ - the file does not match its [JSON Schema](file-format.md#json-schemas);
65
+ - a command or condition name that `robot.json` does not list, or arguments that do not fit the
66
+ command's `params`;
67
+ - a `{ "ref": ... }` to a waypoint that `waypoints.json` does not have;
68
+ - a `wait` with both `seconds` and `until`, or with neither;
69
+ - a `parallel` group in `deadline` mode whose `deadline` names none of its own direct members.
70
+
71
+ **Fix.** Read the message for the exact key that is wrong. Pick the name from the list the editor
72
+ offers, or add the missing value.
73
+
74
+ ### `CONTINUITY`
75
+
76
+ **Path jumps.** Error.
77
+
78
+ A path starts somewhere other than where the robot is, so the robot would have to teleport. The
79
+ gap is measured from where the previous step ended, and anything over 0.5 in counts. Segments
80
+ inside one path must also meet within 0.5 in.
81
+
82
+ How "where the previous step ended" is worked out:
83
+
84
+ - a `sequence` chains its members like the top-level list;
85
+ - every member of a `parallel` group starts where the group started;
86
+ - the first step of each side of a `branch` starts where the branch started;
87
+ - `"from": "current"` is only allowed after a step that defines where the robot is.
88
+
89
+ **Fix.** Set the path's start to `"current"` so it begins wherever the robot is. Or drag its first
90
+ point onto the end of the step before it.
91
+
92
+ ### `HEADING_MISSING`
93
+
94
+ **No heading.** Error.
95
+
96
+ A path does not say which way the robot should face while it drives. Pedro, the path follower,
97
+ stops the auto with an error when a path has no heading.
98
+
99
+ **Fix.** Choose a heading mode in the path's inspector. `tangent`, which points the nose along the
100
+ path, is the usual choice.
101
+
102
+ ### `HEADING`
103
+
104
+ **Heading differs on the robot.** Warning or info.
105
+
106
+ The robot will not face the way this path asks. Two cases:
107
+
108
+ - **Warning:** a `linear` heading turns more than half a circle on one segment. Pedro turns each
109
+ segment's share of the sweep the short way round, so the robot goes the other way. The message
110
+ gives the turn the robot actually makes, in degrees, counter-clockwise positive.
111
+ - **Info:** a `facePoint` heading has a non-zero `offsetRad`. The robot runtime ignores the offset
112
+ for now. The editor still draws it.
113
+
114
+ Both apply inside a [`piecewise`](file-format.md#piecewise-heading) heading too, to a `linear` or
115
+ `facePoint` range; the finding's `t` is where the range starts.
116
+
117
+ **Fix.** Split the path so no piece turns more than half a circle, or set the heading at a waypoint
118
+ in between. For the info, set `offsetRad` to 0 or accept that the robot will face the point
119
+ directly.
120
+
121
+ ### `HEADING_RANGES`
122
+
123
+ **Heading ranges do not fit.** Error.
124
+
125
+ A [`piecewise`](file-format.md#piecewise-heading) heading must split its path into ranges that run
126
+ from `t` 0 to `t` 1 in order: the first starts at 0, each starts where the one before it ends, each
127
+ ends after it starts, and the last ends at 1. Pedro's piecewise interpolator stops the auto on the
128
+ robot when they do not, so the file cannot run. The message names the first range that is wrong and
129
+ how.
130
+
131
+ **Fix.** Drag the boundaries in the inspector's range track, or set each range's end, so each range
132
+ starts where the one before it ends. The editor's own range edits never leave a gap or an overlap;
133
+ this finding means the file was edited by hand.
134
+
135
+ ### `PERIMETER`
136
+
137
+ **Leaves the field.** Error.
138
+
139
+ Part of the robot, its body or an intake mouth, would go past the field wall at some point on the
140
+ path. A real robot would hit the wall instead. The check uses the robot's expanded footprint,
141
+ turned to its heading, plus every mouth.
142
+
143
+ **Fix.** Move the point away from the wall until the outline stays inside. Snapping to the wall
144
+ places the robot flush against it and never raises this finding.
145
+
146
+ ### `STRUCTURE`
147
+
148
+ **Hits a field element.** Error.
149
+
150
+ The robot's outline overlaps an obstacle marked `solidToRobot` in the field file, such as the hive
151
+ or a flower base. The robot would crash into it. Only obstacles that reach below the robot's height
152
+ count, so the robot can drive under a bar that is higher than it is. The footprint is checked every
153
+ 2 in along the path and at every segment end, mouths included. The finding names the obstacle and
154
+ marks where the overlap is deepest.
155
+
156
+ **Fix.** Move the path around the element, or add a point to bend it clear.
157
+
158
+ ### `KEEPOUT`
159
+
160
+ **Enters a no-go zone.** Warning.
161
+
162
+ The robot drives into a zone the game rules restrict during the autonomous period. That can cost a
163
+ penalty. Only zones marked `appliesInAuto: true` in the field file count.
164
+
165
+ **Fix.** Reroute the path so the outline stays out of the shaded zone. The zone's rule is named in
166
+ the message.
167
+
168
+ ### `START_ILLEGAL`
169
+
170
+ **Start not allowed.** Error.
171
+
172
+ The starting pose breaks a rule in the field's `startRules`: not touching a wall, starting in the
173
+ wrong half, starting in a loading zone, or touching a flower. The referees would not let the match
174
+ start like this.
175
+
176
+ **Fix.** Drag the start pose to a legal spot, usually flush against your own alliance's wall. Wall
177
+ snap helps.
178
+
179
+ ### `LEGAL_APPROACH`
180
+
181
+ **Shot from an illegal spot.** Error.
182
+
183
+ A command that launches pieces (one with `ledger.launches` in `robot.json`) runs where the target is
184
+ not legally approachable. For a BIOBUZZ hive cell, the robot must be outboard of the up cell's outer
185
+ face by the margin the field file gives, on the correct side. The scoring would not count or would
186
+ draw a penalty.
187
+
188
+ **Fix.** Move the shooting pose to the allowed side of the target. The one-click fix moves it to the
189
+ nearest legal spot.
190
+
191
+ ### `TURRET_RANGE`
192
+
193
+ **Turret cannot aim.** Warning.
194
+
195
+ At this shooting pose, the bearing to the target relative to the chassis is outside the turret's
196
+ `turretRangeRad` in `robot.json`. The robot would shoot in the wrong direction. Robots with no
197
+ turret never raise it.
198
+
199
+ **Fix.** Turn the robot so the target is closer to straight ahead, or move the shooting pose.
200
+
201
+ ### `CAPACITY`
202
+
203
+ **Holds too many.** Error.
204
+
205
+ The ledger says the robot would hold more pieces than `capacity.max` in `robot.json`, either at the
206
+ start or after a collect. Something would fall out or draw a penalty.
207
+
208
+ **Fix.** Shoot or drop pieces before collecting more, or collect fewer. The ledger panel shows what
209
+ the robot holds after each step.
210
+
211
+ ### `EMPTY_SHOT`
212
+
213
+ **Shooting nothing.** Warning.
214
+
215
+ A shoot step runs when the ledger says the robot holds nothing, or fewer pieces than the step
216
+ launches. It wastes time in the autonomous period.
217
+
218
+ **Fix.** Collect before shooting, or remove the shot. Check the ledger panel to see when the robot
219
+ is empty.
220
+
221
+ ### `STRAFE_FRACTION`
222
+
223
+ **Driving sideways.** Warning.
224
+
225
+ Too much of this path is driven sideways: the distance where the travel direction is closer to the
226
+ robot's side than to its nose is over the threshold (20 % by default, set by `strafeFractionWarn` in
227
+ `robot.json`). On mecanum wheels, sideways driving is slower and stops less sharply than driving
228
+ forward. The message says how many seconds it costs against driving the same leg nose-first.
229
+
230
+ **Fix.** Use the fix that points the nose along the path, or turn during the previous stop. Keep
231
+ sideways driving for short, deliberate moves, such as a sweep along a wall.
232
+
233
+ ### `MOUTH_LEADING`
234
+
235
+ **Intake not in front.** Warning.
236
+
237
+ An intake is running on this path, but its mouth is more than 30° away from the direction the robot
238
+ drives. The robot's body would push game pieces away instead of picking them up. The intake counts
239
+ as running when a marker turns it on, when an earlier `intakeOn` was never stopped, or when an
240
+ `intakeOn` runs in another member of the same `parallel` group.
241
+
242
+ **Fix.** Choose a heading that puts the running mouth in front: `tangent` for a front mouth,
243
+ `tangentReversed` for a back one.
244
+
245
+ ### `SWEEP_SPEED`
246
+
247
+ **Intaking too fast.** Warning.
248
+
249
+ The robot drives faster than `sweepSpeedFraction` in `robot.json` (0.4 by default) while its intake
250
+ runs. Pieces get knocked away rather than collected at that speed.
251
+
252
+ **Fix.** Lower this path's `speedFraction` to the sweep speed. The one-click fix does it for you.
253
+
254
+ ### `TIME_BUDGET`
255
+
256
+ **Over the time limit.** Error, warning or info.
257
+
258
+ The whole routine may take longer than the autonomous period (`periods.autoS` in the field file).
259
+ Anything after the buzzer does not happen. The estimate is a range, and the severity depends on
260
+ which end of it is over:
261
+
262
+ - **Error:** even the optimistic end of the range is over the period.
263
+ - **Warning:** the nominal estimate is over; only the optimistic end fits.
264
+ - **Info:** the routine fits, but some step has no fixed time. Either a step has no estimate at
265
+ all, so the total is a lower bound, or a step ends on a condition, so the total is an upper bound.
266
+
267
+ **Fix.** Cut or shorten steps, drive faster where it is safe, or move slow steps later. The timeline
268
+ shows which steps take the longest.
269
+
270
+ ### `TIMEOUT_TIGHT`
271
+
272
+ **Timeout too short.** Info.
273
+
274
+ This step's `timeoutS` is under 1.2 times its estimate. A slightly slow run would be cut off before
275
+ it finishes.
276
+
277
+ **Fix.** Raise the step's timeout to a little more than its estimate. The estimate is shown beside
278
+ the step.
279
+
280
+ ### `STATIONARY_MARKER`
281
+
282
+ **Stop-only command while moving.** Warning.
283
+
284
+ A marker fires a command that `robot.json` marks `stationary: true`, in the middle of a path. It
285
+ would run while the robot is still driving.
286
+
287
+ **Fix.** Make it its own `command` step after the path instead of a marker on it.
288
+
289
+ ### `MOVES_ROBOT`
290
+
291
+ **Start after a moving command.** Error.
292
+
293
+ The step before this one runs a command marked `movesRobot: true`, which drives the robot by itself,
294
+ so nobody knows exactly where it ends. This path starts from a fixed pose anyway.
295
+
296
+ **Fix.** Set this path's start to `"current"` so it begins wherever the robot really is.
297
+
298
+ ### `PROVENANCE`
299
+
300
+ **Where did this come from?** Info.
301
+
302
+ A pose has no provenance label saying where its numbers came from, such as measured on the field or
303
+ set in the editor. Inline poses the editor writes are treated as `SET FROM EDITOR`. This is only a
304
+ reminder, not an error. See [provenance labels](file-format.md#provenance-labels).
305
+
306
+ **Fix.** Nothing is required. Measure the pose on the field, or save it as a named waypoint with a
307
+ label, to record where it came from.
308
+
309
+ ## Checks that need an estimate
310
+
311
+ `STRAFE_FRACTION`, `TIME_BUDGET` and `TIMEOUT_TIGHT` use the time estimate. If an estimate cannot be
312
+ made, those three are skipped and every other check still runs. See [Simulation](simulation.md) for
313
+ how the estimate is made.