@fleetless/contracts 1.1.0 → 2.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 (66) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/artifacts/constants.json +30 -4
  3. package/artifacts/openapi.json +667 -98
  4. package/artifacts/routes.json +97 -6
  5. package/artifacts/schema/apply-error.schema.json +2 -1
  6. package/artifacts/schema/asset-list-response.schema.json +77 -12
  7. package/artifacts/schema/asset-sync-status.schema.json +35 -8
  8. package/artifacts/schema/asset.schema.json +2 -3
  9. package/artifacts/schema/assets-clear-response.schema.json +23 -0
  10. package/artifacts/schema/authorization-server-metadata.schema.json +1 -1
  11. package/artifacts/schema/bridge-asset-progress.schema.json +14 -8
  12. package/artifacts/schema/bridge-config-applied.schema.json +2 -1
  13. package/artifacts/schema/bridge-link-mode.schema.json +36 -0
  14. package/artifacts/schema/bridge-state.schema.json +6 -1
  15. package/artifacts/schema/client-robot-list-item.schema.json +6 -1
  16. package/artifacts/schema/client-robot-list-response.schema.json +6 -1
  17. package/artifacts/schema/cloud-config.schema.json +90 -5
  18. package/artifacts/schema/cloud-hello-ok.schema.json +45 -0
  19. package/artifacts/schema/cloud-ping.schema.json +27 -1
  20. package/artifacts/schema/config-draft-response.schema.json +90 -5
  21. package/artifacts/schema/config-state.schema.json +2 -1
  22. package/artifacts/schema/config-version-response.schema.json +90 -5
  23. package/artifacts/schema/datapoint-config.schema.json +5 -0
  24. package/artifacts/schema/datapoint-frame.schema.json +4 -0
  25. package/artifacts/schema/datapoint-list-response.schema.json +2 -2
  26. package/artifacts/schema/dynamic-client-registration-request.schema.json +1 -1
  27. package/artifacts/schema/dynamic-client-registration-response.schema.json +1 -1
  28. package/artifacts/schema/joint-state-put-request.schema.json +23 -0
  29. package/artifacts/schema/joint-state-put-response.schema.json +24 -0
  30. package/artifacts/schema/oauth-token-request.schema.json +79 -41
  31. package/artifacts/schema/oauth-token-response.schema.json +1 -1
  32. package/artifacts/schema/org-quota-usage-counts.schema.json +0 -5
  33. package/artifacts/schema/org-quota-usage.schema.json +1 -12
  34. package/artifacts/schema/org-quotas.schema.json +1 -7
  35. package/artifacts/schema/robot-config-doc.schema.json +90 -5
  36. package/artifacts/schema/robot-deletion-summary.schema.json +2 -1
  37. package/artifacts/schema/robot-detail-response.schema.json +63 -2
  38. package/artifacts/schema/robot-list-item.schema.json +15 -1
  39. package/artifacts/schema/robot-list-response.schema.json +15 -1
  40. package/artifacts/schema/robot-token-rotate-response.schema.json +15 -0
  41. package/artifacts/schema-outgoing/bridge-asset-progress.schema.json +14 -8
  42. package/artifacts/schema-outgoing/bridge-config-applied.schema.json +2 -1
  43. package/artifacts/schema-outgoing/bridge-link-mode.schema.json +37 -0
  44. package/artifacts/schema-outgoing/datapoint-frame.schema.json +4 -0
  45. package/dist/assets.d.ts +85 -50
  46. package/dist/assets.js +152 -62
  47. package/dist/audit.d.ts +1 -1
  48. package/dist/audit.js +1 -1
  49. package/dist/client-robots.d.ts +2 -0
  50. package/dist/common.d.ts +10 -0
  51. package/dist/common.js +16 -1
  52. package/dist/config.d.ts +69 -1
  53. package/dist/config.js +86 -6
  54. package/dist/errors.d.ts +1 -1
  55. package/dist/errors.js +1 -8
  56. package/dist/index.d.ts +10 -10
  57. package/dist/index.js +5 -5
  58. package/dist/oauth.d.ts +34 -19
  59. package/dist/oauth.js +39 -24
  60. package/dist/protocol.d.ts +150 -71
  61. package/dist/protocol.js +144 -87
  62. package/dist/rest.d.ts +137 -35
  63. package/dist/rest.js +98 -66
  64. package/dist/routes.js +68 -19
  65. package/package.json +1 -1
  66. package/artifacts/schema/bridge-pressure.schema.json +0 -292
package/CHANGELOG.md CHANGED
@@ -5,7 +5,38 @@ follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the
5
5
  project uses [semantic versioning](https://semver.org/spec/v2.0.0.html) over
6
6
  the wire shapes.
7
7
 
8
- ## [Unreleased]
8
+ ## [2.0.0] — 2026-09-22
9
+
10
+ ### Added
11
+
12
+ - **A robot's own asset store.** `ROBOT_ASSET_STORE_BYTES` (1 GB) is what every robot gets, in `constants.json` too, so the bridge reads the same number the cloud enforces. `assetStoreRefusedDetails` carries `store_bytes`, `used_bytes` and `size_bytes` behind the `409 quota_exceeded` an upload with no room left answers, and rides on a `refused` entry in `assetFailure.details`. `assetListResponse` gains `store { bytes, used_bytes }`, so the page that lists a robot's assets can say how full it is without asking a second endpoint about the organisation.
13
+ - **A full store is never a dead end.** `DELETE /api/robots/:id/assets` (Owner tier, `200`, `assetsClearResponse { deleted, bytes_freed }`) removes every URDF, mesh and texture of a robot and resets its store to zero, refusing `409 busy` while a sync is running; the next sync fills it again, and the bridge's own availability report is untouched. It is the blunt third answer alongside the URDF upload's exemption from the store gate and reconcile freeing what a new URDF no longer references.
14
+ - **Two robot-detail routes.** `POST /api/robots/:id/token/rotate` (Owner tier, `201`, `robotTokenRotateResponse`) mints a new bridge token and stops the socket speaking on the old one; `CLOSE_TOKEN_ROTATED` (4005) is the code it closes with, distinct from `CLOSE_ROBOT_DELETED` because the robot very much still exists. `PUT /api/robots/:id/urdf/joint-state` (`jointStatePutRequest`/`jointStatePutResponse`) chooses the whole-message `sensor_msgs/msg/JointState` datapoint that moves the URDF's joints, or clears it; `assetListResponse.joint_state_slug` reads it back.
15
+ - **A sync says what the store holds, not only what the robot claimed.** `assetSyncStatus` gains the required pair `stored` and `announced`: how many of the announced files — the URDF and every mesh URI the description references — the cloud's store actually holds — counted once after the robot's terminal frame, and `null` until then — against how many the robot announced. `state` alone was the bridge's terminal frame, so a stack whose object store answered `500` to every upload still reported `succeeded`; the cloud counts after that frame now, and a `succeeded` sync over an empty store ends `failed` with an `upload_failed` entry naming what is not there.
16
+ - **`applyErrorKind` gains `low_bandwidth`.** A `low_bandwidth` section that does not resolve on the robot is reported under its own kind, slug `low_bandwidth`, instead of borrowing `datapoint` with slug `*`.
17
+
18
+ ### Changed
19
+
20
+ - **Protocol 3 — the bridge decides its own low-bandwidth mode.** `cloudPing` carries `latency_ms` and `lag_ms`; the bridge sends `link_mode`; `bridge_state` gains `low_bandwidth`. `fleetless.yaml` gains an optional top-level `low_bandwidth` section and a per-datapoint `low_bandwidth: keep`; `LOW_BANDWIDTH_DEFAULTS` ships in `constants.json`. `datapointFrame` gains an optional `backfill` flag, so a replayed sample carrying its original capture time is not read as lag on the link. Protocol 2 is deprecated as of this release and served until 2026-12-21; its cloud adapter owes it two translations on the way in — it drops the pressure datapoints, and it rewrites an `asset_progress` failure of kind `too_large` (a kind protocol 3 no longer has) to `refused` with `details: null`.
21
+ - **Required, not merely present.** `assetListResponse.store`, `assetListResponse.joint_state_slug` and `bridgeState.low_bandwidth` are required keys now, not optional-by-absence; `cloudPing.latency_ms` and `cloudPing.lag_ms` are required (nullable) on protocol 3. `LATEST_BRIDGE_VERSION` is `4.0.0`. Deploy the cloud before any consumer pins `2.0.0` — a response from a 0.2x cloud no longer parses these shapes.
22
+
23
+ ### Removed
24
+
25
+ - **The per-file upload ceiling, and the organisation's storage dial.** `ASSET_UPLOAD_MAX_BYTES`, `assetTooLargeDetails`, the error code `asset_too_large` and the `assetFailureKind` member `too_large` are gone: nothing is refused for its own size any more, only for the robot's store. `orgQuotas.max_asset_storage_bytes` and its usage twin go with them — a robot has 1 GB; the organisation dial is gone.
26
+ - **`assetKind` member `other`.** No producer ever sent it. The bridge classifies what it uploads and has only `urdf`, `mesh` and `texture` to choose from, so `other` was a slot for a file nobody had that every consumer still had to branch on.
27
+ - **`bridge_pressure`.** The datapoint, `bridgePressure`, `PRESSURE_SLUG` and the reserved slug are gone; an app that read it reads `bridge_state.low_bandwidth` instead. This is the break that makes this release a major.
28
+
29
+ ## [1.3.0] — 2026-09-21
30
+
31
+ ### Added
32
+
33
+ - **A protocol version window.** `PROTOCOL_VERSIONS` lists every protocol version with the bridge that introduced it and the date it was deprecated; `PROTOCOL_SUNSET_DAYS` (90) says how long a deprecated version is still served; `LATEST_BRIDGE_VERSION` names the newest bridge package. `protocolStatus()` and `minimumProtocolVersion()` answer for a date. All four reach `constants.json` for the bridge. `cloudHelloOk` may now carry `protocol { status, sunset_at }` and `bridge { latest_version }`. `robotListItem` gains `protocol_status`; `robotDetailResponse` gains `protocol_version` and `protocol`. All three are optional in this release, so a response from an older cloud still parses; a consumer reads their absence as `current`. Protocol 2 stays current; nothing previously valid becomes invalid.
34
+
35
+ ## [1.2.0] — 2026-09-18
36
+
37
+ ### Added
38
+
39
+ - **The MCP token request has its refresh grant back.** `oauthTokenRequest` is a discriminated union again: `oauthCodeTokenRequest` (unchanged) or the new `oauthRefreshTokenRequest` — `grant_type: refresh_token`, `refresh_token`, a required `client_id` and an optional RFC 8707 `resource`. Both MCP authorization servers answer it from cloud 0.20.0: every exchange issues a refresh token, every refresh rotates it, and it lives ninety days from its last use. The registration, token-response and metadata descriptions and the four route notes stop promising there is no refresh grant. Nothing previously valid becomes invalid.
9
40
 
10
41
  ## [1.1.0] — 2026-09-17
11
42
 
@@ -1,5 +1,22 @@
1
1
  {
2
2
  "AUDIT_RETENTION_DAYS": 90,
3
+ "PROTOCOL_VERSION": 3,
4
+ "PROTOCOL_VERSIONS": [
5
+ {
6
+ "version": 2,
7
+ "bridge_from": "3.0.0",
8
+ "deprecated_at": "2026-09-22"
9
+ },
10
+ {
11
+ "version": 3,
12
+ "bridge_from": "4.0.0",
13
+ "deprecated_at": null
14
+ }
15
+ ],
16
+ "PROTOCOL_SUNSET_DAYS": 90,
17
+ "LATEST_BRIDGE_VERSION": "4.0.0",
18
+ "CLOSE_ROBOT_DELETED": 4004,
19
+ "CLOSE_TOKEN_ROTATED": 4005,
3
20
  "ASSET_UPLOAD_HEADERS": {
4
21
  "kind": "x-fleetless-asset-kind",
5
22
  "name": "x-fleetless-asset-name",
@@ -7,7 +24,7 @@
7
24
  "syncId": "x-fleetless-sync-id",
8
25
  "size": "x-fleetless-asset-size"
9
26
  },
10
- "ASSET_UPLOAD_MAX_BYTES": 67108864,
27
+ "ROBOT_ASSET_STORE_BYTES": 1000000000,
11
28
  "SNAPSHOT_HEADERS": {
12
29
  "ageMs": "x-fleetless-age-ms",
13
30
  "timestampMs": "x-fleetless-timestamp-ms",
@@ -18,7 +35,16 @@
18
35
  "ASSET_KINDS": [
19
36
  "urdf",
20
37
  "mesh",
21
- "texture",
22
- "other"
23
- ]
38
+ "texture"
39
+ ],
40
+ "LOW_BANDWIDTH_DEFAULTS": {
41
+ "mode": "auto",
42
+ "enter_lag_ms": 2000,
43
+ "enter_after_s": 10,
44
+ "exit_lag_ms": 500,
45
+ "exit_after_s": 60,
46
+ "datapoint_max_hz": 1,
47
+ "camera": "reduce",
48
+ "camera_bitrate_kbps": 300
49
+ }
24
50
  }