@fleetless/contracts 1.0.5 β†’ 1.0.6

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 (91) hide show
  1. package/CHANGELOG.md +11 -2
  2. package/CONTRIBUTING.md +100 -75
  3. package/README.md +69 -83
  4. package/SECURITY.md +24 -24
  5. package/artifacts/openapi.json +65 -65
  6. package/artifacts/routes.json +3 -3
  7. package/artifacts/schema/app-list-response.schema.json +2 -2
  8. package/artifacts/schema/app-oidc-provider-list-response.schema.json +1 -1
  9. package/artifacts/schema/app-oidc-provider.schema.json +1 -1
  10. package/artifacts/schema/app-user-list-response.schema.json +2 -2
  11. package/artifacts/schema/app-user.schema.json +2 -2
  12. package/artifacts/schema/app.schema.json +2 -2
  13. package/artifacts/schema/asset-list-response.schema.json +7 -7
  14. package/artifacts/schema/asset-sync-request.schema.json +1 -1
  15. package/artifacts/schema/asset-sync-status.schema.json +1 -1
  16. package/artifacts/schema/asset.schema.json +3 -3
  17. package/artifacts/schema/auth-me-response.schema.json +2 -2
  18. package/artifacts/schema/auth-ok.schema.json +1 -1
  19. package/artifacts/schema/authorization-server-metadata.schema.json +1 -1
  20. package/artifacts/schema/bridge-asset-progress.schema.json +1 -1
  21. package/artifacts/schema/busy-details.schema.json +3 -3
  22. package/artifacts/schema/client-identity.schema.json +1 -1
  23. package/artifacts/schema/client-login-request.schema.json +1 -1
  24. package/artifacts/schema/client-logout-request.schema.json +1 -1
  25. package/artifacts/schema/client-mcp-interaction.schema.json +1 -1
  26. package/artifacts/schema/cloud-config.schema.json +1 -1
  27. package/artifacts/schema/command-result.schema.json +3 -3
  28. package/artifacts/schema/config-draft-response.schema.json +1 -1
  29. package/artifacts/schema/config-version-response.schema.json +1 -1
  30. package/artifacts/schema/create-server-key-response.schema.json +1 -1
  31. package/artifacts/schema/datapoint-config.schema.json +1 -1
  32. package/artifacts/schema/datapoint-value.schema.json +2 -2
  33. package/artifacts/schema/dynamic-client-registration-request.schema.json +2 -2
  34. package/artifacts/schema/fleetless-user-list-response.schema.json +2 -2
  35. package/artifacts/schema/fleetless-user.schema.json +2 -2
  36. package/artifacts/schema/invoke-or-service-response.schema.json +4 -4
  37. package/artifacts/schema/invoke-response.schema.json +3 -3
  38. package/artifacts/schema/job-actor.schema.json +1 -1
  39. package/artifacts/schema/job-event.schema.json +3 -3
  40. package/artifacts/schema/job-response.schema.json +3 -3
  41. package/artifacts/schema/job-run-list-response.schema.json +2 -2
  42. package/artifacts/schema/job-run.schema.json +2 -2
  43. package/artifacts/schema/job.schema.json +3 -3
  44. package/artifacts/schema/mcp-consent-grant-list-response.schema.json +2 -2
  45. package/artifacts/schema/mcp-consent-grant.schema.json +2 -2
  46. package/artifacts/schema/oauth-authorize-query.schema.json +1 -1
  47. package/artifacts/schema/oauth-token-request.schema.json +1 -1
  48. package/artifacts/schema/patch-org-response.schema.json +1 -1
  49. package/artifacts/schema/patch-robot-response.schema.json +1 -1
  50. package/artifacts/schema/robot-config-doc.schema.json +1 -1
  51. package/artifacts/schema/robot-jobs-response.schema.json +3 -3
  52. package/artifacts/schema/role-list-response.schema.json +1 -1
  53. package/artifacts/schema/role.schema.json +1 -1
  54. package/artifacts/schema/server-key-list-response.schema.json +2 -2
  55. package/artifacts/schema/server-key.schema.json +1 -1
  56. package/artifacts/schema/service-call-response.schema.json +1 -1
  57. package/artifacts/schema/sign-up-response.schema.json +2 -2
  58. package/artifacts/schema/urdf-completeness.schema.json +2 -2
  59. package/artifacts/schema-outgoing/bridge-asset-progress.schema.json +1 -1
  60. package/dist/alerts.d.ts +15 -17
  61. package/dist/alerts.js +15 -17
  62. package/dist/app-users.d.ts +5 -6
  63. package/dist/app-users.js +9 -10
  64. package/dist/apps.d.ts +5 -6
  65. package/dist/apps.js +11 -12
  66. package/dist/assets.js +10 -13
  67. package/dist/audit.d.ts +10 -12
  68. package/dist/audit.js +14 -17
  69. package/dist/client-auth.d.ts +8 -9
  70. package/dist/client-auth.js +14 -15
  71. package/dist/config-issues.d.ts +3 -3
  72. package/dist/config-issues.js +3 -3
  73. package/dist/config.d.ts +5 -6
  74. package/dist/config.js +7 -8
  75. package/dist/errors.d.ts +4 -4
  76. package/dist/errors.js +8 -9
  77. package/dist/identity.d.ts +4 -5
  78. package/dist/identity.js +7 -8
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.js +1 -1
  81. package/dist/jobs.js +5 -5
  82. package/dist/mcp.d.ts +5 -8
  83. package/dist/mcp.js +2 -2
  84. package/dist/oauth.d.ts +8 -10
  85. package/dist/oauth.js +13 -15
  86. package/dist/protocol.d.ts +7 -8
  87. package/dist/protocol.js +20 -22
  88. package/dist/realtime.js +4 -4
  89. package/dist/rest.js +4 -4
  90. package/dist/routes.js +3 -3
  91. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,15 @@ 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]
9
+
10
+ ## [1.0.6] β€” 2026-09-16
11
+
12
+ - Published from GitHub Actions by npm trusted publishing: no publish token exists anywhere, and every version from this one on carries a provenance attestation linking it to the commit and the run that built it. `npm audit signatures` checks it.
13
+
14
+ - **The README is a lobby now.** Who the package is for, what is in the box, the two schema directories and which one to validate against, versioning, and links into docs.fleetless.dev. No wire shape changes.
15
+ - The prose guard treats a path into the company-site repository the way it treats every other sibling repository's path. No wire shape changes.
16
+
8
17
  ## [1.0.5] β€” 2026-09-07
9
18
 
10
19
  The guard was rebuilt around the set of bytes that become public rather than
@@ -91,8 +100,8 @@ files under `artifacts/schema/` β€” the one that moves carries a reworded
91
100
 
92
101
  - **Descriptions and comments that spoke inward.** 1.0.2 removed the markers β€” a
93
102
  ticket id, a robot's hostname, a German paragraph β€” and left the stance. Text
94
- that named an internal decision label (`D2`, `D7`), pointed at a file in
95
- another repository (`cloud/src/routes/config.ts`), said "this project" or
103
+ that named an internal decision label (`D2`, `D7`), pointed at a source file in
104
+ another repository, said "this project" or
96
105
  "this repository", cited a document a reader does not have, or explained how
97
106
  somebody discovered the behaviour rather than what the behaviour is. All of it
98
107
  is rewritten for a reader who has only this package: 13 descriptions and every
package/CONTRIBUTING.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Contributing to `@fleetless/contracts`
2
2
 
3
- This package is the single source of wire truth for Fleetless: every shape the
4
- API accepts or returns, and every message the robot-side bridge exchanges with
5
- the cloud, is written here once as a zod schema and exported as JSON Schema and
6
- OpenAPI for consumers that are not TypeScript.
3
+ This package is Fleetless's single source of wire truth. Every shape the API
4
+ accepts or returns, every message the robot-side bridge exchanges with the
5
+ cloud β€” written once as a zod schema, exported as JSON Schema and OpenAPI for
6
+ consumers that don't speak TypeScript.
7
7
 
8
- That makes a change here a cross-repository change. A schema is not a detail of
9
- one program; it is the agreement between several.
8
+ A change here is a cross-repository change: a schema isn't one program's
9
+ detail, it's the agreement between several.
10
10
 
11
11
  ## Setup
12
12
 
@@ -18,8 +18,8 @@ corepack enable
18
18
  pnpm install
19
19
  ```
20
20
 
21
- There are no private dependencies. `pnpm install` works from a clean checkout
22
- with nothing but a network connection to the npm registry.
21
+ No private dependencies β€” a clean checkout and a network connection to npm
22
+ are all `pnpm install` needs.
23
23
 
24
24
  ## The checks
25
25
 
@@ -32,67 +32,81 @@ with nothing but a network connection to the npm registry.
32
32
  | `pnpm run test:pack` | Packs the tarball, asserts what is and is not inside it, then installs it into a scratch project and imports it for real. |
33
33
 
34
34
  To run one test file, use `pnpm vitest run test/<name>.test.ts`. Do **not**
35
- use `pnpm test -- <pattern>`: it does not filter, it runs the whole suite, and
36
- the exit code you read is the suite's.
35
+ use `pnpm test -- <pattern>`: it does not filter, it runs the whole suite,
36
+ and the exit code you read is the suite's.
37
37
 
38
38
  ## Changing a schema
39
39
 
40
40
  1. Edit the zod schema in `src/`.
41
- 2. Run `pnpm artifacts`. This regenerates `artifacts/`, which is **committed**.
42
- A test fails if the committed artifacts are stale, and so does CI.
41
+ 2. Run `pnpm artifacts`. It regenerates `artifacts/`, which is
42
+ **committed** β€” a stale artifact fails a test, and so does CI.
43
43
  3. Run `pnpm typecheck && pnpm test`.
44
- 4. Commit the schema change and the regenerated artifacts together. A commit
45
- that changes one without the other is a commit that publishes a lie to every
46
- consumer validating against the artifact.
44
+ 4. Commit the schema and the regenerated artifacts together β€” split them
45
+ and you've published a lie to every consumer validating against the
46
+ artifact.
47
47
 
48
- Every source file carries the SPDX header `// SPDX-License-Identifier:
49
- Apache-2.0` as its first line. A test asserts this over the whole set β€” and the
50
- directory list is derived from the repository rather than written down, so a new
51
- top-level directory is swept the day it exists.
48
+ Every source file's first line is the SPDX header
49
+ `// SPDX-License-Identifier: Apache-2.0`. A test asserts the whole set, and
50
+ the directory list comes from the repository rather than a written-down
51
+ list β€” a new top-level directory is swept in the day it's created.
52
52
 
53
- The published files carry it too, which `tsc` does not do on its own:
54
- declaration emit drops a leading comment, so `scripts/stamp-dist.mjs` puts the
55
- header back on every file in `dist/` and `pnpm run test:pack` asserts it over
56
- the tarball's own bytes.
53
+ The published files carry it too β€” `tsc` won't do that alone; declaration
54
+ emit drops a leading comment, so `scripts/stamp-dist.mjs` puts the header
55
+ back on every file in `dist/`, and `pnpm run test:pack` asserts the tarball's
56
+ own bytes.
57
57
 
58
58
  **Nothing internal reaches the published bytes.** Doc comments in `src/` are
59
59
  carried into `dist/*.js` and `dist/*.d.ts` by `tsc`, and every
60
- `.meta({ description })` is copied into the JSON Schema and OpenAPI artifacts β€”
61
- so a comment written for the people who build this is a comment an editor shows
62
- to somebody who installed it. Write a description as what a field means to a
63
- caller, never as how the behaviour was found, on which machine, or under which
64
- internal ticket. `test/published-prose.test.ts` greps the built output and fails
65
- on German prose, an internal ticket id, a developer machine path or a
66
- first-name attribution.
60
+ `.meta({ description })` is copied into the JSON Schema and OpenAPI
61
+ artifacts β€” so a comment written for the people who build this is a comment
62
+ an editor shows to somebody who installed it. Write a description as what a
63
+ field means to a caller, never as how the behaviour was found, on which
64
+ machine, or under which internal ticket. `test/published-prose.test.ts`
65
+ greps the built output and fails on German prose, an internal ticket id, a
66
+ developer machine path or a first-name attribution.
67
67
 
68
68
  ## Pull requests
69
69
 
70
70
  **Pull requests are welcome on GitHub**, at
71
- <https://github.com/fleetless/contracts>. Open an issue first for anything that
72
- changes an existing shape, so we can say what else has to move with it.
73
-
74
- **CI runs on GitLab.** This repository is mirrored from an internal GitLab
75
- instance, which is where the pipeline that verifies and publishes it lives. You
76
- will not see a check run on your GitHub pull request; a maintainer runs the
77
- same checks, and the result comes back as a review comment. Run `pnpm
78
- typecheck && pnpm test && pnpm artifacts` yourself before you open the pull
79
- request and you will have seen everything CI would tell you.
71
+ <https://github.com/fleetless/contracts>. Changing an existing shape? Open
72
+ an issue first β€” so we can say what else has to move with it.
73
+
74
+ **CI runs on GitHub Actions**, in this repository
75
+ (`.github/workflows/verify.yml`) β€” the suite, on every push and every pull
76
+ request. `release.yml` publishes on a release tag and calls that same file
77
+ first, so a release is never checked by a different pipeline than a push.
78
+
79
+ **Your pull request is verified, a fork's included** β€” the same file, the
80
+ same suite. The first run by a first-time contributor waits for a maintainer
81
+ to press approve on it; that is a button on your run, not a setting anybody
82
+ has to change, so checks sitting idle for a while are the queue and not a
83
+ failure. The run reads code and reaches nothing else: it is granted
84
+ `contents: read`, no secret is exposed to it, and publishing lives in a
85
+ workflow only a tag can trigger.
86
+
87
+ Run `pnpm typecheck && pnpm build && pnpm test && pnpm artifacts && pnpm run
88
+ test:pack` yourself first and you've seen everything `verify` will tell you.
89
+ Mind `pnpm artifacts`: `artifacts/` is generated *and* committed, and CI
90
+ fails if regenerating it changes a file β€” so commit whatever it writes
91
+ together with the schema you changed. That is the single most common reason
92
+ a first pull
93
+ request here goes red.
80
94
 
81
95
  ## The CLA
82
96
 
83
- The first pull request you open will ask you to sign a Contributor Licence
84
- Agreement. It grants Dehne Robotik GmbH the right to license your contribution
85
- under terms other than Apache-2.0 in future β€” that is the whole of what it is
86
- for, and it is why the project can relicense its own code later without having
87
- to find every past contributor. It does not take your copyright away and it
88
- does not stop you from using your own contribution however you like.
97
+ The first pull request you open asks you to sign a Contributor Licence
98
+ Agreement. It grants Dehne Robotik GmbH the right to license your
99
+ contribution under terms other than Apache-2.0 later β€” that's the whole of
100
+ it, and how the project can relicense without hunting down every past
101
+ contributor. It does not take your copyright away and it does not stop you
102
+ from using your own contribution however you like.
89
103
 
90
104
  ## Commit messages
91
105
 
92
106
  [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):
93
- `feat:`, `fix:`, `docs:`, `chore:`, `ci:`, `refactor:`, `test:`. A change that
94
- alters an existing wire shape is a breaking change; say so with a `!` and a
95
- `BREAKING CHANGE:` footer, because it decides the next version number.
107
+ `feat:`, `fix:`, `docs:`, `chore:`, `ci:`, `refactor:`, `test:`. Altering an
108
+ existing wire shape is a breaking change β€” say so with a `!` and a
109
+ `BREAKING CHANGE:` footer; it decides the next version number.
96
110
 
97
111
  Everything in this repository is written in **English** β€” code, comments,
98
112
  commit messages, documentation.
@@ -104,33 +118,44 @@ By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md).
104
118
 
105
119
  ## Releasing (maintainers)
106
120
 
107
- The pipeline publishes, and `npm publish` from a working tree is refused by a
108
- `prepublishOnly` script β€” the rule has a mechanism rather than only a sentence.
109
- (The pipeline is unaffected: it publishes the tarball `verify` packed, and npm
110
- runs no prepare lifecycle for a tarball argument.)
121
+ The `publish` workflow job publishes, and `npm publish` from a working tree
122
+ is refused by a `prepublishOnly` script β€” the rule has a mechanism rather
123
+ than only a sentence. (`publish` is unaffected: it publishes the tarball
124
+ `verify` packed, and npm runs no prepare lifecycle for a tarball argument.)
111
125
 
112
- 1. Update `CHANGELOG.md` and set the new version in `package.json`. **CI checks
113
- both**, in `scripts/verify-version-tag.mjs`: `package.json` must equal the
114
- tag without its `v`, and `CHANGELOG.md` must carry a dated heading reading
115
- exactly `## [X.Y.Z] β€” YYYY-MM-DD`. `CHANGELOG.md` ships inside the tarball,
116
- so a forgotten entry documents the wrong version to every consumer and npm
117
- will not take a version back.
126
+ 1. Update `CHANGELOG.md` and set the new version in `package.json`. **CI
127
+ checks both** (`scripts/verify-version-tag.mjs`): `package.json` must
128
+ equal the tag without its `v`, and `CHANGELOG.md` needs a dated heading
129
+ reading exactly `## [X.Y.Z] β€” YYYY-MM-DD`. `CHANGELOG.md` ships inside
130
+ the tarball β€” skip an entry and you've documented the wrong version to
131
+ every consumer, and npm won't take a version back.
118
132
 
119
133
  The same script refuses a release tag that would move npm's `latest`
120
- backwards β€” a backported `v1.0.1` published while `latest` is `2.0.0` would
121
- make `npm i @fleetless/contracts`, the command the README gives outsiders,
122
- install a package a major version behind.
123
- 2. Commit, push, and let the `verify` job go green on the branch.
124
- 3. Tag `vX.Y.Z` (or `vX.Y.Z-beta.N` for a pre-release, which publishes to the
125
- `next` dist-tag) and push the tag. The tag pipeline runs `verify` again and
126
- then `publish`.
127
-
128
- `publish` needs an `NPM_TOKEN` variable, protected and masked. Protected means
129
- an unprotected ref receives an empty value rather than a missing one, so the
130
- tag pattern must be protected too; the job names that case before it can fail
131
- on it obliquely.
132
-
133
- **If the publish job goes red after `npm publish` has run, do not press
134
- retry.** npm refuses to republish a version, so a retry fails with a 403 that
135
- reads like a broken pipeline rather than like a release that already happened.
136
- Check `npm view @fleetless/contracts@<version>` first.
134
+ backwards β€” a backported `v1.0.1` published while `latest` is `2.0.0`
135
+ would make `npm i @fleetless/contracts`, the command the README gives
136
+ outsiders, install a package a major version behind.
137
+ 2. Commit, push, and let the `verify` job go green on the branch (the
138
+ Actions tab).
139
+ 3. Tag `vX.Y.Z` (or `vX.Y.Z-beta.N` for a pre-release, which publishes to
140
+ the `next` dist-tag) and push the tag. The tag run's `verify` job runs
141
+ again and then `publish`.
142
+
143
+ `publish` carries no npm token. It authenticates by **trusted publishing**:
144
+ GitHub mints a short-lived credential for the job, npm checks it against the
145
+ trusted publisher configured on npmjs.com for this repository and this
146
+ workflow filename, and npm generates the provenance attestation itself β€”
147
+ `npm audit signatures` verifies it against this commit and this run. Renaming
148
+ `release.yml` breaks publishing until the publisher is updated on npmjs.com.
149
+ The job refuses a missing credential by name, rather than failing on an opaque
150
+ error from deep inside `npm publish`. There is no repository secret to add and
151
+ no `.npmrc` anywhere.
152
+
153
+ **If the publish job goes red after `npm publish` already ran, do not press
154
+ retry.** npm refuses to republish a version β€” the resulting 403 reads like
155
+ a broken run, not like a release that already happened. Check `npm view
156
+ @fleetless/contracts@<version>` first.
157
+
158
+ Removing a bad tag is an ordinary git operation here β€” nothing configures
159
+ tag protection, so `git tag -d vX.Y.Z` locally and `git push origin
160
+ :refs/tags/vX.Y.Z` remotely both just work. What that does *not* undo is a
161
+ publish: the tag is retractable, the npm version is not.
package/README.md CHANGED
@@ -1,24 +1,43 @@
1
- # `@fleetless/contracts`
1
+ # @fleetless/contracts
2
2
 
3
- The wire contracts for [Fleetless](https://fleetless.dev): every shape the
4
- Fleetless API accepts or returns, and every message a robot's bridge exchanges
5
- with the cloud, written once as [zod](https://zod.dev) schemas and exported as
6
- JSON Schema and OpenAPI.
3
+ [![npm version](https://img.shields.io/npm/v/@fleetless/contracts)](https://www.npmjs.com/package/@fleetless/contracts)
4
+ [![license Apache-2.0](https://img.shields.io/npm/l/@fleetless/contracts)](LICENSE)
7
5
 
8
- Fleetless turns a ROS 2 robot into a REST and realtime API. A developer
9
- configures which topics, services, actions and cameras a robot exposes; client
10
- apps consume those over HTTP and WebSocket. This package is the definition of
11
- what goes over that wire β€” it is the same file the server validates with, so a
12
- client built against it cannot disagree with the server about a field name, a
13
- bound or an error code.
6
+ **Every shape the Fleetless API accepts or returns, and every frame a robot's
7
+ bridge exchanges with the cloud.** Written once as [zod](https://zod.dev)
8
+ schemas, shipped as JSON Schema and OpenAPI.
9
+
10
+ [Fleetless](https://fleetless.dev) turns a ROS 2 robot into a hosted REST and
11
+ realtime API. This package is the definition of what crosses that wire, and
12
+ it is the same file the server validates with. A client built against it
13
+ cannot disagree with the server about a field name, a bound or an error code.
14
+
15
+ ## 🎯 Who this is for
16
+
17
+ Most app developers do not need this package.
18
+ [`@fleetless/sdk`](https://www.npmjs.com/package/@fleetless/sdk) is the client
19
+ library and already speaks these shapes. Reach for `@fleetless/contracts` when
20
+ you are building what the SDK does not cover: a server-side integration, a
21
+ client in another language, or a bridge of your own.
22
+
23
+ ## πŸ“¦ What is in the box
24
+
25
+ | Path | What it is |
26
+ |---|---|
27
+ | `dist/` | The zod schemas, their inferred types and the error codes, exported from the package root. |
28
+ | `artifacts/openapi.json` | The OpenAPI 3.1 description of the REST API. |
29
+ | `artifacts/routes.json` | Every route with its request and response schema names, and the notes that explain each one. |
30
+ | `artifacts/schema/*.json` | One JSON Schema per wire shape, as **a receiver validates an incoming document**. |
31
+ | `artifacts/schema-outgoing/*.json` | The twelve frames a bridge **sends**, as the sender must produce them. |
32
+
33
+ ## πŸš€ Getting started
14
34
 
15
35
  ```sh
16
36
  npm i @fleetless/contracts
17
37
  ```
18
38
 
19
- ## TypeScript
20
-
21
- Import the schemas and the types inferred from them:
39
+ TypeScript imports the schemas and the types inferred from them, all from the
40
+ package root:
22
41
 
23
42
  ```ts
24
43
  import { robotListResponse, ERROR_CODES } from '@fleetless/contracts'
@@ -27,98 +46,65 @@ import type { RobotListResponse, ErrorCode } from '@fleetless/contracts'
27
46
  const robots: RobotListResponse = robotListResponse.parse(await res.json())
28
47
  ```
29
48
 
30
- Everything is exported from the package root. There is no deep import for the
31
- TypeScript surface.
32
-
33
- Most application developers do not need this package directly:
34
- [`@fleetless/sdk`](https://www.npmjs.com/package/@fleetless/sdk) is the client
35
- library, and it already speaks these shapes. Reach for `@fleetless/contracts`
36
- when you are writing something the SDK does not cover β€” a server-side
37
- integration, your own client, or a validator in another language.
38
-
39
- ## JSON Schema and OpenAPI
40
-
41
- Consumers that are not TypeScript read the generated documents under
42
- `artifacts/`, which ship inside the published package and are importable by
43
- path:
49
+ Everything else imports the generated documents by path, no TypeScript
50
+ required:
44
51
 
45
52
  ```ts
46
53
  import routes from '@fleetless/contracts/artifacts/routes.json' with { type: 'json' }
47
54
  import openapi from '@fleetless/contracts/artifacts/openapi.json' with { type: 'json' }
48
55
  ```
49
56
 
50
- | Path | What it is |
51
- |---|---|
52
- | `artifacts/openapi.json` | The OpenAPI 3.1 description of the REST API, generated from the route manifest and the schemas. |
53
- | `artifacts/routes.json` | Every route with its request and response schema names, and the notes that explain each one. |
54
- | `artifacts/schema/*.json` | One JSON Schema per wire shape, named after the shape, rendered as **a receiver validates an incoming document**. |
55
- | `artifacts/schema-outgoing/*.json` | Twelve of those same shapes rendered again as **a sender must produce them** β€” the frames a robot's bridge sends to the cloud. |
57
+ Two compatibility axes: the package version follows semver over the wire
58
+ shapes, and `zod` is a range rather than a pin because a schema from here must
59
+ be an instance of the one copy of zod in your tree.
56
60
 
57
- The two schema directories are the same shapes in zod's two rendering modes,
58
- and the difference matters if you are writing a bridge.
61
+ ## ↔️ Two schema directories, and which one you want
59
62
 
60
- `artifacts/schema/` is *input* mode: what a receiver accepts. Fleetless
61
- receivers strip unknown keys rather than refusing them, so these documents omit
62
- `additionalProperties: false`, and a field with a default is not marked
63
- required.
63
+ `artifacts/schema/` is what a receiver accepts. Fleetless receivers strip
64
+ unknown keys rather than refuse them, so these documents omit
65
+ `additionalProperties: false`, and a field with a default is not required.
64
66
 
65
- `artifacts/schema-outgoing/` is *output* mode, for the twelve frames a bridge
66
- **sends**. There a relaxed schema points the wrong way: a misspelled key in an
67
- outgoing frame would pass an input-mode check and then be silently dropped by
68
- the server. Validate what you send against `schema-outgoing/`, and what you
69
- receive against `schema/`.
67
+ `artifacts/schema-outgoing/` is what a sender must produce, for the twelve
68
+ frames a bridge sends to the cloud. Checked against the relaxed schema, a
69
+ misspelled key in an outgoing frame passes and is then silently dropped by the
70
+ server, which is a bug nobody reports because nothing fails.
70
71
 
71
- The artifacts are generated and committed rather than produced at install time
72
- because a consumer in another language needs them without running a TypeScript
73
- build.
72
+ So: validate what you **receive** against `schema/`, and what you **send**
73
+ against `schema-outgoing/`. If you are writing a bridge, this paragraph is the
74
+ one to remember.
74
75
 
75
- ## Versioning
76
+ ## πŸ”’ Versioning
76
77
 
77
78
  Semantic versioning over the wire shapes. A change that makes a previously
78
- valid message invalid β€” a new required field, a narrowed bound, a removed
79
- enum member β€” is a **major**. Adding an optional field, a new enum member a
80
- client may ignore, or a description is a minor or a patch.
79
+ valid message invalid β€” a new required field, a narrowed bound, a removed enum
80
+ member β€” is a major. A new optional field, a new enum member a client may
81
+ ignore, or a better description is a minor or a patch.
81
82
 
82
83
  Pin an exact version. These shapes describe a running server, and "compatible
83
84
  with the server you are talking to" is not something a range can express.
84
85
 
85
- **The one dependency, `zod`, is deliberately a range and not a pin.** zod is a
86
- peer in everything but name: a consumer that imports both this package and zod
87
- must get one copy, or a schema from here fails an `instanceof` check against
88
- their own. An exact pin here forces a second copy on anyone whose lockfile
89
- resolves a different patch. The range floor is the version these schemas are
90
- built, tested and exported against, and a zod major is a major here too.
91
-
92
- ## Documentation
86
+ ## πŸ“š Documentation
93
87
 
94
88
  The API reference at
95
- [docs.fleetless.dev/reference/api](https://docs.fleetless.dev/reference/api) is
96
- generated from these artifacts and is the place to read what a field means.
97
- This package is the place to read what it *is*.
98
-
99
- ## Reporting a security issue
100
-
101
- Email **security@fleetless.dev**. Please do not open a public issue for a
102
- security report.
89
+ [docs.fleetless.dev/reference/api](https://docs.fleetless.dev/reference/api)
90
+ is generated from these artifacts. Read it for what a field *means*; this
91
+ package is for what it *is*. [CHANGELOG.md](CHANGELOG.md) lists what moved in
92
+ each version.
103
93
 
104
- **A wrong schema is a security report.** If a schema here accepts a value that
105
- should never reach a server β€” an identifier that escapes its own grammar, a
106
- missing bound, a union that admits a shape the API does not expect β€” that is a
107
- vulnerability in this package, even though nothing in it executes anything. So
108
- is a generated artifact that disagrees with the zod schema it came from, because
109
- consumers that are not TypeScript validate against the artifact and never see
110
- the zod.
94
+ ## πŸ”’ Reporting a security issue
111
95
 
112
- `SECURITY.md` ships inside the published package and has the full policy: what
113
- is in scope, what is not, and the response times we hold ourselves to.
96
+ Email **security@fleetless.dev** rather than opening a public issue. A wrong
97
+ schema is a security report: a bound that is missing, an identifier that
98
+ escapes its own grammar, or a generated artifact that disagrees with the zod
99
+ it came from. [SECURITY.md](SECURITY.md) has the full policy.
114
100
 
115
- ## Contributing
101
+ ## 🀝 Contributing
116
102
 
117
- `CONTRIBUTING.md` ships inside the published package and has the setup, the
118
- checks and the pull request process. In short: `pnpm install`, then `pnpm
119
- typecheck && pnpm test`; every schema change regenerates `artifacts/` with
120
- `pnpm artifacts` and commits it in the same commit.
103
+ [CONTRIBUTING.md](CONTRIBUTING.md) has the setup, the checks and the pull
104
+ request process. In short: `pnpm install`, then `pnpm typecheck && pnpm test`,
105
+ and every schema change regenerates `artifacts/` with `pnpm artifacts` in the
106
+ same commit.
121
107
 
122
- ## Licence
108
+ ## πŸ“œ Licence
123
109
 
124
110
  [Apache-2.0](LICENSE). Copyright 2026 Dehne Robotik GmbH.
package/SECURITY.md CHANGED
@@ -2,31 +2,31 @@
2
2
 
3
3
  ## Reporting a vulnerability
4
4
 
5
- Email **security@fleetless.dev**. Please do not open a public GitHub issue for
6
- a security report.
5
+ Email **security@fleetless.dev**. Do not open a public GitHub issue for a
6
+ security report.
7
7
 
8
- Include what you found, the schema or artifact it concerns, and β€” if you have
9
- one β€” a value that the schema accepts and should not, or rejects and should
10
- not. A minimal reproduction against a published version of this package is the
11
- most useful thing you can send.
8
+ Tell us what you found and which schema or artifact it concerns. If you have
9
+ one, include a value the schema wrongly accepts or wrongly rejects. A minimal
10
+ reproduction against a published version of this package is the most useful
11
+ thing you can send.
12
12
 
13
- We acknowledge every report within **3 working days** and follow up with
14
- either a fix or a written plan within **30 days**. If a report leads to a
15
- released fix, we credit you by name unless you ask us not to.
13
+ We acknowledge every report within **3 working days** and follow up with a fix
14
+ or a written plan within **30 days**. A released fix credits you by name
15
+ unless you ask us not to.
16
16
 
17
17
  ## What is in scope
18
18
 
19
- This repository is a schema library. It defines the wire shapes of the
19
+ This repository is a schema library: it defines the wire shapes of the
20
20
  Fleetless API and the bridge–cloud protocol as zod schemas, and exports them
21
21
  as JSON Schema and OpenAPI documents under `artifacts/`.
22
22
 
23
- **A wrong schema is a security report.** If a schema accepts a value that
24
- should never reach a server β€” an identifier that escapes its own grammar, a
25
- bound that is missing, a union that admits a shape the API does not expect, a
26
- field that a validator lets through unchecked β€” that is a vulnerability in
27
- this package, even though nothing here executes it. The same is true of a
28
- generated artifact that disagrees with the zod schema it came from, because
29
- non-TypeScript consumers validate against the artifact and never see the zod.
23
+ **A wrong schema is a security report.** A schema that accepts a value that
24
+ should never reach a server β€” an identifier escaping its own grammar, a
25
+ missing bound, a union admitting a shape the API does not expect, a field a
26
+ validator lets through unchecked β€” is a vulnerability in this package, even
27
+ though nothing here executes it. So is a generated artifact that disagrees
28
+ with the zod schema it came from: non-TypeScript consumers validate against
29
+ the artifact and never see the zod.
30
30
 
31
31
  So, in scope:
32
32
 
@@ -40,16 +40,16 @@ So, in scope:
40
40
 
41
41
  **The Fleetless cloud is not in this repository.** A server that fails to
42
42
  enforce a schema, an authentication or authorisation flaw, a rate limit, a
43
- data leak from an API endpoint β€” none of those live here, and none of them can
44
- be fixed by a change to this package. Report them to the same address; say
45
- which service you were looking at, and we will route it. What we cannot do is
46
- treat this repository's issue tracker as the place where they are tracked.
43
+ data leak from an API endpoint β€” none of that lives here, and none of it can
44
+ be fixed by a change to this package. Report it to the same address, say
45
+ which service you were looking at, and we will route it. This repository's
46
+ issue tracker is not where they get tracked.
47
47
 
48
48
  Also out of scope here: the Fleetless console, the bridge, the SDK, the
49
49
  documentation site, and any deployment of Fleetless operated by someone else.
50
50
 
51
51
  ## Supported versions
52
52
 
53
- The latest published minor of `@fleetless/contracts` receives fixes. Older
54
- minors do not; a security fix is released as a new patch on the current minor,
55
- and consumers pin exact versions, so upgrading is the remedy.
53
+ The latest published minor of `@fleetless/contracts` gets fixes. Older minors
54
+ don't β€” a security fix is released as a new patch on the current minor, and
55
+ since consumers pin exact versions, upgrading is the remedy.