@fleetless/contracts 1.0.0 → 1.0.3
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.
- package/CHANGELOG.md +97 -2
- package/CODE_OF_CONDUCT.md +83 -0
- package/CONTRIBUTING.md +136 -0
- package/README.md +49 -13
- package/SECURITY.md +55 -0
- package/artifacts/openapi.json +11 -11
- package/artifacts/routes.json +12 -12
- package/artifacts/schema/create-app-oidc-provider-request.schema.json +1 -1
- package/dist/alerts.d.ts +23 -28
- package/dist/alerts.js +23 -29
- package/dist/app-users.d.ts +18 -19
- package/dist/app-users.js +18 -20
- package/dist/apps.d.ts +21 -25
- package/dist/apps.js +42 -52
- package/dist/assets.d.ts +70 -132
- package/dist/assets.js +130 -223
- package/dist/audit.d.ts +14 -15
- package/dist/audit.js +28 -55
- package/dist/client-auth.d.ts +9 -9
- package/dist/client-auth.js +8 -9
- package/dist/common.d.ts +29 -37
- package/dist/common.js +28 -37
- package/dist/config-issues.d.ts +23 -25
- package/dist/config-issues.js +17 -17
- package/dist/config.d.ts +37 -44
- package/dist/config.js +145 -187
- package/dist/errors.d.ts +4 -3
- package/dist/errors.js +83 -116
- package/dist/identity.d.ts +24 -27
- package/dist/identity.js +23 -27
- package/dist/index.d.ts +4 -4
- package/dist/index.js +14 -15
- package/dist/introspection.d.ts +7 -6
- package/dist/introspection.js +6 -6
- package/dist/jobs.d.ts +16 -16
- package/dist/jobs.js +24 -29
- package/dist/mcp.d.ts +14 -15
- package/dist/mcp.js +12 -14
- package/dist/oauth.d.ts +21 -27
- package/dist/oauth.js +33 -43
- package/dist/protocol.d.ts +51 -62
- package/dist/protocol.js +107 -139
- package/dist/realtime.d.ts +53 -68
- package/dist/realtime.js +78 -104
- package/dist/rest.d.ts +183 -244
- package/dist/rest.js +305 -399
- package/dist/routes.d.ts +4 -3
- package/dist/routes.js +33 -32
- package/package.json +12 -7
package/dist/identity.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
/**
|
|
3
4
|
* **Fleetless users: the org's team, and the only people who reach the
|
|
4
|
-
* console
|
|
5
|
+
* console.**
|
|
5
6
|
*
|
|
6
7
|
* There are two identity spaces now and **nothing joins them**:
|
|
7
8
|
*
|
|
@@ -16,7 +17,7 @@ import { z } from 'zod';
|
|
|
16
17
|
* A Fleetless user who wants to use an app registers or is invited like
|
|
17
18
|
* anybody else; there is no path from one space to the other.
|
|
18
19
|
*
|
|
19
|
-
* **What that deleted, with no successor
|
|
20
|
+
* **What that deleted, with no successor**: groups and the Org Admins
|
|
20
21
|
* group, app assignments, impersonation, the per-user MCP override and the
|
|
21
22
|
* org-level federation policy. The 2026-08-29 model had put developers and end
|
|
22
23
|
* users into one pool per org and connected them with all of the above; in use
|
|
@@ -48,7 +49,7 @@ export declare const password: z.ZodString;
|
|
|
48
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. */
|
|
49
50
|
export declare const USER_DISPLAY_NAME_MAX = 120;
|
|
50
51
|
/**
|
|
51
|
-
* **The two tiers a Fleetless user can hold
|
|
52
|
+
* **The two tiers a Fleetless user can hold**. Owner-exclusive: delete
|
|
52
53
|
* the org, edit org settings, promote to owner, and later billing. Everything
|
|
53
54
|
* else a Fleetless user may do, a `developer` may do.
|
|
54
55
|
*
|
|
@@ -96,7 +97,7 @@ export type PatchOrgResponse = z.infer<typeof patchOrgResponse>;
|
|
|
96
97
|
* central endpoint), and `has_password`. The last is the interesting one — it
|
|
97
98
|
* existed because a pool user might have been provisioned by an identity
|
|
98
99
|
* provider and hold no Fleetless credential. A Fleetless user always holds
|
|
99
|
-
* one: the console is password-only by design
|
|
100
|
+
* one: the console is password-only by design, which removes the
|
|
100
101
|
* IdP-lockout class entirely, so a field reporting whether the credential
|
|
101
102
|
* exists would have exactly one value forever.
|
|
102
103
|
*/
|
|
@@ -128,7 +129,7 @@ export declare const fleetlessUserListResponse: z.ZodObject<{
|
|
|
128
129
|
}, z.core.$strip>;
|
|
129
130
|
export type FleetlessUserListResponse = z.infer<typeof fleetlessUserListResponse>;
|
|
130
131
|
/**
|
|
131
|
-
* Access plus refresh
|
|
132
|
+
* Access plus refresh. The access token is short-lived; the
|
|
132
133
|
* refresh token rotates on every use, so a stolen one is detectable when the
|
|
133
134
|
* original is presented again.
|
|
134
135
|
*
|
|
@@ -146,8 +147,8 @@ export declare const refreshRequest: z.ZodObject<{
|
|
|
146
147
|
}, z.core.$strip>;
|
|
147
148
|
export type RefreshRequest = z.infer<typeof refreshRequest>;
|
|
148
149
|
/**
|
|
149
|
-
* Registering an org creates the org and its first owner in one step
|
|
150
|
-
*
|
|
150
|
+
* Registering an org creates the org and its first owner in one step: whoever
|
|
151
|
+
* registers the organisation is the owner.
|
|
151
152
|
*/
|
|
152
153
|
export declare const signUpRequest: z.ZodObject<{
|
|
153
154
|
org_name: z.ZodString;
|
|
@@ -204,7 +205,7 @@ export declare const waitlistRequest: z.ZodObject<{
|
|
|
204
205
|
export type WaitlistRequest = z.infer<typeof waitlistRequest>;
|
|
205
206
|
/**
|
|
206
207
|
* Console login. Fleetless users only, always the Fleetless password — the
|
|
207
|
-
* console has no federated door at all
|
|
208
|
+
* console has no federated door at all, which removes the IdP-lockout
|
|
208
209
|
* class entirely.
|
|
209
210
|
*
|
|
210
211
|
* This resolves a person by address alone, and a Fleetless user's email is
|
|
@@ -222,7 +223,7 @@ export declare const developerLoginRequest: z.ZodObject<{
|
|
|
222
223
|
}, z.core.$strip>;
|
|
223
224
|
export type DeveloperLoginRequest = z.infer<typeof developerLoginRequest>;
|
|
224
225
|
/**
|
|
225
|
-
* What happened to the mail, in four words instead of one
|
|
226
|
+
* What happened to the mail, in four words instead of one.
|
|
226
227
|
*
|
|
227
228
|
* `mail_sent: boolean` could not tell **"we have no SMTP configured"** from
|
|
228
229
|
* **"we tried and the server refused"**, so the console had to pick a sentence
|
|
@@ -387,10 +388,10 @@ export declare const tierChangeRequest: z.ZodObject<{
|
|
|
387
388
|
export type TierChangeRequest = z.infer<typeof tierChangeRequest>;
|
|
388
389
|
/**
|
|
389
390
|
* What a `forbidden` refusal carries when the reason is the caller's **tier**
|
|
390
|
-
* rather than a missing grant
|
|
391
|
+
* rather than a missing grant.
|
|
391
392
|
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
393
|
+
* `forbidden` is deliberately silent about *existence*, and that stays true —
|
|
394
|
+
* this says nothing about what the target is. But "your role does not
|
|
394
395
|
* permit this" and "there is no such thing" are the same answer today, and a
|
|
395
396
|
* developer cannot tell *ask an owner* from *you have the wrong id*. Naming
|
|
396
397
|
* the required tier reveals only what the caller could read off the docs.
|
|
@@ -429,8 +430,8 @@ export type PasswordChangeRequest = z.infer<typeof passwordChangeRequest>;
|
|
|
429
430
|
*
|
|
430
431
|
* **The response never says whether the address exists.** It is unauthenticated
|
|
431
432
|
* and would otherwise be an account-enumeration oracle — the one place where
|
|
432
|
-
*
|
|
433
|
-
*
|
|
433
|
+
* revealing nothing about what exists is not a preference but the whole point.
|
|
434
|
+
* So this answers the same way for a known and an unknown address, in
|
|
434
435
|
* status, body **and timing**, and any consumer that renders "no such account"
|
|
435
436
|
* from it has reintroduced the oracle.
|
|
436
437
|
*
|
|
@@ -463,24 +464,20 @@ export type PasswordResetConfirm = z.infer<typeof passwordResetConfirm>;
|
|
|
463
464
|
* An IdP issuer URL — **an attacker-supplied string that decides where the
|
|
464
465
|
* *server* connects.**
|
|
465
466
|
*
|
|
466
|
-
* `redirectUri` in `oauth.ts`
|
|
467
|
-
* loopback allow-list
|
|
468
|
-
*
|
|
469
|
-
* the
|
|
470
|
-
*
|
|
471
|
-
* through the app's IdP route, then caught the outbound discovery fetch on a
|
|
472
|
-
* listener he stood up. **That is this project's own question — which rules
|
|
473
|
-
* have we already written down, and where else do they apply — answered badly,
|
|
474
|
-
* one field over.**
|
|
467
|
+
* `redirectUri` in `oauth.ts` carries a parsed scheme check and an explicit
|
|
468
|
+
* loopback allow-list because it decides where a *credential* goes. A bare
|
|
469
|
+
* `z.url()` here would accept `file:///etc/passwd`, a cloud metadata address or
|
|
470
|
+
* an internal database host, and the server would then fetch it during issuer
|
|
471
|
+
* discovery. The same rule applies one field over.
|
|
475
472
|
*
|
|
476
473
|
* **What this shape can decide, it now decides:** http(s) only (so no `file:`,
|
|
477
474
|
* `gopher:`, `data:`), no credentials in the URL, no fragment, no query. RFC
|
|
478
|
-
* 8414
|
|
475
|
+
* 8414 builds the discovery URL from the issuer's path, so a query string
|
|
479
476
|
* there is meaningless and a `@` is a redirect trick.
|
|
480
477
|
*
|
|
481
478
|
* **What it cannot decide, stated rather than implied:** it cannot tell
|
|
482
|
-
* `http://localhost:8081
|
|
483
|
-
*
|
|
479
|
+
* a development identity provider on `http://localhost:8081` from a database
|
|
480
|
+
* on `http://127.0.0.1:5432`. Both are loopback http. So **this is
|
|
484
481
|
* not the SSRF defence and must not be mistaken for one.** The defence belongs
|
|
485
482
|
* at the fetch, in the cloud: refuse loopback, link-local and private ranges
|
|
486
483
|
* unless something explicitly opts in for development, and it names DNS
|
|
@@ -498,7 +495,7 @@ export type IdpIssuer = z.infer<typeof idpIssuer>;
|
|
|
498
495
|
* here.** `oidcCallbackErrorCode` and `oidcCallbackError` described the page
|
|
499
496
|
* `GET /mcp/oauth/idp-callback` rendered when a group's identity provider sent
|
|
500
497
|
* a browser back — `jit_disabled` and `email_collision` name provisioning steps
|
|
501
|
-
* only a group provider had.
|
|
498
|
+
* only a group provider had. Fleetless users are password-only now, which deletes
|
|
502
499
|
* group providers, so the flow that produced these codes cannot start; the
|
|
503
500
|
* route is gone from this manifest and from the cloud.
|
|
504
501
|
*
|
package/dist/identity.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
/**
|
|
4
4
|
* **Fleetless users: the org's team, and the only people who reach the
|
|
5
|
-
* console
|
|
5
|
+
* console.**
|
|
6
6
|
*
|
|
7
7
|
* There are two identity spaces now and **nothing joins them**:
|
|
8
8
|
*
|
|
@@ -17,7 +17,7 @@ import { z } from 'zod';
|
|
|
17
17
|
* A Fleetless user who wants to use an app registers or is invited like
|
|
18
18
|
* anybody else; there is no path from one space to the other.
|
|
19
19
|
*
|
|
20
|
-
* **What that deleted, with no successor
|
|
20
|
+
* **What that deleted, with no successor**: groups and the Org Admins
|
|
21
21
|
* group, app assignments, impersonation, the per-user MCP override and the
|
|
22
22
|
* org-level federation policy. The 2026-08-29 model had put developers and end
|
|
23
23
|
* users into one pool per org and connected them with all of the above; in use
|
|
@@ -49,7 +49,7 @@ export const password = z.string().min(12).max(256);
|
|
|
49
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
50
|
export const USER_DISPLAY_NAME_MAX = 120;
|
|
51
51
|
/**
|
|
52
|
-
* **The two tiers a Fleetless user can hold
|
|
52
|
+
* **The two tiers a Fleetless user can hold**. Owner-exclusive: delete
|
|
53
53
|
* the org, edit org settings, promote to owner, and later billing. Everything
|
|
54
54
|
* else a Fleetless user may do, a `developer` may do.
|
|
55
55
|
*
|
|
@@ -95,7 +95,7 @@ export const patchOrgResponse = z.object({
|
|
|
95
95
|
* central endpoint), and `has_password`. The last is the interesting one — it
|
|
96
96
|
* existed because a pool user might have been provisioned by an identity
|
|
97
97
|
* provider and hold no Fleetless credential. A Fleetless user always holds
|
|
98
|
-
* one: the console is password-only by design
|
|
98
|
+
* one: the console is password-only by design, which removes the
|
|
99
99
|
* IdP-lockout class entirely, so a field reporting whether the credential
|
|
100
100
|
* exists would have exactly one value forever.
|
|
101
101
|
*/
|
|
@@ -126,7 +126,7 @@ export const fleetlessUserListResponse = z.object({
|
|
|
126
126
|
}),
|
|
127
127
|
});
|
|
128
128
|
/**
|
|
129
|
-
* Access plus refresh
|
|
129
|
+
* Access plus refresh. The access token is short-lived; the
|
|
130
130
|
* refresh token rotates on every use, so a stolen one is detectable when the
|
|
131
131
|
* original is presented again.
|
|
132
132
|
*
|
|
@@ -146,8 +146,8 @@ export const sessionTokens = z.object({
|
|
|
146
146
|
});
|
|
147
147
|
export const refreshRequest = z.object({ refresh_token: z.string().min(1) });
|
|
148
148
|
/**
|
|
149
|
-
* Registering an org creates the org and its first owner in one step
|
|
150
|
-
*
|
|
149
|
+
* Registering an org creates the org and its first owner in one step: whoever
|
|
150
|
+
* registers the organisation is the owner.
|
|
151
151
|
*/
|
|
152
152
|
export const signUpRequest = z.object({
|
|
153
153
|
org_name: z.string().min(1).max(120),
|
|
@@ -181,7 +181,7 @@ export const signUpResponse = z.object({
|
|
|
181
181
|
export const waitlistRequest = z.object({ email: z.email().max(254) });
|
|
182
182
|
/**
|
|
183
183
|
* Console login. Fleetless users only, always the Fleetless password — the
|
|
184
|
-
* console has no federated door at all
|
|
184
|
+
* console has no federated door at all, which removes the IdP-lockout
|
|
185
185
|
* class entirely.
|
|
186
186
|
*
|
|
187
187
|
* This resolves a person by address alone, and a Fleetless user's email is
|
|
@@ -198,7 +198,7 @@ export const developerLoginRequest = z.object({
|
|
|
198
198
|
password: z.string().min(1),
|
|
199
199
|
});
|
|
200
200
|
/**
|
|
201
|
-
* What happened to the mail, in four words instead of one
|
|
201
|
+
* What happened to the mail, in four words instead of one.
|
|
202
202
|
*
|
|
203
203
|
* `mail_sent: boolean` could not tell **"we have no SMTP configured"** from
|
|
204
204
|
* **"we tried and the server refused"**, so the console had to pick a sentence
|
|
@@ -353,10 +353,10 @@ export const patchFleetlessUserRequest = z
|
|
|
353
353
|
export const tierChangeRequest = z.object({ tier: orgAdminTier }).strict();
|
|
354
354
|
/**
|
|
355
355
|
* What a `forbidden` refusal carries when the reason is the caller's **tier**
|
|
356
|
-
* rather than a missing grant
|
|
356
|
+
* rather than a missing grant.
|
|
357
357
|
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
358
|
+
* `forbidden` is deliberately silent about *existence*, and that stays true —
|
|
359
|
+
* this says nothing about what the target is. But "your role does not
|
|
360
360
|
* permit this" and "there is no such thing" are the same answer today, and a
|
|
361
361
|
* developer cannot tell *ask an owner* from *you have the wrong id*. Naming
|
|
362
362
|
* the required tier reveals only what the caller could read off the docs.
|
|
@@ -392,8 +392,8 @@ export const passwordChangeRequest = z.object({
|
|
|
392
392
|
*
|
|
393
393
|
* **The response never says whether the address exists.** It is unauthenticated
|
|
394
394
|
* and would otherwise be an account-enumeration oracle — the one place where
|
|
395
|
-
*
|
|
396
|
-
*
|
|
395
|
+
* revealing nothing about what exists is not a preference but the whole point.
|
|
396
|
+
* So this answers the same way for a known and an unknown address, in
|
|
397
397
|
* status, body **and timing**, and any consumer that renders "no such account"
|
|
398
398
|
* from it has reintroduced the oracle.
|
|
399
399
|
*
|
|
@@ -424,24 +424,20 @@ export const passwordResetConfirm = z.object({
|
|
|
424
424
|
* An IdP issuer URL — **an attacker-supplied string that decides where the
|
|
425
425
|
* *server* connects.**
|
|
426
426
|
*
|
|
427
|
-
* `redirectUri` in `oauth.ts`
|
|
428
|
-
* loopback allow-list
|
|
429
|
-
*
|
|
430
|
-
* the
|
|
431
|
-
*
|
|
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.**
|
|
427
|
+
* `redirectUri` in `oauth.ts` carries a parsed scheme check and an explicit
|
|
428
|
+
* loopback allow-list because it decides where a *credential* goes. A bare
|
|
429
|
+
* `z.url()` here would accept `file:///etc/passwd`, a cloud metadata address or
|
|
430
|
+
* an internal database host, and the server would then fetch it during issuer
|
|
431
|
+
* discovery. The same rule applies one field over.
|
|
436
432
|
*
|
|
437
433
|
* **What this shape can decide, it now decides:** http(s) only (so no `file:`,
|
|
438
434
|
* `gopher:`, `data:`), no credentials in the URL, no fragment, no query. RFC
|
|
439
|
-
* 8414
|
|
435
|
+
* 8414 builds the discovery URL from the issuer's path, so a query string
|
|
440
436
|
* there is meaningless and a `@` is a redirect trick.
|
|
441
437
|
*
|
|
442
438
|
* **What it cannot decide, stated rather than implied:** it cannot tell
|
|
443
|
-
* `http://localhost:8081
|
|
444
|
-
*
|
|
439
|
+
* a development identity provider on `http://localhost:8081` from a database
|
|
440
|
+
* on `http://127.0.0.1:5432`. Both are loopback http. So **this is
|
|
445
441
|
* not the SSRF defence and must not be mistaken for one.** The defence belongs
|
|
446
442
|
* at the fetch, in the cloud: refuse loopback, link-local and private ranges
|
|
447
443
|
* unless something explicitly opts in for development, and it names DNS
|
|
@@ -476,7 +472,7 @@ export const idpIssuer = z
|
|
|
476
472
|
* here.** `oidcCallbackErrorCode` and `oidcCallbackError` described the page
|
|
477
473
|
* `GET /mcp/oauth/idp-callback` rendered when a group's identity provider sent
|
|
478
474
|
* a browser back — `jit_disabled` and `email_collision` name provisioning steps
|
|
479
|
-
* only a group provider had.
|
|
475
|
+
* only a group provider had. Fleetless users are password-only now, which deletes
|
|
480
476
|
* group providers, so the flow that produced these codes cannot start; the
|
|
481
477
|
* route is gone from this manifest and from the cloud.
|
|
482
478
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
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';
|
|
2
3
|
export type { ApplyErrorKind, ApplyError } from './common.js';
|
|
3
4
|
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';
|
|
@@ -12,10 +13,9 @@ export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec,
|
|
|
12
13
|
export type { CameraSource } from './config.js';
|
|
13
14
|
export type { ParameterType, ParameterSpec, ActionConfig, ServiceConfig, PublisherConfig, CameraConfig, CameraCredentials, AlertCondition, DatapointAlert, DatapointNumeric, DatapointRetention, DatapointChart, DatapointConfig, RobotConfigDoc, ValidationIssue, ConfigState, } from './config.js';
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `config-issues.ts`'s header for what that window cost.
|
|
16
|
+
* The one account of what is wrong with a configuration document, shared by
|
|
17
|
+
* every layer that reports on one. See `config-issues.ts`'s header for why a
|
|
18
|
+
* second copy of this vocabulary is a defect rather than a convenience.
|
|
19
19
|
*/
|
|
20
20
|
export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
|
|
21
21
|
export type { SchemaIssue, ExposureSection } from './config-issues.js';
|
package/dist/index.js
CHANGED
|
@@ -2,46 +2,45 @@
|
|
|
2
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
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
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
|
-
//
|
|
5
|
+
// Assets.
|
|
6
6
|
bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress,
|
|
7
|
-
//
|
|
7
|
+
// Addressing.
|
|
8
8
|
activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, } from './protocol.js';
|
|
9
9
|
export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
|
|
10
10
|
export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
|
|
11
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
|
-
//
|
|
12
|
+
// The defaults the format names, so nobody invents them twice.
|
|
13
13
|
ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT,
|
|
14
|
-
//
|
|
14
|
+
// Retention, history and quotas.
|
|
15
15
|
cameraSource, cameraCredentials, } from './config.js';
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* `config-issues.ts`'s header for what that window cost.
|
|
17
|
+
* The one account of what is wrong with a configuration document, shared by
|
|
18
|
+
* every layer that reports on one. See `config-issues.ts`'s header for why a
|
|
19
|
+
* second copy of this vocabulary is a defect rather than a convenience.
|
|
21
20
|
*/
|
|
22
21
|
export { DOCUMENT_ROOT_PATH, EXPOSURE_SECTIONS, schemaIssues, formatPath, splitFormatPath, configSchemaHash, } from './config-issues.js';
|
|
23
22
|
export { rosGraphEntry, rosGraph, typeField, typeDefinition, parameterFieldsOf } from './introspection.js';
|
|
24
23
|
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
|
-
//
|
|
24
|
+
// Addressing.
|
|
26
25
|
cancelRequest, releaseLiveQuery, serviceCallResponse, invokeOrServiceResponse, publishRequest, jobResponse, robotJobsResponse, rateLimitDetails, exposure, exposureListResponse, SNAPSHOT_HEADERS, ASSET_UPLOAD_HEADERS, cameraDescriptor, cameraListResponse, liveSessionResponse, snapshotMetaResponse,
|
|
27
|
-
//
|
|
26
|
+
// Retention, history, quotas.
|
|
28
27
|
historyQuery, historySamplesResponse, historyBucketsResponse, historyResponse, orgQuotas, orgQuotaUsage, orgQuotaUsageCounts, robotDeletionSummary, RESOURCE_HEALTH_STATES, resourceHealthState, resourceHealthListResponse, orgHealthQuery, robotDeleteQuery,
|
|
29
|
-
//
|
|
28
|
+
// Robot rename, slug rename.
|
|
30
29
|
patchRobotRequest, renameSlugRequest, renameSlugResponse, slugUsageResponse, } from './rest.js';
|
|
31
30
|
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
31
|
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
32
|
export { password, org, patchOrgResponse, sessionTokens, refreshRequest, signUpRequest, signUpResponse,
|
|
34
33
|
// 2026-09-04 — the public site (closed beta).
|
|
35
34
|
waitlistRequest, developerLoginRequest,
|
|
36
|
-
//
|
|
35
|
+
// The two identity spaces.
|
|
37
36
|
USER_DISPLAY_NAME_MAX, orgAdminTier, fleetlessUser, fleetlessUserListResponse, createTeamInviteRequest, teamInvite, pendingTeamInvite, pendingTeamInviteListResponse, acceptTeamInviteRequest, patchFleetlessUserRequest, tierChangeRequest,
|
|
38
|
-
//
|
|
37
|
+
// Identity.
|
|
39
38
|
mailStatus, tierRequiredDetails, passwordChangeRequest, passwordResetRequest, passwordResetConfirm, idpIssuer,
|
|
40
|
-
//
|
|
39
|
+
// auth/me, org and member patches.
|
|
41
40
|
authMeResponse, patchOrgRequest, patchAuthMeRequest, } from './identity.js';
|
|
42
41
|
export { appIdentifier, app, appListResponse, createAppRequest, updateAppRequest, serverKeyToken, serverKey, serverKeyListResponse, createServerKeyResponse, role, roleListResponse, rolePermissions, } from './apps.js';
|
|
43
42
|
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
|
-
//
|
|
43
|
+
// The per-app identity space.
|
|
45
44
|
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
45
|
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
46
|
export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
|
package/dist/introspection.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
/**
|
|
3
|
-
* Introspection
|
|
4
|
+
* Introspection: what the connected bridge can tell the
|
|
4
5
|
* cloud about the robot's ROS graph, so the console can offer a quick pick
|
|
5
6
|
* instead of a blank text field.
|
|
6
7
|
*
|
|
@@ -45,10 +46,10 @@ export interface TypeField {
|
|
|
45
46
|
}
|
|
46
47
|
export declare const typeField: z.ZodType<TypeField>;
|
|
47
48
|
/**
|
|
48
|
-
* A resolved type of one robot. Custom types are per robot
|
|
49
|
-
*
|
|
49
|
+
* A resolved type of one robot. Custom types are per robot: two robots may
|
|
50
|
+
* define `custom_msgs/msg/Speed` differently and both are right.
|
|
50
51
|
*
|
|
51
|
-
*
|
|
52
|
+
* Messages, services and actions all appear here, because a
|
|
52
53
|
* `parameterSpec.name` has to resolve against *something*, and an action has
|
|
53
54
|
* no flat field list — it has a goal, a result and a feedback tree.
|
|
54
55
|
*
|
|
@@ -65,8 +66,8 @@ export declare const typeField: z.ZodType<TypeField>;
|
|
|
65
66
|
* a result in. They are carried so the console can show what an action will
|
|
66
67
|
* report back, and so a client knows the shape of `job.result` in advance.
|
|
67
68
|
*
|
|
68
|
-
* The `msg` member
|
|
69
|
-
*
|
|
69
|
+
* The `msg` member is the flat field list a message resolves to; the other
|
|
70
|
+
* two carry one tree per part.
|
|
70
71
|
*/
|
|
71
72
|
export declare const typeDefinition: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
72
73
|
name: z.ZodString;
|
package/dist/introspection.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { rosName, rosTypeName } from './common.js';
|
|
4
4
|
/**
|
|
5
|
-
* Introspection
|
|
5
|
+
* Introspection: what the connected bridge can tell the
|
|
6
6
|
* cloud about the robot's ROS graph, so the console can offer a quick pick
|
|
7
7
|
* instead of a blank text field.
|
|
8
8
|
*
|
|
@@ -31,10 +31,10 @@ export const typeField = z.lazy(() => z.object({
|
|
|
31
31
|
fields: z.array(typeField).nullable(),
|
|
32
32
|
}));
|
|
33
33
|
/**
|
|
34
|
-
* A resolved type of one robot. Custom types are per robot
|
|
35
|
-
*
|
|
34
|
+
* A resolved type of one robot. Custom types are per robot: two robots may
|
|
35
|
+
* define `custom_msgs/msg/Speed` differently and both are right.
|
|
36
36
|
*
|
|
37
|
-
*
|
|
37
|
+
* Messages, services and actions all appear here, because a
|
|
38
38
|
* `parameterSpec.name` has to resolve against *something*, and an action has
|
|
39
39
|
* no flat field list — it has a goal, a result and a feedback tree.
|
|
40
40
|
*
|
|
@@ -51,8 +51,8 @@ export const typeField = z.lazy(() => z.object({
|
|
|
51
51
|
* a result in. They are carried so the console can show what an action will
|
|
52
52
|
* report back, and so a client knows the shape of `job.result` in advance.
|
|
53
53
|
*
|
|
54
|
-
* The `msg` member
|
|
55
|
-
*
|
|
54
|
+
* The `msg` member is the flat field list a message resolves to; the other
|
|
55
|
+
* two carry one tree per part.
|
|
56
56
|
*/
|
|
57
57
|
export const typeDefinition = z.discriminatedUnion('kind', [
|
|
58
58
|
z.object({
|
package/dist/jobs.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
/**
|
|
3
|
-
* Jobs
|
|
4
|
+
* Jobs: one running unit of work on a robot — an action
|
|
4
5
|
* goal or a service call — with an id both sides know, so bridge and cloud
|
|
5
6
|
* stay in sync across a disconnect.
|
|
6
7
|
*
|
|
7
8
|
* Two rules shape everything here:
|
|
8
9
|
*
|
|
9
|
-
* 1. **State is observed by slug, not by id.** The id is informative
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* 2. **`lost` is a real outcome and must be said out loud
|
|
10
|
+
* 1. **State is observed by slug, not by id.** The id is informative; a client
|
|
11
|
+
* watches `robot × slug` and sees whatever job is running there, which is
|
|
12
|
+
* also why every observer of a slug sees the same job.
|
|
13
|
+
* 2. **`lost` is a real outcome and must be said out loud.** Job state
|
|
13
14
|
* lives only in the bridge's memory; if it restarts mid-job, the results
|
|
14
15
|
* are gone. The cloud then marks the job `lost` — never leaves it reading
|
|
15
16
|
* "running" because nobody contradicted it. A system that reports a
|
|
@@ -49,8 +50,8 @@ export type Job = z.infer<typeof job>;
|
|
|
49
50
|
/**
|
|
50
51
|
* One update about a job, pushed to subscribers of its slug.
|
|
51
52
|
*
|
|
52
|
-
* `timestamp_ms` is the bridge's capture time, exactly as for a datapoint
|
|
53
|
-
*
|
|
53
|
+
* `timestamp_ms` is the bridge's capture time, exactly as for a datapoint —
|
|
54
|
+
* action feedback carries it too — so a client computes the age
|
|
54
55
|
* of a progress report the same way it computes the age of a sensor value,
|
|
55
56
|
* and a burst of late-delivered feedback after a reconnect is visibly late
|
|
56
57
|
* rather than looking current.
|
|
@@ -86,9 +87,8 @@ export declare const jobEvent: z.ZodObject<{
|
|
|
86
87
|
}, z.core.$strip>;
|
|
87
88
|
export type JobEvent = z.infer<typeof jobEvent>;
|
|
88
89
|
/**
|
|
89
|
-
* What a busy refusal tells the caller
|
|
90
|
-
*
|
|
91
|
-
* to wait or to give up.
|
|
90
|
+
* What a busy refusal tells the caller: what is already running. A refusal that
|
|
91
|
+
* only says "busy" forces the caller to guess whether to wait or to give up.
|
|
92
92
|
*/
|
|
93
93
|
export declare const busyDetails: z.ZodObject<{
|
|
94
94
|
running: z.ZodObject<{
|
|
@@ -115,7 +115,7 @@ export declare const busyDetails: z.ZodObject<{
|
|
|
115
115
|
}, z.core.$strip>;
|
|
116
116
|
export type BusyDetails = z.infer<typeof busyDetails>;
|
|
117
117
|
/**
|
|
118
|
-
* What a `publisher_busy` refusal tells the caller
|
|
118
|
+
* What a `publisher_busy` refusal tells the caller.
|
|
119
119
|
*
|
|
120
120
|
* "Another caller is publishing and has not been quiet long enough" names a
|
|
121
121
|
* state and no action: the caller does not know how much longer, because
|
|
@@ -133,7 +133,7 @@ export declare const publisherBusyDetails: z.ZodObject<{
|
|
|
133
133
|
}, z.core.$strip>;
|
|
134
134
|
export type PublisherBusyDetails = z.infer<typeof publisherBusyDetails>;
|
|
135
135
|
/**
|
|
136
|
-
* What a `job_queue_full` refusal tells the caller
|
|
136
|
+
* What a `job_queue_full` refusal tells the caller.
|
|
137
137
|
*
|
|
138
138
|
* Both numbers, not just the limit: `limit` alone says how big the queue is
|
|
139
139
|
* and nothing about whether waiting will help, and `queued` alone cannot be
|
|
@@ -163,7 +163,7 @@ export declare const JOB_RUN_RETENTION_DAYS = 90;
|
|
|
163
163
|
* invites every reader to handle it.
|
|
164
164
|
*
|
|
165
165
|
* **`app_user` is what a client-app caller writes now, and `end_user` stays**
|
|
166
|
-
*
|
|
166
|
+
* identity spaces. The seam this comment used to describe — two names for
|
|
167
167
|
* two ways into one merged pool — is settled: the two identity spaces are
|
|
168
168
|
* separate tables again, and `app_user` is a row in `app_users`, belonging to
|
|
169
169
|
* exactly one app. `end_user` is kept for the same reason `auditActor.kind`
|
|
@@ -188,10 +188,10 @@ export declare const jobRunKind: z.ZodEnum<{
|
|
|
188
188
|
}>;
|
|
189
189
|
export type JobRunKind = z.infer<typeof jobRunKind>;
|
|
190
190
|
/**
|
|
191
|
-
* One durable record of one invocation
|
|
192
|
-
*
|
|
191
|
+
* One durable record of one invocation. One row per run, never one per event:
|
|
192
|
+
* the per-event timeline's write rate
|
|
193
193
|
* is set by the bridge, and a throttled log that cannot say it was throttled is
|
|
194
|
-
*
|
|
194
|
+
* an instrument that cannot say what it does not know. The live timeline is
|
|
195
195
|
* delivered in full by realtime, for as long as somebody is watching.
|
|
196
196
|
*/
|
|
197
197
|
export declare const jobRun: z.ZodObject<{
|