@fleetless/contracts 1.0.5 → 1.1.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.
- package/CHANGELOG.md +17 -2
- package/CONTRIBUTING.md +100 -75
- package/README.md +69 -83
- package/SECURITY.md +24 -24
- package/artifacts/openapi.json +359 -65
- package/artifacts/routes.json +74 -3
- package/artifacts/schema/app-list-response.schema.json +2 -2
- package/artifacts/schema/app-oidc-provider-list-response.schema.json +1 -1
- package/artifacts/schema/app-oidc-provider.schema.json +1 -1
- package/artifacts/schema/app-user-list-response.schema.json +2 -2
- package/artifacts/schema/app-user.schema.json +2 -2
- package/artifacts/schema/app.schema.json +2 -2
- package/artifacts/schema/asset-list-response.schema.json +7 -7
- package/artifacts/schema/asset-sync-request.schema.json +1 -1
- package/artifacts/schema/asset-sync-status.schema.json +1 -1
- package/artifacts/schema/asset.schema.json +3 -3
- package/artifacts/schema/auth-me-response.schema.json +2 -2
- package/artifacts/schema/auth-ok.schema.json +1 -1
- package/artifacts/schema/authorization-server-metadata.schema.json +1 -1
- package/artifacts/schema/bridge-asset-progress.schema.json +1 -1
- package/artifacts/schema/busy-details.schema.json +3 -3
- package/artifacts/schema/client-identity.schema.json +1 -1
- package/artifacts/schema/client-login-request.schema.json +1 -1
- package/artifacts/schema/client-logout-request.schema.json +1 -1
- package/artifacts/schema/client-mcp-interaction.schema.json +1 -1
- package/artifacts/schema/client-robot-list-item.schema.json +70 -0
- package/artifacts/schema/client-robot-list-response.schema.json +83 -0
- package/artifacts/schema/cloud-config.schema.json +1 -1
- package/artifacts/schema/command-result.schema.json +3 -3
- package/artifacts/schema/config-draft-response.schema.json +1 -1
- package/artifacts/schema/config-version-response.schema.json +1 -1
- package/artifacts/schema/create-server-key-response.schema.json +1 -1
- package/artifacts/schema/datapoint-config.schema.json +1 -1
- package/artifacts/schema/datapoint-value.schema.json +2 -2
- package/artifacts/schema/dynamic-client-registration-request.schema.json +2 -2
- package/artifacts/schema/fleetless-user-list-response.schema.json +2 -2
- package/artifacts/schema/fleetless-user.schema.json +2 -2
- package/artifacts/schema/invoke-or-service-response.schema.json +4 -4
- package/artifacts/schema/invoke-response.schema.json +3 -3
- package/artifacts/schema/job-actor.schema.json +1 -1
- package/artifacts/schema/job-event.schema.json +3 -3
- package/artifacts/schema/job-response.schema.json +3 -3
- package/artifacts/schema/job-run-list-response.schema.json +2 -2
- package/artifacts/schema/job-run.schema.json +2 -2
- package/artifacts/schema/job.schema.json +3 -3
- package/artifacts/schema/mcp-consent-grant-list-response.schema.json +2 -2
- package/artifacts/schema/mcp-consent-grant.schema.json +2 -2
- package/artifacts/schema/oauth-authorize-query.schema.json +1 -1
- package/artifacts/schema/oauth-token-request.schema.json +1 -1
- package/artifacts/schema/patch-org-response.schema.json +1 -1
- package/artifacts/schema/patch-robot-response.schema.json +1 -1
- package/artifacts/schema/robot-config-doc.schema.json +1 -1
- package/artifacts/schema/robot-jobs-response.schema.json +3 -3
- package/artifacts/schema/role-list-response.schema.json +1 -1
- package/artifacts/schema/role.schema.json +1 -1
- package/artifacts/schema/server-key-list-response.schema.json +2 -2
- package/artifacts/schema/server-key.schema.json +1 -1
- package/artifacts/schema/service-call-response.schema.json +1 -1
- package/artifacts/schema/sign-up-response.schema.json +2 -2
- package/artifacts/schema/urdf-completeness.schema.json +2 -2
- package/artifacts/schema-outgoing/bridge-asset-progress.schema.json +1 -1
- package/dist/alerts.d.ts +15 -17
- package/dist/alerts.js +15 -17
- package/dist/app-users.d.ts +5 -6
- package/dist/app-users.js +9 -10
- package/dist/apps.d.ts +5 -6
- package/dist/apps.js +11 -12
- package/dist/assets.js +10 -13
- package/dist/audit.d.ts +10 -12
- package/dist/audit.js +14 -17
- package/dist/client-auth.d.ts +8 -9
- package/dist/client-auth.js +14 -15
- package/dist/client-robots.d.ts +37 -0
- package/dist/client-robots.js +30 -0
- package/dist/config-issues.d.ts +3 -3
- package/dist/config-issues.js +3 -3
- package/dist/config.d.ts +5 -6
- package/dist/config.js +7 -8
- package/dist/errors.d.ts +4 -4
- package/dist/errors.js +8 -9
- package/dist/identity.d.ts +4 -5
- package/dist/identity.js +7 -8
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/jobs.js +5 -5
- package/dist/mcp.d.ts +11 -9
- package/dist/mcp.js +8 -3
- package/dist/oauth.d.ts +8 -10
- package/dist/oauth.js +13 -15
- package/dist/protocol.d.ts +7 -8
- package/dist/protocol.js +20 -22
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js +4 -4
- package/dist/rest.js +4 -4
- package/dist/routes.js +40 -4
- package/package.json +1 -1
package/dist/protocol.js
CHANGED
|
@@ -10,8 +10,8 @@ import { rosTypeName } from './common.js';
|
|
|
10
10
|
* Bridge <-> cloud protocol, version 2.
|
|
11
11
|
*
|
|
12
12
|
* The version is exchanged in the hello handshake; the cloud refuses an
|
|
13
|
-
* incompatible bridge
|
|
14
|
-
*
|
|
13
|
+
* incompatible bridge: `protocol_mismatch`, which names both versions and
|
|
14
|
+
* reaches the robot's detail view as `last_hello_error`.
|
|
15
15
|
*
|
|
16
16
|
* **2 (2026-08-21):** `config_applied.errors` entries gained `kind` and `code`
|
|
17
17
|
* beside `message`. The check is `!==`, not a floor, so a bridge that is not
|
|
@@ -78,12 +78,11 @@ export { slug } from './common.js';
|
|
|
78
78
|
*
|
|
79
79
|
* It carries the **slug and the state**, not only the id, because the cloud's
|
|
80
80
|
* reconciliation needs both and had neither. Reading `active_job_ids` as bare
|
|
81
|
-
* uuids, a restarted cloud could
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* the row.
|
|
81
|
+
* uuids, a restarted cloud could only ask "is this job still alive?" for jobs
|
|
82
|
+
* it already knew about — not what the robot is doing, not whether a
|
|
83
|
+
* `running` job had actually finished while the cloud was down, and nothing
|
|
84
|
+
* at all about a job it never recorded because it crashed between minting the
|
|
85
|
+
* id and writing the row.
|
|
87
86
|
*
|
|
88
87
|
* `state` is the bridge's own current answer, not a history. A bridge that
|
|
89
88
|
* has a terminal result still in hand reports it here and the cloud writes it
|
|
@@ -103,22 +102,21 @@ export const bridgeHello = z.object({
|
|
|
103
102
|
/**
|
|
104
103
|
* Every job this bridge still knows about, right now.
|
|
105
104
|
*
|
|
106
|
-
* A reconnect and a restart look **identical** on the wire
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* `lost`.
|
|
105
|
+
* A reconnect and a restart look **identical** on the wire — same token,
|
|
106
|
+
* same version, same frame — but must end differently: after a dropped
|
|
107
|
+
* connection the running jobs are still running, after a restart their
|
|
108
|
+
* results are gone forever. Enumerating what the bridge still has settles
|
|
109
|
+
* it without either side guessing: the cloud marks every job it believed
|
|
110
|
+
* running that is *not* named here as `lost`.
|
|
113
111
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
112
|
+
* Deliberately needs no persistence at the bridge: a live process lists its
|
|
113
|
+
* live jobs, a process that just started lists none — exactly the truth
|
|
114
|
+
* the cloud needs. A breadcrumb file would only add a window in which the
|
|
115
|
+
* crash beat the write.
|
|
118
116
|
*
|
|
119
|
-
* Defaulted, so a bridge that sends no such field still parses;
|
|
120
|
-
*
|
|
121
|
-
*
|
|
117
|
+
* Defaulted, so a bridge that sends no such field still parses; no jobs
|
|
118
|
+
* and no report both mean the same thing to the cloud: nothing to keep
|
|
119
|
+
* alive.
|
|
122
120
|
*/
|
|
123
121
|
active_jobs: z.array(activeJob).max(500).default([]),
|
|
124
122
|
});
|
package/dist/realtime.d.ts
CHANGED
|
@@ -254,8 +254,8 @@ export type DatapointEvent = z.infer<typeof datapointEvent>;
|
|
|
254
254
|
*/
|
|
255
255
|
export declare const liveSessionEndReason: z.ZodEnum<{
|
|
256
256
|
unknown: "unknown";
|
|
257
|
-
robot_offline: "robot_offline";
|
|
258
257
|
publish_failed: "publish_failed";
|
|
258
|
+
robot_offline: "robot_offline";
|
|
259
259
|
released_by_peer: "released_by_peer";
|
|
260
260
|
config_changed: "config_changed";
|
|
261
261
|
revoked: "revoked";
|
|
@@ -285,8 +285,8 @@ export declare const liveSessionEvent: z.ZodObject<{
|
|
|
285
285
|
state: z.ZodLiteral<"ended">;
|
|
286
286
|
reason: z.ZodEnum<{
|
|
287
287
|
unknown: "unknown";
|
|
288
|
-
robot_offline: "robot_offline";
|
|
289
288
|
publish_failed: "publish_failed";
|
|
289
|
+
robot_offline: "robot_offline";
|
|
290
290
|
released_by_peer: "released_by_peer";
|
|
291
291
|
config_changed: "config_changed";
|
|
292
292
|
revoked: "revoked";
|
package/dist/realtime.js
CHANGED
|
@@ -324,10 +324,10 @@ export const liveSessionEvent = z.object({
|
|
|
324
324
|
/**
|
|
325
325
|
* **Classified text the cloud produced, never text the robot sent.**
|
|
326
326
|
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
327
|
+
* Nothing sanitises `bridgeCameraState.error.message`, and a camera
|
|
328
|
+
* password reaches a developer surface through exactly that route — which
|
|
329
|
+
* is why the cloud maps a robot's diagnosis to fixed strings rather than
|
|
330
|
+
* forwarding it.
|
|
331
331
|
*
|
|
332
332
|
* So: `null` unless the cloud itself has something classified to say. If a
|
|
333
333
|
* developer needs the robot's own diagnosis later, it arrives as a mapped
|
package/dist/rest.js
CHANGED
|
@@ -23,7 +23,7 @@ export const robot = z.object({
|
|
|
23
23
|
/** What `PATCH /api/robots/:id` answers: the robot as it now stands. */
|
|
24
24
|
export const patchRobotResponse = z.object({
|
|
25
25
|
robot: robot.meta({
|
|
26
|
-
description: 'The robot as it now stands, after the patch
|
|
26
|
+
description: 'The robot as it now stands, after the patch. The whole resource comes back, not only the changed fields.',
|
|
27
27
|
}),
|
|
28
28
|
});
|
|
29
29
|
export const createRobotRequest = z.object({
|
|
@@ -85,10 +85,10 @@ export const robotListResponse = z.object({
|
|
|
85
85
|
export const datapointValue = z.object({
|
|
86
86
|
slug: slug.meta({ description: 'The datapoint this value belongs to.' }),
|
|
87
87
|
value: z.unknown().meta({
|
|
88
|
-
description: 'The value
|
|
88
|
+
description: 'The value, shaped by the datapoint: a number, a boolean, a string, or the whole ROS message where the configuration names no field inside it. Any `scale` and `offset` the configuration declares have already been applied, at the robot.',
|
|
89
89
|
}),
|
|
90
90
|
timestamp_ms: z.number().int().nonnegative().meta({
|
|
91
|
-
description: 'When the value was captured, as a unix timestamp in milliseconds.
|
|
91
|
+
description: 'When the value was captured, as a unix timestamp in milliseconds. The **bridge\'s capture time**, never the time the cloud received it — the one exception is the built-in `bridge_state`, which the cloud observes by construction.',
|
|
92
92
|
}),
|
|
93
93
|
});
|
|
94
94
|
/* ------------------------------------------------------------------------
|
|
@@ -396,7 +396,7 @@ export const invokeResponse = z.object({
|
|
|
396
396
|
/** A service call answers with its result directly — no job to observe. */
|
|
397
397
|
export const serviceCallResponse = z.object({
|
|
398
398
|
result: z.unknown().meta({
|
|
399
|
-
description: 'What the service returned, shaped by the ROS service
|
|
399
|
+
description: 'What the service returned, shaped by the ROS service. A service call is awaited to completion, so there is no job to observe afterwards and no id to hold on to.',
|
|
400
400
|
}),
|
|
401
401
|
});
|
|
402
402
|
/**
|
package/dist/routes.js
CHANGED
|
@@ -4,10 +4,11 @@ import { alertListResponse, orgAlertsQuery, orgFiringAlertsResponse } from './al
|
|
|
4
4
|
import { asset, assetListResponse, assetSyncRequest, assetSyncResponse, assetSyncStatus, missingAssetQuery } from './assets.js';
|
|
5
5
|
import { auditListResponse, auditQuery } from './audit.js';
|
|
6
6
|
import { CLIENT_OIDC_CALLBACK_PATH, clientAcceptInvitationRequest, clientIdentity, clientLoginRequest, clientLogoutRequest, clientMcpInteraction, clientMcpInteractionDecisionResponse, clientOidcCallbackQuery, clientOidcExchangeRequest, clientOidcStartQuery, clientPasswordResetConfirmRequest, clientPasswordResetRequest, clientProviderListQuery, clientProviderListResponse, clientRefreshRequest, clientRegisterRequest, clientResendVerificationRequest, clientVerifyEmailRequest, mcpConsentGrantListResponse, } from './client-auth.js';
|
|
7
|
+
import { clientRobotListResponse } from './client-robots.js';
|
|
7
8
|
import { appAuthConfig, appInvitation, appInvitationListResponse, appMailTemplate, appMailTemplateListResponse, appOidcProvider, appOidcProviderListResponse, appUser, appUserListResponse, createAppInvitationRequest, createAppOidcProviderRequest, createAppUserRequest, mailOutcome, mailTemplatePreviewRequest, mailTemplatePreviewResponse, patchAppOidcProviderRequest, patchAppUserRequest, putAppAuthConfigRequest, putAppMailTemplateRequest, } from './app-users.js';
|
|
8
9
|
import { acceptTeamInviteRequest, authMeResponse, createTeamInviteRequest, fleetlessUser, fleetlessUserListResponse, passwordChangeRequest, passwordResetConfirm, passwordResetRequest, patchAuthMeRequest, patchFleetlessUserRequest, patchOrgRequest, patchOrgResponse, pendingTeamInviteListResponse, refreshRequest, sessionTokens, signUpRequest, signUpResponse, teamInvite, tierChangeRequest, waitlistRequest, } from './identity.js';
|
|
9
10
|
import { jobRunListResponse, jobRunQuery, jobRunSummary, jobRunSummaryQuery } from './jobs.js';
|
|
10
|
-
import { MCP_APP_PATHS, mcpRolePreviewResponse } from './mcp.js';
|
|
11
|
+
import { MCP_APP_PATHS, mcpRobotDatasheet, mcpRolePreviewResponse } from './mcp.js';
|
|
11
12
|
import { authorizationServerMetadata, dynamicClientRegistrationRequest, dynamicClientRegistrationResponse, oauthAuthorizeQuery, oauthRedirectResponse, oauthTokenRequest, oauthTokenResponse, protectedResourceMetadata, } from './oauth.js';
|
|
12
13
|
import { cameraListResponse, cancelRequest, configDraftResponse, configVersionResponse, configVersionsResponse, createRobotRequest, createRobotResponse, datapointListResponse, datapointValue, exposureListResponse, fetchTypesRequest, fetchTypesResponse, historyQuery, historyResponse, introspectionResponse, invokeOrServiceResponse, invokeRequest, jobResponse, liveSessionResponse, orgHealthQuery, orgLatencyQuery, orgLatencyResponse, orgQuotaUsage, orgUsageQuery, orgUsageResponse, patchRobotRequest, patchRobotResponse, publishConfigResponse, publishRequest, putConfigDraftRequest, putRobotDetailsRequest, putRobotDetailsResponse, releaseLiveQuery, renameSlugRequest, renameSlugResponse, robotDeleteQuery, resourceHealthListResponse, robotDeletionSummary, robotDetailResponse, robotJobsResponse, robotListResponse, slugUsageResponse, snapshotMetaResponse, typesResponse, } from './rest.js';
|
|
13
14
|
export const ROUTE_SECTIONS = [
|
|
@@ -208,6 +209,14 @@ export const ROUTES = [
|
|
|
208
209
|
'and splitting them here would tell a stranger which tokens ever existed. No rate limiter: the GET changes nothing, and the POST it ' +
|
|
209
210
|
'leads to is limited per IP.',
|
|
210
211
|
},
|
|
212
|
+
{
|
|
213
|
+
method: 'GET', path: '/favicon.svg', section: 'client-auth',
|
|
214
|
+
summary: 'Serves the Fleetless icon for the auth portal\'s and the MCP welcome page\'s browser tab.',
|
|
215
|
+
audience: 'internal', auth: 'none', rateLimited: false, ownerTier: false, status: 200,
|
|
216
|
+
params: [], query: null, request: null, response: null, errors: [], transport: 'http',
|
|
217
|
+
notes: 'An SVG, not JSON. Those pages carry a Content-Security-Policy that admits no `data:` image, so the icon is a file on their own ' +
|
|
218
|
+
'origin — the one source `img-src \'self\'` names. Cached for a day: the bytes change when the brand does, not per deploy.',
|
|
219
|
+
},
|
|
211
220
|
{
|
|
212
221
|
method: 'POST', path: '/api/auth/password/reset/confirm', section: 'developer-auth',
|
|
213
222
|
summary: 'Spends a reset token, sets the new password and ends every session of the account.',
|
|
@@ -509,7 +518,7 @@ export const ROUTES = [
|
|
|
509
518
|
params: [
|
|
510
519
|
{ name: 'id', description: 'The app\'s uuid, as returned by `POST /api/apps` or listed by `GET /api/apps`.' },
|
|
511
520
|
{ name: 'userId', description: 'The app user\'s uuid, from `GET /api/apps/:id/users`; a user of another app answers `404`.' },
|
|
512
|
-
{ name: 'clientId', description: 'The MCP client, as `GET /api/apps/:id/users/:userId/mcp-grants` reports its `client_id`. Not a uuid —
|
|
521
|
+
{ name: 'clientId', description: 'The MCP client, as `GET /api/apps/:id/users/:userId/mcp-grants` reports its `client_id`. Not a uuid — the identifier dynamic registration issued.' },
|
|
513
522
|
],
|
|
514
523
|
query: null, request: null, response: null,
|
|
515
524
|
errors: [...DEVELOPER_GUARD, 'invalid_uuid', 'not_found'], transport: 'http',
|
|
@@ -1628,7 +1637,7 @@ export const ROUTES = [
|
|
|
1628
1637
|
method: 'DELETE', path: '/api/client/mcp/grants/:clientId', section: 'client-auth',
|
|
1629
1638
|
summary: 'Withdraws the signed-in app user\'s consent to one MCP client.',
|
|
1630
1639
|
audience: 'client', auth: 'developer_or_client', rateLimited: false, ownerTier: false, status: 204,
|
|
1631
|
-
params: [{ name: 'clientId', description: 'The MCP client, as `GET /api/client/mcp/grants` reports its `client_id`. Not a uuid —
|
|
1640
|
+
params: [{ name: 'clientId', description: 'The MCP client, as `GET /api/client/mcp/grants` reports its `client_id`. Not a uuid — the identifier dynamic registration issued.' }],
|
|
1632
1641
|
query: null, request: null, response: null, errors: [...CLIENT_GUARD], transport: 'http',
|
|
1633
1642
|
notes: 'The person\'s own door, beside the developer\'s `DELETE /api/apps/:id/users/:userId/mcp-grants/:clientId`. It acts on the bearer\'s ' +
|
|
1634
1643
|
'own account and on no other — the path carries a client and never a subject — so there is no user for a caller to name and none to ' +
|
|
@@ -1750,6 +1759,33 @@ export const ROUTES = [
|
|
|
1750
1759
|
'`404 unknown_datapoint` and a configured one with no sample yet is `404 no_data` — three facts a caller who is entitled to them needs ' +
|
|
1751
1760
|
'told apart. The plane built-ins (`bridge_state`, `robot_details`) answer here too, without appearing in any document.',
|
|
1752
1761
|
},
|
|
1762
|
+
/* ------------------------------------------ discovery: the REST twins of the two MCP tools a session starts from */
|
|
1763
|
+
{
|
|
1764
|
+
method: 'GET', path: '/api/client/robots', section: 'robots',
|
|
1765
|
+
summary: 'Lists the robots the caller reaches, with bridge state and the published configuration version.',
|
|
1766
|
+
audience: 'client', auth: 'developer_or_client', rateLimited: false, ownerTier: false, status: 200,
|
|
1767
|
+
params: [], query: null, request: null, response: clientRobotListResponse,
|
|
1768
|
+
errors: [...CLIENT_GUARD], transport: 'http',
|
|
1769
|
+
notes: '**The REST twin of the MCP tool `robots_list`**, and the one robot question no robot-scoped route can answer: which robots may I name ' +
|
|
1770
|
+
'at all. An app user sees the robots their app attaches on which their role grants at least one slug or capability; a server key sees ' +
|
|
1771
|
+
'every robot its app attaches; a developer bearer sees the organisation\'s robots. Name order, id as the tiebreak. A robot on which the ' +
|
|
1772
|
+
'role grants nothing is absent rather than listed empty — the same answer `robots_list` gives, for the same reason: reach is a grant, ' +
|
|
1773
|
+
'not an attachment. Under `/api/client/` because it names no robot; every robot-scoped read stays under `/api/robots/:id/…`.',
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
method: 'GET', path: '/api/robots/:id/datasheet', section: 'robots',
|
|
1777
|
+
summary: 'Describes everything the caller\'s role lets them do on one robot, with parameter schemas.',
|
|
1778
|
+
audience: 'client', auth: 'developer_or_client', rateLimited: false, ownerTier: false, status: 200,
|
|
1779
|
+
params: [{ name: 'id', description: 'The robot\'s uuid, as `GET /api/client/robots` lists it.' }],
|
|
1780
|
+
query: null, request: null, response: mcpRobotDatasheet,
|
|
1781
|
+
errors: [...CLIENT_GUARD, 'invalid_uuid', 'not_found'], transport: 'http',
|
|
1782
|
+
notes: '**The REST twin of the MCP tool `robot_describe`**: one answer per robot — every datapoint, action, service, publisher and camera the ' +
|
|
1783
|
+
'role grants, each with its `input_schema` where it takes parameters, plus the two capabilities that gate whole features, ' +
|
|
1784
|
+
'`action_history` and `assets`. A robot with nothing published answers an empty `exposures` list, never a refusal. A robot the caller ' +
|
|
1785
|
+
'does not reach — not attached to their app, or attached with a role that grants nothing on it — answers `404` exactly as one that ' +
|
|
1786
|
+
'does not exist. The app-user datapoint and camera listings under this prefix stay; this is the one read that also names actions, ' +
|
|
1787
|
+
'services, publishers and capabilities, which is what an app needs before it can draw a screen.',
|
|
1788
|
+
},
|
|
1753
1789
|
/* ------------------------------------------------- config (draft/publish) */
|
|
1754
1790
|
{
|
|
1755
1791
|
method: 'GET', path: '/api/robots/:id/config/draft', section: 'config',
|
|
@@ -1946,7 +1982,7 @@ export const ROUTES = [
|
|
|
1946
1982
|
audience: 'client', auth: 'developer_or_client', rateLimited: false, ownerTier: false, status: 202,
|
|
1947
1983
|
params: [
|
|
1948
1984
|
{ name: 'id', description: 'The robot\'s uuid; an end user reaches it through an app that attaches it.' },
|
|
1949
|
-
{ name: 'slug', description: 'The action or service slug from the published configuration
|
|
1985
|
+
{ name: 'slug', description: 'The action or service slug from the published configuration — the cloud already knows which kind.' },
|
|
1950
1986
|
],
|
|
1951
1987
|
query: null, request: invokeRequest, response: invokeOrServiceResponse,
|
|
1952
1988
|
errors: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetless/contracts",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Fleetless wire contracts: the bridge-cloud protocol, the REST API schemas and the error codes, as zod schemas with generated JSON Schema and OpenAPI artifacts.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dehne Robotik GmbH",
|