@fleetless/contracts 1.0.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 (287) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +17 -0
  4. package/README.md +88 -0
  5. package/artifacts/constants.json +24 -0
  6. package/artifacts/openapi.json +17219 -0
  7. package/artifacts/routes.json +4605 -0
  8. package/artifacts/schema/accept-team-invite-request.schema.json +22 -0
  9. package/artifacts/schema/action-config.schema.json +198 -0
  10. package/artifacts/schema/alert-list-response.schema.json +172 -0
  11. package/artifacts/schema/api-error.schema.json +20 -0
  12. package/artifacts/schema/app-auth-config.schema.json +106 -0
  13. package/artifacts/schema/app-invitation-list-response.schema.json +57 -0
  14. package/artifacts/schema/app-invitation.schema.json +69 -0
  15. package/artifacts/schema/app-list-response.schema.json +82 -0
  16. package/artifacts/schema/app-mail-template-list-response.schema.json +68 -0
  17. package/artifacts/schema/app-mail-template.schema.json +54 -0
  18. package/artifacts/schema/app-oidc-provider-list-response.schema.json +93 -0
  19. package/artifacts/schema/app-oidc-provider.schema.json +80 -0
  20. package/artifacts/schema/app-user-list-response.schema.json +111 -0
  21. package/artifacts/schema/app-user.schema.json +98 -0
  22. package/artifacts/schema/app.schema.json +69 -0
  23. package/artifacts/schema/apply-error.schema.json +41 -0
  24. package/artifacts/schema/asset-list-response.schema.json +288 -0
  25. package/artifacts/schema/asset-sync-request.schema.json +17 -0
  26. package/artifacts/schema/asset-sync-response.schema.json +16 -0
  27. package/artifacts/schema/asset-sync-status.schema.json +136 -0
  28. package/artifacts/schema/asset.schema.json +68 -0
  29. package/artifacts/schema/audit-actor.schema.json +32 -0
  30. package/artifacts/schema/audit-event.schema.json +119 -0
  31. package/artifacts/schema/audit-list-response.schema.json +144 -0
  32. package/artifacts/schema/audit-query.schema.json +79 -0
  33. package/artifacts/schema/auth-error.schema.json +23 -0
  34. package/artifacts/schema/auth-me-response.schema.json +99 -0
  35. package/artifacts/schema/auth-ok.schema.json +115 -0
  36. package/artifacts/schema/authorization-server-metadata.schema.json +80 -0
  37. package/artifacts/schema/bridge-asset-progress.schema.json +99 -0
  38. package/artifacts/schema/bridge-assets-available.schema.json +25 -0
  39. package/artifacts/schema/bridge-camera-state.schema.json +78 -0
  40. package/artifacts/schema/bridge-config-applied.schema.json +67 -0
  41. package/artifacts/schema/bridge-hello.schema.json +65 -0
  42. package/artifacts/schema/bridge-introspect.schema.json +114 -0
  43. package/artifacts/schema/bridge-job-lost.schema.json +22 -0
  44. package/artifacts/schema/bridge-job-update.schema.json +100 -0
  45. package/artifacts/schema/bridge-pong.schema.json +19 -0
  46. package/artifacts/schema/bridge-pressure.schema.json +292 -0
  47. package/artifacts/schema/bridge-state.schema.json +24 -0
  48. package/artifacts/schema/bridge-type-definitions.schema.json +169 -0
  49. package/artifacts/schema/busy-details.schema.json +115 -0
  50. package/artifacts/schema/camera-descriptor.schema.json +45 -0
  51. package/artifacts/schema/camera-list-response.schema.json +58 -0
  52. package/artifacts/schema/camera-source.schema.json +240 -0
  53. package/artifacts/schema/cancel-request.schema.json +20 -0
  54. package/artifacts/schema/client-accept-invitation-request.schema.json +35 -0
  55. package/artifacts/schema/client-auth.schema.json +18 -0
  56. package/artifacts/schema/client-cancel.schema.json +45 -0
  57. package/artifacts/schema/client-identity.schema.json +103 -0
  58. package/artifacts/schema/client-invoke.schema.json +45 -0
  59. package/artifacts/schema/client-login-request.schema.json +29 -0
  60. package/artifacts/schema/client-logout-request.schema.json +14 -0
  61. package/artifacts/schema/client-mcp-interaction-decision-response.schema.json +15 -0
  62. package/artifacts/schema/client-mcp-interaction.schema.json +59 -0
  63. package/artifacts/schema/client-oidc-callback-query.schema.json +28 -0
  64. package/artifacts/schema/client-oidc-exchange-request.schema.json +21 -0
  65. package/artifacts/schema/client-oidc-start-query.schema.json +36 -0
  66. package/artifacts/schema/client-password-reset-confirm-request.schema.json +22 -0
  67. package/artifacts/schema/client-password-reset-request.schema.json +24 -0
  68. package/artifacts/schema/client-provider-list-query.schema.json +17 -0
  69. package/artifacts/schema/client-provider-list-response.schema.json +34 -0
  70. package/artifacts/schema/client-publish.schema.json +40 -0
  71. package/artifacts/schema/client-refresh-request.schema.json +14 -0
  72. package/artifacts/schema/client-register-request.schema.json +44 -0
  73. package/artifacts/schema/client-resend-verification-request.schema.json +24 -0
  74. package/artifacts/schema/client-subscribe.schema.json +43 -0
  75. package/artifacts/schema/client-unsubscribe.schema.json +26 -0
  76. package/artifacts/schema/client-verify-email-request.schema.json +15 -0
  77. package/artifacts/schema/cloud-asset-request.schema.json +37 -0
  78. package/artifacts/schema/cloud-camera-start.schema.json +41 -0
  79. package/artifacts/schema/cloud-camera-stop.schema.json +26 -0
  80. package/artifacts/schema/cloud-cancel.schema.json +33 -0
  81. package/artifacts/schema/cloud-config.schema.json +1635 -0
  82. package/artifacts/schema/cloud-hello-error.schema.json +23 -0
  83. package/artifacts/schema/cloud-hello-ok.schema.json +19 -0
  84. package/artifacts/schema/cloud-introspect-request.schema.json +19 -0
  85. package/artifacts/schema/cloud-invoke.schema.json +40 -0
  86. package/artifacts/schema/cloud-ping.schema.json +19 -0
  87. package/artifacts/schema/cloud-publish.schema.json +28 -0
  88. package/artifacts/schema/cloud-type-request.schema.json +30 -0
  89. package/artifacts/schema/command-result.schema.json +175 -0
  90. package/artifacts/schema/config-draft-response.schema.json +1695 -0
  91. package/artifacts/schema/config-state.schema.json +124 -0
  92. package/artifacts/schema/config-version-response.schema.json +1641 -0
  93. package/artifacts/schema/config-versions-response.schema.json +33 -0
  94. package/artifacts/schema/create-app-invitation-request.schema.json +40 -0
  95. package/artifacts/schema/create-app-oidc-provider-request.schema.json +70 -0
  96. package/artifacts/schema/create-app-request.schema.json +30 -0
  97. package/artifacts/schema/create-app-user-request.schema.json +42 -0
  98. package/artifacts/schema/create-robot-request.schema.json +14 -0
  99. package/artifacts/schema/create-robot-response.schema.json +44 -0
  100. package/artifacts/schema/create-server-key-response.schema.json +65 -0
  101. package/artifacts/schema/create-team-invite-request.schema.json +43 -0
  102. package/artifacts/schema/datapoint-alert-row.schema.json +160 -0
  103. package/artifacts/schema/datapoint-config.schema.json +366 -0
  104. package/artifacts/schema/datapoint-display.schema.json +31 -0
  105. package/artifacts/schema/datapoint-event.schema.json +34 -0
  106. package/artifacts/schema/datapoint-frame.schema.json +28 -0
  107. package/artifacts/schema/datapoint-list-response.schema.json +61 -0
  108. package/artifacts/schema/datapoint-value.schema.json +28 -0
  109. package/artifacts/schema/developer-login-request.schema.json +19 -0
  110. package/artifacts/schema/dynamic-client-registration-request.schema.json +60 -0
  111. package/artifacts/schema/dynamic-client-registration-response.schema.json +68 -0
  112. package/artifacts/schema/error-frame.schema.json +23 -0
  113. package/artifacts/schema/exposure-counts.schema.json +39 -0
  114. package/artifacts/schema/exposure-list-response.schema.json +43 -0
  115. package/artifacts/schema/fetch-types-request.schema.json +19 -0
  116. package/artifacts/schema/fetch-types-response.schema.json +163 -0
  117. package/artifacts/schema/fleetless-user-list-response.schema.json +73 -0
  118. package/artifacts/schema/fleetless-user.schema.json +60 -0
  119. package/artifacts/schema/history-buckets-response.schema.json +79 -0
  120. package/artifacts/schema/history-query.schema.json +58 -0
  121. package/artifacts/schema/history-response.schema.json +150 -0
  122. package/artifacts/schema/history-samples-response.schema.json +68 -0
  123. package/artifacts/schema/introspection-response.schema.json +118 -0
  124. package/artifacts/schema/invoke-or-service-response.schema.json +141 -0
  125. package/artifacts/schema/invoke-request.schema.json +23 -0
  126. package/artifacts/schema/invoke-response.schema.json +125 -0
  127. package/artifacts/schema/job-actor.schema.json +34 -0
  128. package/artifacts/schema/job-event.schema.json +158 -0
  129. package/artifacts/schema/job-response.schema.json +123 -0
  130. package/artifacts/schema/job-run-list-response.schema.json +222 -0
  131. package/artifacts/schema/job-run-query.schema.json +95 -0
  132. package/artifacts/schema/job-run-summary-query.schema.json +23 -0
  133. package/artifacts/schema/job-run-summary.schema.json +33 -0
  134. package/artifacts/schema/job-run.schema.json +195 -0
  135. package/artifacts/schema/job-state.schema.json +11 -0
  136. package/artifacts/schema/job.schema.json +106 -0
  137. package/artifacts/schema/latency-bucket.schema.json +63 -0
  138. package/artifacts/schema/live-session-response.schema.json +41 -0
  139. package/artifacts/schema/mail-outcome.schema.json +20 -0
  140. package/artifacts/schema/mail-template-preview-request.schema.json +35 -0
  141. package/artifacts/schema/mail-template-preview-response.schema.json +31 -0
  142. package/artifacts/schema/mail-template-problem-details.schema.json +24 -0
  143. package/artifacts/schema/mcp-consent-grant-list-response.schema.json +52 -0
  144. package/artifacts/schema/mcp-consent-grant.schema.json +39 -0
  145. package/artifacts/schema/mcp-robot-datasheet.schema.json +115 -0
  146. package/artifacts/schema/mcp-role-preview-response.schema.json +134 -0
  147. package/artifacts/schema/missing-asset-query.schema.json +11 -0
  148. package/artifacts/schema/oauth-authorize-query.schema.json +47 -0
  149. package/artifacts/schema/oauth-redirect-response.schema.json +15 -0
  150. package/artifacts/schema/oauth-token-request.schema.json +47 -0
  151. package/artifacts/schema/oauth-token-response.schema.json +38 -0
  152. package/artifacts/schema/org-alerts-query.schema.json +15 -0
  153. package/artifacts/schema/org-event-dropped.schema.json +26 -0
  154. package/artifacts/schema/org-event-replay.schema.json +97 -0
  155. package/artifacts/schema/org-event-subscribe.schema.json +14 -0
  156. package/artifacts/schema/org-event-unsubscribe.schema.json +14 -0
  157. package/artifacts/schema/org-event.schema.json +75 -0
  158. package/artifacts/schema/org-firing-alerts-response.schema.json +178 -0
  159. package/artifacts/schema/org-health-query.schema.json +13 -0
  160. package/artifacts/schema/org-latency-query.schema.json +42 -0
  161. package/artifacts/schema/org-latency-response.schema.json +124 -0
  162. package/artifacts/schema/org-quota-usage-counts.schema.json +42 -0
  163. package/artifacts/schema/org-quota-usage.schema.json +102 -0
  164. package/artifacts/schema/org-quotas.schema.json +51 -0
  165. package/artifacts/schema/org-usage-query.schema.json +19 -0
  166. package/artifacts/schema/org-usage-response.schema.json +77 -0
  167. package/artifacts/schema/org.schema.json +30 -0
  168. package/artifacts/schema/parameter-invalid-details.schema.json +37 -0
  169. package/artifacts/schema/parameter-spec.schema.json +120 -0
  170. package/artifacts/schema/parameter-violation.schema.json +24 -0
  171. package/artifacts/schema/password-change-request.schema.json +21 -0
  172. package/artifacts/schema/password-reset-confirm.schema.json +19 -0
  173. package/artifacts/schema/password-reset-request.schema.json +14 -0
  174. package/artifacts/schema/patch-app-oidc-provider-request.schema.json +50 -0
  175. package/artifacts/schema/patch-app-user-request.schema.json +34 -0
  176. package/artifacts/schema/patch-auth-me-request.schema.json +22 -0
  177. package/artifacts/schema/patch-fleetless-user-request.schema.json +20 -0
  178. package/artifacts/schema/patch-org-request.schema.json +15 -0
  179. package/artifacts/schema/patch-org-response.schema.json +40 -0
  180. package/artifacts/schema/patch-robot-request.schema.json +15 -0
  181. package/artifacts/schema/patch-robot-response.schema.json +40 -0
  182. package/artifacts/schema/pending-team-invite-list-response.schema.json +52 -0
  183. package/artifacts/schema/pending-team-invite.schema.json +39 -0
  184. package/artifacts/schema/protected-resource-metadata.schema.json +41 -0
  185. package/artifacts/schema/publish-config-response.schema.json +21 -0
  186. package/artifacts/schema/publish-request.schema.json +17 -0
  187. package/artifacts/schema/publisher-config.schema.json +285 -0
  188. package/artifacts/schema/put-app-auth-config-request.schema.json +93 -0
  189. package/artifacts/schema/put-app-mail-template-request.schema.json +35 -0
  190. package/artifacts/schema/put-config-draft-request.schema.json +13 -0
  191. package/artifacts/schema/put-datapoint-display-request.schema.json +31 -0
  192. package/artifacts/schema/put-robot-details-request.schema.json +41 -0
  193. package/artifacts/schema/put-robot-details-response.schema.json +43 -0
  194. package/artifacts/schema/rate-limit-details.schema.json +15 -0
  195. package/artifacts/schema/refresh-request.schema.json +13 -0
  196. package/artifacts/schema/release-live-query.schema.json +13 -0
  197. package/artifacts/schema/rename-slug-request.schema.json +23 -0
  198. package/artifacts/schema/rename-slug-response.schema.json +24 -0
  199. package/artifacts/schema/resource-health-event.schema.json +72 -0
  200. package/artifacts/schema/resource-health-list-response.schema.json +80 -0
  201. package/artifacts/schema/resource-health-state.schema.json +68 -0
  202. package/artifacts/schema/robot-config-doc.schema.json +1616 -0
  203. package/artifacts/schema/robot-delete-query.schema.json +12 -0
  204. package/artifacts/schema/robot-deletion-summary.schema.json +63 -0
  205. package/artifacts/schema/robot-detail-response.schema.json +262 -0
  206. package/artifacts/schema/robot-details-doc.schema.json +33 -0
  207. package/artifacts/schema/robot-jobs-response.schema.json +119 -0
  208. package/artifacts/schema/robot-latency-series.schema.json +81 -0
  209. package/artifacts/schema/robot-list-item.schema.json +94 -0
  210. package/artifacts/schema/robot-list-response.schema.json +106 -0
  211. package/artifacts/schema/robot.schema.json +30 -0
  212. package/artifacts/schema/role-list-response.schema.json +48 -0
  213. package/artifacts/schema/role-permissions.schema.json +61 -0
  214. package/artifacts/schema/role.schema.json +35 -0
  215. package/artifacts/schema/ros-graph.schema.json +99 -0
  216. package/artifacts/schema/server-key-list-response.schema.json +64 -0
  217. package/artifacts/schema/server-key.schema.json +51 -0
  218. package/artifacts/schema/service-call-response.schema.json +13 -0
  219. package/artifacts/schema/service-config.schema.json +198 -0
  220. package/artifacts/schema/session-tokens.schema.json +28 -0
  221. package/artifacts/schema/sign-up-request.schema.json +26 -0
  222. package/artifacts/schema/sign-up-response.schema.json +127 -0
  223. package/artifacts/schema/slug-usage-response.schema.json +32 -0
  224. package/artifacts/schema/snapshot-header.schema.json +44 -0
  225. package/artifacts/schema/snapshot-meta-response.schema.json +85 -0
  226. package/artifacts/schema/subscribe-error.schema.json +31 -0
  227. package/artifacts/schema/team-invite.schema.json +57 -0
  228. package/artifacts/schema/tier-change-request.schema.json +17 -0
  229. package/artifacts/schema/type-definition.schema.json +144 -0
  230. package/artifacts/schema/types-response.schema.json +156 -0
  231. package/artifacts/schema/update-app-request.schema.json +32 -0
  232. package/artifacts/schema/urdf-completeness.schema.json +50 -0
  233. package/artifacts/schema/validation-issue.schema.json +43 -0
  234. package/artifacts/schema/waitlist-request.schema.json +15 -0
  235. package/artifacts/schema-outgoing/bridge-asset-progress.schema.json +102 -0
  236. package/artifacts/schema-outgoing/bridge-assets-available.schema.json +26 -0
  237. package/artifacts/schema-outgoing/bridge-camera-state.schema.json +80 -0
  238. package/artifacts/schema-outgoing/bridge-config-applied.schema.json +69 -0
  239. package/artifacts/schema-outgoing/bridge-hello.schema.json +68 -0
  240. package/artifacts/schema-outgoing/bridge-introspect.schema.json +119 -0
  241. package/artifacts/schema-outgoing/bridge-job-lost.schema.json +23 -0
  242. package/artifacts/schema-outgoing/bridge-job-update.schema.json +102 -0
  243. package/artifacts/schema-outgoing/bridge-pong.schema.json +20 -0
  244. package/artifacts/schema-outgoing/bridge-type-definitions.schema.json +174 -0
  245. package/artifacts/schema-outgoing/datapoint-frame.schema.json +29 -0
  246. package/artifacts/schema-outgoing/snapshot-header.schema.json +45 -0
  247. package/dist/alerts.d.ts +255 -0
  248. package/dist/alerts.js +193 -0
  249. package/dist/app-users.d.ts +606 -0
  250. package/dist/app-users.js +696 -0
  251. package/dist/apps.d.ts +175 -0
  252. package/dist/apps.js +267 -0
  253. package/dist/assets.d.ts +434 -0
  254. package/dist/assets.js +546 -0
  255. package/dist/audit.d.ts +129 -0
  256. package/dist/audit.js +238 -0
  257. package/dist/client-auth.d.ts +409 -0
  258. package/dist/client-auth.js +487 -0
  259. package/dist/common.d.ts +186 -0
  260. package/dist/common.js +199 -0
  261. package/dist/config-issues.d.ts +175 -0
  262. package/dist/config-issues.js +339 -0
  263. package/dist/config.d.ts +862 -0
  264. package/dist/config.js +1988 -0
  265. package/dist/errors.d.ts +52 -0
  266. package/dist/errors.js +786 -0
  267. package/dist/identity.d.ts +549 -0
  268. package/dist/identity.js +503 -0
  269. package/dist/index.d.ts +51 -0
  270. package/dist/index.js +51 -0
  271. package/dist/introspection.d.ts +99 -0
  272. package/dist/introspection.js +97 -0
  273. package/dist/jobs.d.ts +334 -0
  274. package/dist/jobs.js +345 -0
  275. package/dist/mcp.d.ts +239 -0
  276. package/dist/mcp.js +153 -0
  277. package/dist/oauth.d.ts +344 -0
  278. package/dist/oauth.js +488 -0
  279. package/dist/protocol.d.ts +781 -0
  280. package/dist/protocol.js +715 -0
  281. package/dist/realtime.d.ts +494 -0
  282. package/dist/realtime.js +512 -0
  283. package/dist/rest.d.ts +1989 -0
  284. package/dist/rest.js +1963 -0
  285. package/dist/routes.d.ts +94 -0
  286. package/dist/routes.js +2298 -0
  287. package/package.json +61 -0
@@ -0,0 +1,503 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { z } from 'zod';
3
+ /**
4
+ * **Fleetless users: the org's team, and the only people who reach the
5
+ * console** (spec `2026-09-05-app-user-auth`, D1).
6
+ *
7
+ * There are two identity spaces now and **nothing joins them**:
8
+ *
9
+ * - *Fleetless users*, this file. The people who configure robots in the
10
+ * console. Email globally unique, tier `owner | developer`, a Fleetless
11
+ * password, login through the auth portal. They always have MCP access, at
12
+ * the one central endpoint.
13
+ * - *app users*, `app-users.ts`. The people who use a developer's app. One app
14
+ * each, email unique per app, authenticated through the JSON client-auth
15
+ * API that the developer's own UI calls.
16
+ *
17
+ * A Fleetless user who wants to use an app registers or is invited like
18
+ * anybody else; there is no path from one space to the other.
19
+ *
20
+ * **What that deleted, with no successor** (D1): groups and the Org Admins
21
+ * group, app assignments, impersonation, the per-user MCP override and the
22
+ * org-level federation policy. The 2026-08-29 model had put developers and end
23
+ * users into one pool per org and connected them with all of the above; in use
24
+ * it turned out to model the wrong thing — the two populations have different
25
+ * lifecycles, and every mechanism joining them was cost without a product
26
+ * reason.
27
+ *
28
+ * What did **not** change: the password rules, the session and token shapes,
29
+ * and the enumeration-oracle reasoning on password reset. None of those was
30
+ * ever a statement about which space a person lived in.
31
+ *
32
+ * **Email is globally unique here** — `lower(email)` unique across all orgs, so
33
+ * one address is exactly one Fleetless user in exactly one org. Every shape
34
+ * that identifies a person by a bare address (`developerLoginRequest`,
35
+ * `passwordResetRequest`) therefore resolves to at most one account with no org
36
+ * context needed. App users are the opposite and say so on their own shape:
37
+ * unique **per app**, so one address may be several unrelated app accounts.
38
+ */
39
+ /**
40
+ * The password rule, stated once so the cloud, the console and the SDK refuse
41
+ * the same inputs for the same reason. Length only: a rule a user cannot
42
+ * predict is a rule they work around.
43
+ *
44
+ * Shared by both identity spaces on purpose. A weaker rule for app users would
45
+ * be a second policy for one decision, and the weaker one always wins by
46
+ * accident.
47
+ */
48
+ export const password = z.string().min(12).max(256);
49
+ /** The bound on a Fleetless user's display name; `APP_USER_DISPLAY_NAME_MAX` matches it, so a rename cannot be legal in one space and refused in the other. */
50
+ export const USER_DISPLAY_NAME_MAX = 120;
51
+ /**
52
+ * **The two tiers a Fleetless user can hold** (D1). Owner-exclusive: delete
53
+ * the org, edit org settings, promote to owner, and later billing. Everything
54
+ * else a Fleetless user may do, a `developer` may do.
55
+ *
56
+ * `member` was renamed to `developer` in the 2026-08-29 redesign and is **not**
57
+ * accepted as an alias anywhere — a wire that took both would leave two names
58
+ * for one tier in every log, every audit detail and every console fixture, and
59
+ * the older one would keep arriving forever.
60
+ *
61
+ * **Every Fleetless user has one.** It used to be optional, because the pool
62
+ * also held people who were not org admins and had no console powers to grade.
63
+ * That pool is gone: a Fleetless user *is* a member of the team, so the field
64
+ * is required and an absent one is a mapper bug rather than a state.
65
+ */
66
+ export const orgAdminTier = z.enum(['owner', 'developer']);
67
+ export const org = z.object({
68
+ id: z.uuid().meta({
69
+ description: 'The organisation. Every developer route is scoped to the caller\'s org already, so a client rarely has to send this anywhere.',
70
+ }),
71
+ name: z.string().min(1).max(120).meta({
72
+ description: 'The organisation\'s display name. Free text, changed through `PATCH /api/org`.',
73
+ }),
74
+ created_at: z.iso.datetime().meta({
75
+ description: 'When the organisation was created, as an ISO 8601 timestamp.',
76
+ }),
77
+ });
78
+ /** What `PATCH /api/org` answers: the org as it now stands. */
79
+ export const patchOrgResponse = z.object({
80
+ org: org.meta({
81
+ description: 'The organisation as it now stands, after the patch was applied. The whole resource comes back, not only the fields that changed.',
82
+ }),
83
+ });
84
+ /**
85
+ * **A member of the org's team.** Console access, a tier, a Fleetless
86
+ * password, and no relationship whatsoever to any app's users.
87
+ *
88
+ * `email` is **globally unique** — `lower(email)` unique across every org, a
89
+ * constraint the cloud enforces in the database; a schema cannot see two rows
90
+ * at once and this one makes no claim to. One address is one Fleetless user:
91
+ * no two orgs may hold the same one.
92
+ *
93
+ * **What this shape lost with the two-space cut**: `group_id` (there are no
94
+ * groups), `mcp_access` (a Fleetless user always has MCP access, at the
95
+ * central endpoint), and `has_password`. The last is the interesting one — it
96
+ * existed because a pool user might have been provisioned by an identity
97
+ * provider and hold no Fleetless credential. A Fleetless user always holds
98
+ * one: the console is password-only by design (D1), which removes the
99
+ * IdP-lockout class entirely, so a field reporting whether the credential
100
+ * exists would have exactly one value forever.
101
+ */
102
+ export const fleetlessUser = z.object({
103
+ id: z.uuid().meta({
104
+ description: 'The Fleetless user in the API, assigned by the cloud and stable for the life of the account.',
105
+ }),
106
+ org_id: z.uuid().meta({
107
+ description: 'The organisation this person belongs to. Every developer route is already scoped to the caller\'s org, so this confirms what a client is looking at rather than being a filter it applies.',
108
+ }),
109
+ email: z.email().meta({
110
+ description: 'The address the account is identified by, **globally unique** across every organisation. Immutable after creation: it is what every invitation, reset link and audit line names.',
111
+ }),
112
+ display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().meta({
113
+ description: 'Optional human name, shown by the console instead of the address where present. Self-service through `PATCH /api/auth/me`; never used for authentication. `null` when the person never supplied one.',
114
+ }),
115
+ tier: orgAdminTier.meta({
116
+ description: 'The console powers this person holds. **Required** — every Fleetless user is a member of the team and has a tier; the optional version of this field existed only while the org also held people with no console powers to grade, and that pool is gone.',
117
+ }),
118
+ created_at: z.iso.datetime().meta({
119
+ description: 'When the account was created, as an ISO 8601 timestamp.',
120
+ }),
121
+ });
122
+ /** `GET /api/org/users` — the whole team. Never null: an org always has at least its owner. */
123
+ export const fleetlessUserListResponse = z.object({
124
+ users: z.array(fleetlessUser).meta({
125
+ description: 'Every Fleetless user of the caller\'s organisation. This is the team, not an app\'s users — those are listed per app.',
126
+ }),
127
+ });
128
+ /**
129
+ * Access plus refresh (spec §3.4). The access token is short-lived; the
130
+ * refresh token rotates on every use, so a stolen one is detectable when the
131
+ * original is presented again.
132
+ *
133
+ * One shape for both identity spaces: a session is a session, and the claims
134
+ * inside the token are what differ.
135
+ */
136
+ export const sessionTokens = z.object({
137
+ access_token: z.string().min(1).meta({
138
+ description: 'The token to send as `Authorization: Bearer <token>` on every call. Short-lived: read `expires_in` rather than assuming a lifetime.',
139
+ }),
140
+ refresh_token: z.string().min(1).meta({
141
+ description: 'The token that buys the next access token. It rotates on every use, so a value presented twice is detectable theft and ends the whole family.',
142
+ }),
143
+ expires_in: z.number().int().positive().meta({
144
+ description: 'How long the access token stays valid, in **seconds** from now. Not a timestamp, and not milliseconds.',
145
+ }),
146
+ });
147
+ export const refreshRequest = z.object({ refresh_token: z.string().min(1) });
148
+ /**
149
+ * Registering an org creates the org and its first owner in one step
150
+ * (André, 2026-08-10): whoever registers the organisation is the owner.
151
+ */
152
+ export const signUpRequest = z.object({
153
+ org_name: z.string().min(1).max(120),
154
+ email: z.email(),
155
+ password,
156
+ });
157
+ /**
158
+ * Registering answers with the founding **Fleetless user**, tier `owner`.
159
+ *
160
+ * The key is `user` rather than `member` or `owner`, and it has stayed `user`
161
+ * through two identity redesigns deliberately: a renamed shape under a
162
+ * renamed key would typecheck in every consumer that reads `.user.id` and mean
163
+ * something subtly different, which is the quietest way for a cut like this to
164
+ * go wrong.
165
+ */
166
+ export const signUpResponse = z.object({
167
+ org,
168
+ user: fleetlessUser,
169
+ tokens: sessionTokens,
170
+ });
171
+ /**
172
+ * The landing page's waiting list (public site, 2026-09-04): one address,
173
+ * posted from fleetless.dev while sign-up is closed. The route answers
174
+ * `202` whether or not the address was already listed.
175
+ *
176
+ * The address is bounded at 254 characters, the RFC 5321 forward-path limit.
177
+ * `z.email()` alone is length-unbounded, and `waitlist.email` carries a unique
178
+ * btree index, which raises above roughly 2704 bytes — so an unbounded address
179
+ * turns an unauthenticated public route into a `500`.
180
+ */
181
+ export const waitlistRequest = z.object({ email: z.email().max(254) });
182
+ /**
183
+ * Console login. Fleetless users only, always the Fleetless password — the
184
+ * console has no federated door at all (D1), which removes the IdP-lockout
185
+ * class entirely.
186
+ *
187
+ * This resolves a person by address alone, and a Fleetless user's email is
188
+ * **globally unique**, so a bare address names at most one account and no org
189
+ * context is needed to disambiguate. An org selector was never needed and
190
+ * would have told an unauthenticated caller which org an address belongs to.
191
+ *
192
+ * **It cannot be reached by an app user**, whatever their address: the two
193
+ * spaces have separate tables and separate routes, and a credential from one
194
+ * never authenticates the other.
195
+ */
196
+ export const developerLoginRequest = z.object({
197
+ email: z.email(),
198
+ password: z.string().min(1),
199
+ });
200
+ /**
201
+ * What happened to the mail, in four words instead of one (W6c).
202
+ *
203
+ * `mail_sent: boolean` could not tell **"we have no SMTP configured"** from
204
+ * **"we tried and the server refused"**, so the console had to pick a sentence
205
+ * for a cause it could not know — and picked the reassuring one, because a
206
+ * link-only invitation is a normal outcome and a bounced one is not. The two
207
+ * need opposite actions from whoever reads them: configure a mail server, or
208
+ * go and look at why the existing one rejected the message.
209
+ *
210
+ * - `sent` — the SMTP server accepted the message. Not "delivered":
211
+ * no sender can promise that, and this value must never
212
+ * be rendered as if it could.
213
+ * - `not_requested` — no mail was attempted: the caller asked for none
214
+ * (`send_mail: false`), or there was no link for one to
215
+ * carry (the app has configured no `invite_url`, which
216
+ * the `null` `accept_url` beside it says). **A fourth
217
+ * word rather than a reuse of `not_configured`**: the
218
+ * deployment's mailer is irrelevant in both cases, and a
219
+ * console reading "mail server not configured" beside an
220
+ * invitation whose mail checkbox was off would send a
221
+ * developer to fix something that is not broken.
222
+ * - `not_configured` — no SMTP is set up. **An expected state, not a failure**
223
+ * (invitations work without mail; the link is the primary
224
+ * path). The console must not show it as an error.
225
+ * - `failed` — SMTP was configured, was tried, and refused or was
226
+ * unreachable. This one is worth someone's attention.
227
+ *
228
+ * Shared with `appInvitation`, which answers the same four facts about the
229
+ * same mailer.
230
+ */
231
+ export const mailStatus = z.enum(['sent', 'not_requested', 'not_configured', 'failed']);
232
+ /* ----------------------------------------------------- the team invite --
233
+ * One invitation family, for Fleetless users. The app-user invitation lives in
234
+ * `app-users.ts` and is a different thing with a different link: this one
235
+ * points at the Fleetless auth portal, that one points into the developer's
236
+ * own app.
237
+ */
238
+ /**
239
+ * **Inviting somebody onto the team** — the only way a Fleetless user appears.
240
+ *
241
+ * `tier` is **required**, and that is the one decision this shape exists to
242
+ * force. An optional tier would make *"I did not think about it"* and *"I meant
243
+ * developer"* the same request, on the field that decides who can remove whom.
244
+ * Inviting an owner is owner-only, checked by the route: the response hands
245
+ * back the accept link, so an owner-tier invitation is a promotion with one
246
+ * extra step.
247
+ */
248
+ export const createTeamInviteRequest = z
249
+ .object({
250
+ email: z.email().meta({
251
+ description: 'The address to invite. Globally unique across Fleetless users, so an address already on another org\'s team is refused with `email_taken`.',
252
+ }),
253
+ display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().optional().meta({
254
+ description: 'An optional name to pre-fill the account with; the invitee can change it afterwards.',
255
+ }),
256
+ tier: orgAdminTier.meta({
257
+ description: 'The tier the invitee holds on acceptance. **Required, not defaulted** — "I did not think about it" and "I meant developer" would otherwise be the same request, on the field that decides who can remove whom. Inviting an owner requires the owner tier.',
258
+ }),
259
+ send_mail: z.boolean().meta({
260
+ description: 'Whether Fleetless mails the invitation. The link in the answer is the primary path either way: a deployment with no SMTP still issues invitations and says so through `mail`.',
261
+ }),
262
+ })
263
+ .strict();
264
+ /**
265
+ * The invitation as issued. The **link is the primary path** and mail is the
266
+ * second, so this is complete and usable with `mail: 'not_configured'` — a
267
+ * deployment with no SMTP still issues invitations, it just cannot send them
268
+ * and says so.
269
+ */
270
+ export const teamInvite = z.object({
271
+ id: z.uuid().meta({ description: 'The invitation, as listed and revoked by the team.' }),
272
+ email: z.email().meta({ description: 'The address the invitation was addressed to.' }),
273
+ tier: orgAdminTier.meta({ description: 'The tier the invitee holds on acceptance, fixed when the invitation was created.' }),
274
+ expires_at: z.iso.datetime().meta({ description: 'When the token stops working. Seven days from issue; an expired token answers exactly as an unknown one does.' }),
275
+ accept_url: z.url().max(500).meta({
276
+ description: 'The link to give the invitee, on the Fleetless auth portal. Bounded like `idpIssuer`: an unbounded URL on a shape that gets mailed, logged and rendered is a size nobody chose. Unlike an app invitation\'s link this is never `null` — the portal is a page Fleetless does serve.',
277
+ }),
278
+ mail: mailStatus.meta({ description: 'What happened to the mail. `not_configured` is an expected state and not a failure; the link above is the primary path.' }),
279
+ });
280
+ /**
281
+ * A pending invitation as the team sees it in the list — **without its
282
+ * `accept_url`**, and that omission is the point.
283
+ *
284
+ * The list exists so a team can see what is outstanding and revoke it. Neither
285
+ * needs the token, and a list that carries it turns every screenshot, every log
286
+ * line and every browser history entry of that page into live credentials for
287
+ * somebody else's account. It is the same rule `auditEvent.details` already
288
+ * states — never credentials, never tokens — applied to a read surface.
289
+ *
290
+ * There is no escalation either way: an owner can already create an invitation
291
+ * for any address. The reason to withhold it is not what an owner could do with
292
+ * it, but that a page nobody thinks of as sensitive stops being sensitive.
293
+ *
294
+ * `mail` is omitted for a duller reason: it described what happened at creation
295
+ * time, and re-serving it in a list invites a reader to take it as current.
296
+ */
297
+ export const pendingTeamInvite = z.object({
298
+ id: z.uuid().meta({ description: 'The invitation, as revoked and re-issued by the team.' }),
299
+ email: z.email().meta({ description: 'The address the invitation was addressed to.' }),
300
+ tier: orgAdminTier.meta({ description: 'The tier the invitee would hold. Visible so an owner can spot an owner-tier invitation they did not authorise.' }),
301
+ expires_at: z.iso.datetime().meta({ description: 'When the token stops working.' }),
302
+ });
303
+ export const pendingTeamInviteListResponse = z.object({
304
+ invitations: z.array(pendingTeamInvite).meta({
305
+ description: 'Pending invitations only. An accepted invitation is history, not something to revoke.',
306
+ }),
307
+ });
308
+ /** Accepting it: the token proves the invitation, the password creates the login. */
309
+ export const acceptTeamInviteRequest = z
310
+ .object({
311
+ token: z.string().min(1).meta({
312
+ description: 'The opaque invitation token from the link. Unknown, expired and already-accepted all collapse into `410 token_spent` — telling them apart would say whether a token ever existed.',
313
+ }),
314
+ password: password.meta({
315
+ description: 'The password the new Fleetless account will use. At least 12 characters.',
316
+ }),
317
+ })
318
+ .strict();
319
+ /**
320
+ * `PATCH /api/org/users/:id` — **what an admin may change about a team member,
321
+ * and the two things that are absent rather than merely un-required.**
322
+ *
323
+ * `email` is not here. It is the identifier of the account, the value every
324
+ * invitation, reset link and audit line names, and a PATCH that could change it
325
+ * is both an account-takeover surface and a uniqueness race. *Immutable after
326
+ * create* is a sentence a strict schema can actually keep: offering `email` is
327
+ * a refusal, not a silently ignored field — which is the failure mode this
328
+ * project has already paid for once (`toHaveBeenCalledWith` could not tell
329
+ * *field sent* from *field missing*).
330
+ *
331
+ * `tier` is not here either. A tier change is owner-only with a last-owner
332
+ * guard (`tierChangeRequest`), and merging it in would give one route two
333
+ * refusal reasons and one audit event.
334
+ *
335
+ * So exactly one field remains, and the shape is kept rather than collapsed
336
+ * into a bare string: the next thing a team member gains will be optional here,
337
+ * and a route whose body is a naked value has nowhere to put it.
338
+ */
339
+ export const patchFleetlessUserRequest = z
340
+ .object({
341
+ display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable().optional().meta({
342
+ description: 'The member\'s display name. Absent leaves it alone; an explicit `null` clears it.',
343
+ }),
344
+ })
345
+ .strict();
346
+ /**
347
+ * `PUT /api/org/users/:id/tier` — **owner-only, and the last owner is
348
+ * neither demotable nor deletable** (refused with 409 `last_owner`).
349
+ *
350
+ * `tier_required` keeps its exact semantics — it says what the *caller's* tier
351
+ * is and what was needed, and nothing about the target.
352
+ */
353
+ export const tierChangeRequest = z.object({ tier: orgAdminTier }).strict();
354
+ /**
355
+ * What a `forbidden` refusal carries when the reason is the caller's **tier**
356
+ * rather than a missing grant (W6c).
357
+ *
358
+ * §3.3 makes `forbidden` deliberately silent about *existence*, and that stays
359
+ * true — this says nothing about what the target is. But "your role does not
360
+ * permit this" and "there is no such thing" are the same answer today, and a
361
+ * developer cannot tell *ask an owner* from *you have the wrong id*. Naming
362
+ * the required tier reveals only what the caller could read off the docs.
363
+ */
364
+ export const tierRequiredDetails = z.object({
365
+ required: orgAdminTier,
366
+ /** The caller's own tier — theirs to know, and it is what makes the message actionable. */
367
+ actual: orgAdminTier,
368
+ });
369
+ /**
370
+ * Changing your own password while logged in.
371
+ *
372
+ * `current_password` is required even though the session already proves
373
+ * identity: it is what makes a stolen *session* insufficient to take the
374
+ * *account*. Every other session is revoked on success; the one that made the
375
+ * change survives, because logging someone out of the tab they just used is
376
+ * indistinguishable from the change having failed.
377
+ *
378
+ * Shared with the app-user surface (`POST /api/client/password/change`): the
379
+ * argument is about credentials and sessions, not about which space the person
380
+ * lives in.
381
+ */
382
+ export const passwordChangeRequest = z.object({
383
+ current_password: z.string().min(1).meta({
384
+ description: 'The password in use right now. It is required even though the session already proves identity: it is what makes a stolen *session* insufficient to take the *account*.',
385
+ }),
386
+ new_password: password.meta({
387
+ description: 'The replacement password. Every other session is revoked when it is accepted, while the session that made the change survives — logging somebody out of the tab they just used is indistinguishable from the change having failed.',
388
+ }),
389
+ });
390
+ /**
391
+ * Asking for a reset link, **as a Fleetless user**.
392
+ *
393
+ * **The response never says whether the address exists.** It is unauthenticated
394
+ * and would otherwise be an account-enumeration oracle — the one place where
395
+ * §3.3's "reveal nothing about what exists" is not a preference but the whole
396
+ * point. So this answers the same way for a known and an unknown address, in
397
+ * status, body **and timing**, and any consumer that renders "no such account"
398
+ * from it has reintroduced the oracle.
399
+ *
400
+ * A bare address resolves to at most one account: a Fleetless user's email is
401
+ * **globally unique**, so the reset mails the one match, if any, with a token
402
+ * bound to that account.
403
+ *
404
+ * The app-user equivalent is `clientPasswordResetRequest` in `client-auth.ts`
405
+ * and carries an `app_identifier`, because on that surface a person is
406
+ * identified by app *and* address. Two shapes rather than one, because the two
407
+ * surfaces identify a person differently — not because the reasoning differs.
408
+ */
409
+ export const passwordResetRequest = z.object({
410
+ email: z.email(),
411
+ });
412
+ /**
413
+ * Using the link. The token is **single-use and expires**; spending it revokes
414
+ * every session of that subject, because a forgotten password is one of the
415
+ * two states where somebody else may be holding one. `token_spent` covers used
416
+ * and expired alike — telling them apart tells a stranger whether a token ever
417
+ * existed.
418
+ */
419
+ export const passwordResetConfirm = z.object({
420
+ token: z.string().min(1),
421
+ new_password: password,
422
+ });
423
+ /**
424
+ * An IdP issuer URL — **an attacker-supplied string that decides where the
425
+ * *server* connects.**
426
+ *
427
+ * `redirectUri` in `oauth.ts` got a parsed scheme check and an explicit
428
+ * loopback allow-list, with the reasoning written down, because it decides
429
+ * where a *credential* goes. This field got `z.url()` — in the same file, in
430
+ * the same wave. Argus-W7b found it and stored `file:///etc/passwd`,
431
+ * `http://169.254.169.254/latest/meta-data` and `http://infra-postgres-1:5432`
432
+ * through the app's IdP route, then caught the outbound discovery fetch on a
433
+ * listener he stood up. **That is this project's own question — which rules
434
+ * have we already written down, and where else do they apply — answered badly,
435
+ * one field over.**
436
+ *
437
+ * **What this shape can decide, it now decides:** http(s) only (so no `file:`,
438
+ * `gopher:`, `data:`), no credentials in the URL, no fragment, no query. RFC
439
+ * 8414 §3 builds the discovery URL from the issuer's path, so a query string
440
+ * there is meaningless and a `@` is a redirect trick.
441
+ *
442
+ * **What it cannot decide, stated rather than implied:** it cannot tell
443
+ * `http://localhost:8081/realms/fleetless-test` — the dev IdP this project
444
+ * ships — from `http://127.0.0.1:5432`. Both are loopback http. So **this is
445
+ * not the SSRF defence and must not be mistaken for one.** The defence belongs
446
+ * at the fetch, in the cloud: refuse loopback, link-local and private ranges
447
+ * unless something explicitly opts in for development, and it names DNS
448
+ * rebinding as its own residual. A schema that quietly looked sufficient here
449
+ * would be worse than one that says where the real check has to live.
450
+ *
451
+ * It lives in this file rather than beside its one consumer because it is a
452
+ * rule about URLs the server dereferences, and the next such field should find
453
+ * it already written down. `appOidcProvider` is that consumer today.
454
+ */
455
+ export const idpIssuer = z
456
+ .url()
457
+ .max(500)
458
+ .refine((v) => {
459
+ let url;
460
+ try {
461
+ url = new URL(v);
462
+ }
463
+ catch {
464
+ return false;
465
+ }
466
+ if (!['http:', 'https:'].includes(url.protocol))
467
+ return false;
468
+ if (url.username !== '' || url.password !== '')
469
+ return false;
470
+ if (url.hash !== '' || url.search !== '')
471
+ return false;
472
+ return url.hostname.length > 0;
473
+ }, { message: 'issuer must be an http(s) URL with no credentials, query or fragment' });
474
+ /**
475
+ * **The federated callback error vocabulary is deleted, with no successor
476
+ * here.** `oidcCallbackErrorCode` and `oidcCallbackError` described the page
477
+ * `GET /mcp/oauth/idp-callback` rendered when a group's identity provider sent
478
+ * a browser back — `jit_disabled` and `email_collision` name provisioning steps
479
+ * only a group provider had. D1 makes Fleetless users password-only and deletes
480
+ * group providers, so the flow that produced these codes cannot start; the
481
+ * route is gone from this manifest and from the cloud.
482
+ *
483
+ * The per-app OIDC vocabulary is `clientOidcErrorCode` in `client-auth.ts`: a
484
+ * different list, for a different flow, redirected to the developer's own page
485
+ * rather than rendered by Fleetless. Two callback error enums coexisting is how
486
+ * the wrong one gets picked up by the train that adds per-app OIDC, which is
487
+ * why this one is deleted rather than left standing for it.
488
+ */
489
+ /**
490
+ * `GET /api/auth/me` — named so the console can validate it.
491
+ *
492
+ * `user` is a `fleetlessUser`, and its `tier` is required, so this response
493
+ * always states the caller's console powers. It used to be an `orgUser` whose
494
+ * tier was optional and *always present in practice on this route* — a
495
+ * guarantee the route made and the schema could not, which is exactly the kind
496
+ * of gap this file keeps finding. The two-space cut closed it by making the
497
+ * field required on the shape itself.
498
+ */
499
+ export const authMeResponse = z.object({ org, user: fleetlessUser });
500
+ /** `PATCH /api/org` — rename the org. Owner only. Same bounds as signup's `org_name`. */
501
+ export const patchOrgRequest = z.object({ name: z.string().min(1).max(120) }).strict();
502
+ /** `PATCH /api/auth/me` — the caller updates their own display name (null clears it). */
503
+ export const patchAuthMeRequest = z.object({ display_name: z.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable() }).strict();
@@ -0,0 +1,51 @@
1
+ export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, rosName, rosTypeName, fieldPath, wireSeqCursor, wireTimestampMs, applyErrorKind, applyError, } from './common.js';
2
+ export type { ApplyErrorKind, ApplyError } from './common.js';
3
+ export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
4
+ export type { McpAppPaths, McpToolKind, McpExposure, McpCapabilities, McpRobotDatasheet, McpRolePreviewResponse, } from './mcp.js';
5
+ export { PROTOCOL_VERSION, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, datapointFrame, bridgeState, bridgePressure, PRESSURE_SLUG, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress, activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, } from './protocol.js';
6
+ export type { BridgeHello, CloudHelloOk, CloudHelloError, CloudPing, BridgePong, DatapointFrame, BridgeState, BridgePressure, CloudConfig, BridgeConfigApplied, CloudIntrospectRequest, BridgeIntrospect, CloudTypeRequest, BridgeTypeDefinitions, CloudInvoke, CloudCancel, CloudPublish, BridgeJobUpdate, BridgeJobLost, SnapshotHeader, CloudCameraStart, CloudCameraStop, BridgeCameraState, ActiveJob, BridgeAssetsAvailable, CloudAssetRequest, BridgeAssetProgress, } from './protocol.js';
7
+ export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
8
+ export type { JobState, Job, JobEvent, BusyDetails, PublisherBusyDetails, JobQueueFullDetails, } from './jobs.js';
9
+ export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
10
+ export type { JobActor, JobRunKind, JobRun, JobRunQuery, JobRunListResponse, JobRunSummary } from './jobs.js';
11
+ export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds, ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT, cameraSource, cameraCredentials, } from './config.js';
12
+ export type { CameraSource } from './config.js';
13
+ export type { ParameterType, ParameterSpec, ActionConfig, ServiceConfig, PublisherConfig, CameraConfig, CameraCredentials, AlertCondition, DatapointAlert, DatapointNumeric, DatapointRetention, DatapointChart, DatapointConfig, RobotConfigDoc, ValidationIssue, ConfigState, } from './config.js';
14
+ /**
15
+ * FL-005 — the one account of what is wrong with a document, shared by the
16
+ * cloud and the console. The cloud held a second copy for one wave; it was
17
+ * deleted in wave 2 task 8 (cloud `a307e18`, 2026-09-03). See
18
+ * `config-issues.ts`'s header for what that window cost.
19
+ */
20
+ export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
21
+ export type { SchemaIssue, ExposureSection } from './config-issues.js';
22
+ export { rosGraphEntry, rosGraph, typeField, typeDefinition, parameterFieldsOf } from './introspection.js';
23
+ export type { RosGraphEntry, RosGraph, TypeField, TypeDefinition } from './introspection.js';
24
+ export { robot, patchRobotResponse, robotToken, createRobotRequest, createRobotResponse, exposureCounts, robotListItem, robotListResponse, datapointValue, robotDetailResponse, configDraftResponse, putConfigDraftRequest, publishConfigResponse, configVersionsResponse, configVersionResponse, introspectionResponse, typesResponse, fetchTypesRequest, fetchTypesResponse, datapointDescriptor, datapointListResponse, robotDetailsDoc, putRobotDetailsResponse, putRobotDetailsRequest, invokeRequest, invokeResponse, cancelRequest, releaseLiveQuery, serviceCallResponse, invokeOrServiceResponse, publishRequest, jobResponse, robotJobsResponse, rateLimitDetails, exposure, exposureListResponse, SNAPSHOT_HEADERS, ASSET_UPLOAD_HEADERS, cameraDescriptor, cameraListResponse, liveSessionResponse, snapshotMetaResponse, historyQuery, historySamplesResponse, historyBucketsResponse, historyResponse, orgQuotas, orgQuotaUsage, orgQuotaUsageCounts, robotDeletionSummary, RESOURCE_HEALTH_STATES, resourceHealthState, resourceHealthListResponse, orgHealthQuery, robotDeleteQuery, patchRobotRequest, renameSlugRequest, renameSlugResponse, slugUsageResponse, } from './rest.js';
25
+ export type { HistoryQuery, HistorySamplesResponse, HistoryResponse, HistoryBucketsResponse, OrgQuotas, OrgQuotaUsage, OrgQuotaUsageCounts, RobotDeletionSummary, ResourceHealthState, ResourceHealthListResponse, OrgHealthQuery, RobotDeleteQuery, PatchRobotRequest, RenameSlugRequest, RenameSlugResponse, SlugUsageResponse, } from './rest.js';
26
+ export { LATENCY_BUCKET_MS, BRIDGE_LATENCY_RETENTION_DAYS, MAX_LATENCY_BUCKETS_PER_RESPONSE, latencyBucket, robotLatencySeries, orgLatencyQuery, orgLatencyResponse, USAGE_WINDOW_MAX_DAYS, usageMetric, usageDay, orgUsageQuery, usageRow, orgUsageResponse, } from './rest.js';
27
+ export type { LatencyBucket, RobotLatencySeries, OrgLatencyResponse } from './rest.js';
28
+ export type { UsageMetric, OrgUsageQuery, UsageRow, OrgUsageResponse } from './rest.js';
29
+ export type { Robot, PatchRobotResponse, CreateRobotRequest, CreateRobotResponse, ExposureCounts, RobotListItem, RobotListResponse, DatapointValue, RobotDetailResponse, ConfigDraftResponse, PutConfigDraftRequest, PublishConfigResponse, ConfigVersionsResponse, ConfigVersionResponse, IntrospectionResponse, TypesResponse, FetchTypesRequest, FetchTypesResponse, DatapointDescriptor, DatapointListResponse, RobotDetailsDoc, PutRobotDetailsResponse, PutRobotDetailsRequest, InvokeRequest, InvokeResponse, CancelRequest, ReleaseLiveQuery, ServiceCallResponse, InvokeOrServiceResponse, PublishRequest, JobResponse, RobotJobsResponse, RateLimitDetails, Exposure, ExposureListResponse, CameraDescriptor, CameraListResponse, LiveSessionResponse, SnapshotMetaResponse, } from './rest.js';
30
+ export { clientAuth, authOk, authError, clientInvoke, clientCancel, clientPublish, commandResult, errorFrame, clientSubscribe, clientUnsubscribe, subscribeError, datapointEvent, resourceHealthEvent, resourceHealthCleared, liveSessionEndReason, liveSessionEvent, ORG_EVENT_SAMPLE_INTERVAL_MS, ORG_EVENT_ORG_CEILING_PER_SECOND, ORG_EVENT_BUFFER_SIZE, ORG_EVENT_BUFFER_IDLE_MS, ORG_EVENT_DETAIL_MAX_BYTES, orgEventKind, orgEventSeverity, orgEvent, orgEventSubscribe, orgEventUnsubscribe, orgEventReplay, orgEventDropped, } from './realtime.js';
31
+ export type { ClientAuth, AuthOk, AuthError, ClientInvoke, ClientCancel, ClientPublish, CommandResult, ErrorFrame, ClientSubscribe, ClientUnsubscribe, SubscribeError, DatapointEvent, ResourceHealthEvent, ResourceHealthCleared, LiveSessionEndReason, LiveSessionEvent, OrgEventKind, OrgEventSeverity, OrgEvent, OrgEventSubscribe, OrgEventUnsubscribe, OrgEventReplay, OrgEventDropped, } from './realtime.js';
32
+ export { password, org, patchOrgResponse, sessionTokens, refreshRequest, signUpRequest, signUpResponse, waitlistRequest, developerLoginRequest, USER_DISPLAY_NAME_MAX, orgAdminTier, fleetlessUser, fleetlessUserListResponse, createTeamInviteRequest, teamInvite, pendingTeamInvite, pendingTeamInviteListResponse, acceptTeamInviteRequest, patchFleetlessUserRequest, tierChangeRequest, mailStatus, tierRequiredDetails, passwordChangeRequest, passwordResetRequest, passwordResetConfirm, idpIssuer, authMeResponse, patchOrgRequest, patchAuthMeRequest, } from './identity.js';
33
+ export type { Org, PatchOrgResponse, SessionTokens, RefreshRequest, SignUpRequest, SignUpResponse, WaitlistRequest, DeveloperLoginRequest, OrgAdminTier, FleetlessUser, FleetlessUserListResponse, CreateTeamInviteRequest, TeamInvite, PendingTeamInvite, PendingTeamInviteListResponse, AcceptTeamInviteRequest, PatchFleetlessUserRequest, TierChangeRequest, MailStatus, TierRequiredDetails, PasswordChangeRequest, PasswordResetRequest, PasswordResetConfirm, IdpIssuer, AuthMeResponse, PatchOrgRequest, PatchAuthMeRequest, } from './identity.js';
34
+ export { appIdentifier, app, appListResponse, createAppRequest, updateAppRequest, serverKeyToken, serverKey, serverKeyListResponse, createServerKeyResponse, role, roleListResponse, rolePermissions, } from './apps.js';
35
+ export type { App, AppListResponse, CreateAppRequest, UpdateAppRequest, ServerKey, ServerKeyListResponse, CreateServerKeyResponse, Role, RoleListResponse, RolePermissions, } from './apps.js';
36
+ export { clientLoginRequest, clientRefreshRequest, clientLogoutRequest, clientRegisterRequest, clientVerifyEmailRequest, clientResendVerificationRequest, clientPasswordResetRequest, clientPasswordResetConfirmRequest, clientAcceptInvitationRequest, CLIENT_OIDC_CALLBACK_PATH, clientProviderListQuery, clientProviderListResponse, clientOidcStartQuery, clientOidcCallbackQuery, clientOidcExchangeRequest, clientOidcErrorCode, clientMcpInteraction, clientMcpInteractionDecisionResponse, mcpConsentGrant, mcpConsentGrantListResponse, clientIdentity, } from './client-auth.js';
37
+ export type { ClientLoginRequest, ClientRefreshRequest, ClientLogoutRequest, ClientRegisterRequest, ClientVerifyEmailRequest, ClientResendVerificationRequest, ClientPasswordResetRequest, ClientPasswordResetConfirmRequest, ClientAcceptInvitationRequest, ClientProviderListQuery, ClientProviderListResponse, ClientOidcStartQuery, ClientOidcCallbackQuery, ClientOidcExchangeRequest, ClientOidcErrorCode, ClientMcpInteraction, ClientMcpInteractionDecisionResponse, McpConsentGrant, McpConsentGrantListResponse, ClientIdentity, } from './client-auth.js';
38
+ export { APP_USER_DISPLAY_NAME_MAX, APP_URL_PLACEHOLDERS, MAIL_TEMPLATE_VARIABLES, DEFAULT_MAIL_TEMPLATES, providerSlug, appUserStatus, appUser, appUserListResponse, createAppUserRequest, patchAppUserRequest, createAppInvitationRequest, appInvitation, pendingAppInvitation, appInvitationListResponse, appOidcProvider, appOidcProviderListResponse, createAppOidcProviderRequest, patchAppOidcProviderRequest, appUrlTemplate, allowedOrigin, emailDomain, appAuthConfig, putAppAuthConfigRequest, mailTemplateKind, appMailTemplate, appMailTemplateListResponse, putAppMailTemplateRequest, mailTemplatePreviewRequest, mailTemplatePreviewResponse, mailTemplateProblemDetails, mailOutcome, } from './app-users.js';
39
+ export type { AppUserStatus, AppUser, AppUserListResponse, CreateAppUserRequest, PatchAppUserRequest, CreateAppInvitationRequest, AppInvitation, PendingAppInvitation, AppInvitationListResponse, AppOidcProvider, AppOidcProviderListResponse, CreateAppOidcProviderRequest, PatchAppOidcProviderRequest, AppAuthConfig, PutAppAuthConfigRequest, MailTemplateKind, AppMailTemplate, AppMailTemplateListResponse, PutAppMailTemplateRequest, MailTemplatePreviewRequest, MailTemplatePreviewResponse, MailTemplateProblemDetails, MailOutcome, } from './app-users.js';
40
+ export { assetKind, URDF_ASSET_NAME, asset, urdfCompleteness, assetListResponse, missingAssetQuery, assetSyncRequest, assetSyncResponse, assetSyncState, assetSyncStatus, assetFailure, assetFailureKind, assetTooLargeDetails, assetSyncBusyDetails, ASSET_UPLOAD_MAX_BYTES, } from './assets.js';
41
+ export type { AssetKind, Asset, UrdfCompleteness, AssetListResponse, MissingAssetQuery, AssetSyncRequest, AssetSyncResponse, AssetSyncState, AssetSyncStatus, AssetFailure, AssetFailureKind, AssetTooLargeDetails, AssetSyncBusyDetails, } from './assets.js';
42
+ export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
43
+ export type { AuditActor, AuditEvent, AuditQuery, AuditListResponse } from './audit.js';
44
+ export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
45
+ export type { AlertRowCondition, AlertSeverity, AlertState, DatapointAlertRow, AlertListResponse, OrgFiringAlertsResponse, OrgAlertsQuery, DatapointDisplay, PutDatapointDisplayRequest, } from './alerts.js';
46
+ export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
47
+ export type { ApiError, ParameterViolation, ParameterInvalidDetails, ErrorCode } from './errors.js';
48
+ export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
49
+ export type { OauthErrorCode, OauthError, OauthRedirectResponse, OauthTokenRequest, OauthTokenResponse, RedirectUri, OauthAuthorizeQuery, DynamicClientRegistrationRequest, DynamicClientRegistrationResponse, AuthorizationServerMetadata, ProtectedResourceMetadata, } from './oauth.js';
50
+ export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';
51
+ export type { RouteEntry, RouteParam, RouteAudience, RouteAuth, RouteSection, RouteMethod, RouteTransport, } from './routes.js';
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, rosName, rosTypeName, fieldPath, wireSeqCursor, wireTimestampMs, applyErrorKind, applyError, } from './common.js';
3
+ export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
4
+ export { PROTOCOL_VERSION, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, datapointFrame, bridgeState, bridgePressure, PRESSURE_SLUG, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED,
5
+ // W7 — assets.
6
+ bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress,
7
+ // W6b — addressing.
8
+ activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, } from './protocol.js';
9
+ export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
10
+ export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
11
+ export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds,
12
+ // FL-002 — the defaults the format names, so nobody invents them twice.
13
+ ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT,
14
+ // W6
15
+ cameraSource, cameraCredentials, } from './config.js';
16
+ /**
17
+ * FL-005 — the one account of what is wrong with a document, shared by the
18
+ * cloud and the console. The cloud held a second copy for one wave; it was
19
+ * deleted in wave 2 task 8 (cloud `a307e18`, 2026-09-03). See
20
+ * `config-issues.ts`'s header for what that window cost.
21
+ */
22
+ export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
23
+ export { rosGraphEntry, rosGraph, typeField, typeDefinition, parameterFieldsOf } from './introspection.js';
24
+ export { robot, patchRobotResponse, robotToken, createRobotRequest, createRobotResponse, exposureCounts, robotListItem, robotListResponse, datapointValue, robotDetailResponse, configDraftResponse, putConfigDraftRequest, publishConfigResponse, configVersionsResponse, configVersionResponse, introspectionResponse, typesResponse, fetchTypesRequest, fetchTypesResponse, datapointDescriptor, datapointListResponse, robotDetailsDoc, putRobotDetailsResponse, putRobotDetailsRequest, invokeRequest, invokeResponse,
25
+ // W6b — addressing.
26
+ cancelRequest, releaseLiveQuery, serviceCallResponse, invokeOrServiceResponse, publishRequest, jobResponse, robotJobsResponse, rateLimitDetails, exposure, exposureListResponse, SNAPSHOT_HEADERS, ASSET_UPLOAD_HEADERS, cameraDescriptor, cameraListResponse, liveSessionResponse, snapshotMetaResponse,
27
+ // W6 — retention, history, quotas.
28
+ historyQuery, historySamplesResponse, historyBucketsResponse, historyResponse, orgQuotas, orgQuotaUsage, orgQuotaUsageCounts, robotDeletionSummary, RESOURCE_HEALTH_STATES, resourceHealthState, resourceHealthListResponse, orgHealthQuery, robotDeleteQuery,
29
+ // W3a — robot rename, slug rename.
30
+ patchRobotRequest, renameSlugRequest, renameSlugResponse, slugUsageResponse, } from './rest.js';
31
+ export { LATENCY_BUCKET_MS, BRIDGE_LATENCY_RETENTION_DAYS, MAX_LATENCY_BUCKETS_PER_RESPONSE, latencyBucket, robotLatencySeries, orgLatencyQuery, orgLatencyResponse, USAGE_WINDOW_MAX_DAYS, usageMetric, usageDay, orgUsageQuery, usageRow, orgUsageResponse, } from './rest.js';
32
+ export { clientAuth, authOk, authError, clientInvoke, clientCancel, clientPublish, commandResult, errorFrame, clientSubscribe, clientUnsubscribe, subscribeError, datapointEvent, resourceHealthEvent, resourceHealthCleared, liveSessionEndReason, liveSessionEvent, ORG_EVENT_SAMPLE_INTERVAL_MS, ORG_EVENT_ORG_CEILING_PER_SECOND, ORG_EVENT_BUFFER_SIZE, ORG_EVENT_BUFFER_IDLE_MS, ORG_EVENT_DETAIL_MAX_BYTES, orgEventKind, orgEventSeverity, orgEvent, orgEventSubscribe, orgEventUnsubscribe, orgEventReplay, orgEventDropped, } from './realtime.js';
33
+ export { password, org, patchOrgResponse, sessionTokens, refreshRequest, signUpRequest, signUpResponse,
34
+ // 2026-09-04 — the public site (closed beta).
35
+ waitlistRequest, developerLoginRequest,
36
+ // 2026-09-05 — the two identity spaces (app-user-auth, D1).
37
+ USER_DISPLAY_NAME_MAX, orgAdminTier, fleetlessUser, fleetlessUserListResponse, createTeamInviteRequest, teamInvite, pendingTeamInvite, pendingTeamInviteListResponse, acceptTeamInviteRequest, patchFleetlessUserRequest, tierChangeRequest,
38
+ // W6c — identity.
39
+ mailStatus, tierRequiredDetails, passwordChangeRequest, passwordResetRequest, passwordResetConfirm, idpIssuer,
40
+ // W3a — auth/me, org and member patches.
41
+ authMeResponse, patchOrgRequest, patchAuthMeRequest, } from './identity.js';
42
+ export { appIdentifier, app, appListResponse, createAppRequest, updateAppRequest, serverKeyToken, serverKey, serverKeyListResponse, createServerKeyResponse, role, roleListResponse, rolePermissions, } from './apps.js';
43
+ export { clientLoginRequest, clientRefreshRequest, clientLogoutRequest, clientRegisterRequest, clientVerifyEmailRequest, clientResendVerificationRequest, clientPasswordResetRequest, clientPasswordResetConfirmRequest, clientAcceptInvitationRequest, CLIENT_OIDC_CALLBACK_PATH, clientProviderListQuery, clientProviderListResponse, clientOidcStartQuery, clientOidcCallbackQuery, clientOidcExchangeRequest, clientOidcErrorCode, clientMcpInteraction, clientMcpInteractionDecisionResponse, mcpConsentGrant, mcpConsentGrantListResponse, clientIdentity, } from './client-auth.js';
44
+ // 2026-09-05 — the per-app identity space (app-user-auth, D1/D3/D4/D5).
45
+ export { APP_USER_DISPLAY_NAME_MAX, APP_URL_PLACEHOLDERS, MAIL_TEMPLATE_VARIABLES, DEFAULT_MAIL_TEMPLATES, providerSlug, appUserStatus, appUser, appUserListResponse, createAppUserRequest, patchAppUserRequest, createAppInvitationRequest, appInvitation, pendingAppInvitation, appInvitationListResponse, appOidcProvider, appOidcProviderListResponse, createAppOidcProviderRequest, patchAppOidcProviderRequest, appUrlTemplate, allowedOrigin, emailDomain, appAuthConfig, putAppAuthConfigRequest, mailTemplateKind, appMailTemplate, appMailTemplateListResponse, putAppMailTemplateRequest, mailTemplatePreviewRequest, mailTemplatePreviewResponse, mailTemplateProblemDetails, mailOutcome, } from './app-users.js';
46
+ export { assetKind, URDF_ASSET_NAME, asset, urdfCompleteness, assetListResponse, missingAssetQuery, assetSyncRequest, assetSyncResponse, assetSyncState, assetSyncStatus, assetFailure, assetFailureKind, assetTooLargeDetails, assetSyncBusyDetails, ASSET_UPLOAD_MAX_BYTES, } from './assets.js';
47
+ export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
48
+ export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
49
+ export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
50
+ export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
51
+ export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';