@fleetless/contracts 5.1.0-next.2 → 5.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 CHANGED
@@ -9,18 +9,18 @@ version.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [5.1.0] — 2026-09-30
13
+
12
14
  ### Added
13
15
 
14
- - **A cancel can be limited to the bridge's own job.** `cancel`
15
- (`cloudCancel`) gains an optional `own_only: boolean`; absent means
16
- `false`, today's meaning. With `true` the bridge cancels the named job
17
- only if it started it itself: a `job_id` it does not hold — typically an
18
- `unknown` job — cancels nothing, where without the flag it cancels every
19
- external goal on the action. The cloud sets it on the cancels it sends on
20
- its own (a republish's reset and its resend at the next hello), so a
21
- republish never stops a goal Fleetless did not start; a user's cancel
22
- never sets it. `LATEST_BRIDGE_VERSION` is `6.1.0`, the first bridge that
23
- honours it. The protocol stays 5.
16
+ - **`cancelRejectedDetails`** (`CancelRejectedDetails`): the `details` of a
17
+ `cancel_rejected` refusal, `{ goals }` with at least one `{ job_id,
18
+ goal_id, return_code }` — every goal the cancel reached, accepted ones
19
+ included, with its `CancelGoal` return code (`CANCEL_RETURN_CODES`, or
20
+ `null` when that goal's server did not answer). A consumer parses the
21
+ refusal instead of reading its shape from prose. Published as the
22
+ artifact `cancel-rejected-details`. The wire does not change: the cloud
23
+ already sends this shape.
24
24
 
25
25
  ## [5.0.0] — 2026-09-30
26
26
 
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "PROTOCOL_SUNSET_DAYS": 90,
12
- "LATEST_BRIDGE_VERSION": "6.1.0",
12
+ "LATEST_BRIDGE_VERSION": "6.0.0",
13
13
  "CLOSE_ROBOT_DELETED": 4004,
14
14
  "CLOSE_TOKEN_ROTATED": 4005,
15
15
  "JOB_HEARTBEAT_INTERVAL_MS": 1000,
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "goals": {
6
+ "minItems": 1,
7
+ "type": "array",
8
+ "items": {
9
+ "type": "object",
10
+ "properties": {
11
+ "job_id": {
12
+ "type": "string",
13
+ "format": "uuid",
14
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
15
+ },
16
+ "goal_id": {
17
+ "type": "string",
18
+ "minLength": 1
19
+ },
20
+ "return_code": {
21
+ "anyOf": [
22
+ {
23
+ "type": "integer",
24
+ "minimum": 0,
25
+ "maximum": 3
26
+ },
27
+ {
28
+ "type": "null"
29
+ }
30
+ ]
31
+ }
32
+ },
33
+ "required": [
34
+ "job_id",
35
+ "goal_id",
36
+ "return_code"
37
+ ],
38
+ "additionalProperties": false
39
+ }
40
+ }
41
+ },
42
+ "required": [
43
+ "goals"
44
+ ],
45
+ "additionalProperties": false
46
+ }
@@ -28,9 +28,6 @@
28
28
  "type": "null"
29
29
  }
30
30
  ]
31
- },
32
- "own_only": {
33
- "type": "boolean"
34
31
  }
35
32
  },
36
33
  "required": [
package/dist/errors.d.ts CHANGED
@@ -44,6 +44,25 @@ export declare const parameterInvalidDetails: z.ZodObject<{
44
44
  }, z.core.$strip>>;
45
45
  }, z.core.$strip>;
46
46
  export type ParameterInvalidDetails = z.infer<typeof parameterInvalidDetails>;
47
+ /**
48
+ * The `details` of a `cancel_rejected` refusal: every goal the cancel reached,
49
+ * accepted ones included, each with the `CancelGoal` return code its action
50
+ * server answered — compare `return_code` against `CANCEL_RETURN_CODES`
51
+ * (`none`, `rejected`, `unknown_goal_id`, `goal_terminated`); it is `null`
52
+ * when that goal's server did not answer within the bridge's bound. Always at
53
+ * least one goal: the cloud refuses a cancel only because a goal's server
54
+ * answered `ERROR_REJECTED`. Pinned here for the reason
55
+ * `parameterInvalidDetails` is: a caller parses it instead of reading the
56
+ * shape from prose.
57
+ */
58
+ export declare const cancelRejectedDetails: z.ZodObject<{
59
+ goals: z.ZodArray<z.ZodObject<{
60
+ job_id: z.ZodUUID;
61
+ goal_id: z.ZodString;
62
+ return_code: z.ZodNullable<z.ZodNumber>;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>;
65
+ export type CancelRejectedDetails = z.infer<typeof cancelRejectedDetails>;
47
66
  /**
48
67
  * The codes in use today. The wire deliberately allows any string — this
49
68
  * list is the shared vocabulary, not a closed set, so a new refusal never
package/dist/errors.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  import { z } from 'zod';
3
+ import { bridgeCancelResultEntry } from './protocol.js';
3
4
  /**
4
5
  * The one error shape of the REST and realtime APIs: a stable
5
6
  * machine-readable code plus a human message; validation errors name the
@@ -38,6 +39,20 @@ export const parameterViolation = z.object({
38
39
  export const parameterInvalidDetails = z.object({
39
40
  violations: z.array(parameterViolation).min(1),
40
41
  });
42
+ /**
43
+ * The `details` of a `cancel_rejected` refusal: every goal the cancel reached,
44
+ * accepted ones included, each with the `CancelGoal` return code its action
45
+ * server answered — compare `return_code` against `CANCEL_RETURN_CODES`
46
+ * (`none`, `rejected`, `unknown_goal_id`, `goal_terminated`); it is `null`
47
+ * when that goal's server did not answer within the bridge's bound. Always at
48
+ * least one goal: the cloud refuses a cancel only because a goal's server
49
+ * answered `ERROR_REJECTED`. Pinned here for the reason
50
+ * `parameterInvalidDetails` is: a caller parses it instead of reading the
51
+ * shape from prose.
52
+ */
53
+ export const cancelRejectedDetails = z.object({
54
+ goals: z.array(bridgeCancelResultEntry).min(1),
55
+ });
41
56
  /**
42
57
  * The codes in use today. The wire deliberately allows any string — this
43
58
  * list is the shared vocabulary, not a closed set, so a new refusal never
package/dist/index.d.ts CHANGED
@@ -45,8 +45,8 @@ export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMN
45
45
  export type { AuditActor, AuditEvent, AuditQuery, AuditListResponse } from './audit.js';
46
46
  export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
47
47
  export type { AlertRowCondition, AlertSeverity, AlertState, DatapointAlertRow, AlertListResponse, OrgFiringAlertsResponse, OrgAlertsQuery, DatapointDisplay, PutDatapointDisplayRequest, } from './alerts.js';
48
- export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
49
- export type { ApiError, ParameterViolation, ParameterInvalidDetails, ErrorCode } from './errors.js';
48
+ export { apiError, parameterViolation, parameterInvalidDetails, cancelRejectedDetails, ERROR_CODES } from './errors.js';
49
+ export type { ApiError, ParameterViolation, ParameterInvalidDetails, CancelRejectedDetails, ErrorCode } from './errors.js';
50
50
  export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthCodeTokenRequest, oauthRefreshTokenRequest, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
51
51
  export type { OauthErrorCode, OauthError, OauthRedirectResponse, OauthCodeTokenRequest, OauthRefreshTokenRequest, OauthTokenRequest, OauthTokenResponse, RedirectUri, OauthAuthorizeQuery, DynamicClientRegistrationRequest, DynamicClientRegistrationResponse, AuthorizationServerMetadata, ProtectedResourceMetadata, } from './oauth.js';
52
52
  export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';
package/dist/index.js CHANGED
@@ -46,6 +46,6 @@ export { APP_USER_DISPLAY_NAME_MAX, APP_URL_PLACEHOLDERS, MAIL_TEMPLATE_VARIABLE
46
46
  export { assetKind, URDF_ASSET_NAME, asset, urdfCompleteness, assetListResponse, assetsClearResponse, missingAssetQuery, assetSyncRequest, assetSyncResponse, assetSyncState, assetSyncStatus, assetFailure, assetFailureKind, assetStoreRefusedDetails, assetSyncBusyDetails, ROBOT_ASSET_STORE_BYTES, } from './assets.js';
47
47
  export { auditActor, auditEvent, auditQuery, auditListResponse, AUDIT_CSV_COLUMNS, AUDIT_RETENTION_DAYS } from './audit.js';
48
48
  export { alertRowCondition, alertSeverity, alertState, datapointAlertRow, alertListResponse, orgFiringAlertsResponse, orgAlertsQuery, datapointDisplay, putDatapointDisplayRequest, } from './alerts.js';
49
- export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
49
+ export { apiError, parameterViolation, parameterInvalidDetails, cancelRejectedDetails, ERROR_CODES } from './errors.js';
50
50
  export { oauthErrorCode, oauthError, oauthRedirectResponse, oauthCodeTokenRequest, oauthRefreshTokenRequest, oauthTokenRequest, oauthTokenResponse, redirectUri, codeChallengeMethod, oauthAuthorizeQuery, dynamicClientRegistrationRequest, MCP_DCR_MAX_REDIRECT_URIS, dynamicClientRegistrationResponse, authorizationServerMetadata, protectedResourceMetadata, } from './oauth.js';
51
51
  export { ROUTES, ROUTE_SECTIONS, IN_HANDLER_ROUTES } from './routes.js';
@@ -78,7 +78,7 @@ export interface ProtocolVersionEntry {
78
78
  */
79
79
  export declare const PROTOCOL_VERSIONS: readonly ProtocolVersionEntry[];
80
80
  /** The newest bridge package. The cloud mails organisations still below it. */
81
- export declare const LATEST_BRIDGE_VERSION = "6.1.0";
81
+ export declare const LATEST_BRIDGE_VERSION = "6.0.0";
82
82
  export interface ProtocolStatus {
83
83
  status: 'current' | 'deprecated' | 'unsupported';
84
84
  /** ISO date, or null for a current or unknown version. */
@@ -642,24 +642,12 @@ export type CloudInvoke = z.infer<typeof cloudInvoke>;
642
642
  * `request_id` correlates the bridge's `cancel_result`, which carries each
643
643
  * goal's `CancelGoal` return code; the cloud answers its caller only from
644
644
  * that.
645
- *
646
- * `own_only` (fleetless#84) limits a cancel to a job the bridge started
647
- * itself and holds. `true`: the bridge cancels the named job only if it is
648
- * its own; a `job_id` it does not hold, or holds as an external goal,
649
- * cancels **nothing** and is answered `goals: []`. The cloud sets it on the
650
- * cancels it sends on its own — a republish's reset and that reset's resend
651
- * at the next hello — so a republish never stops a goal Fleetless did not
652
- * start. A user's cancel never sets it: only an explicit cancel may reach
653
- * external goals. Absent means `false`, today's meaning. `true` needs a
654
- * `job_id`: the bridge refuses `own_only: true` with `job_id: null` as
655
- * unusable. Bridges before 6.1.0 ignore the key.
656
645
  */
657
646
  export declare const cloudCancel: z.ZodObject<{
658
647
  type: z.ZodLiteral<"cancel">;
659
648
  request_id: z.ZodString;
660
649
  slug: z.ZodString;
661
650
  job_id: z.ZodNullable<z.ZodUUID>;
662
- own_only: z.ZodOptional<z.ZodBoolean>;
663
651
  }, z.core.$strip>;
664
652
  export type CloudCancel = z.infer<typeof cloudCancel>;
665
653
  /**
package/dist/protocol.js CHANGED
@@ -79,7 +79,7 @@ export const PROTOCOL_VERSIONS = [
79
79
  { version: 5, bridge_from: '6.0.0', deprecated_at: null },
80
80
  ];
81
81
  /** The newest bridge package. The cloud mails organisations still below it. */
82
- export const LATEST_BRIDGE_VERSION = '6.1.0';
82
+ export const LATEST_BRIDGE_VERSION = '6.0.0';
83
83
  const DAY_MS = 24 * 60 * 60 * 1000;
84
84
  function isoDate(date) {
85
85
  return date.toISOString().slice(0, 10);
@@ -481,24 +481,12 @@ export const cloudInvoke = z.object({
481
481
  * `request_id` correlates the bridge's `cancel_result`, which carries each
482
482
  * goal's `CancelGoal` return code; the cloud answers its caller only from
483
483
  * that.
484
- *
485
- * `own_only` (fleetless#84) limits a cancel to a job the bridge started
486
- * itself and holds. `true`: the bridge cancels the named job only if it is
487
- * its own; a `job_id` it does not hold, or holds as an external goal,
488
- * cancels **nothing** and is answered `goals: []`. The cloud sets it on the
489
- * cancels it sends on its own — a republish's reset and that reset's resend
490
- * at the next hello — so a republish never stops a goal Fleetless did not
491
- * start. A user's cancel never sets it: only an explicit cancel may reach
492
- * external goals. Absent means `false`, today's meaning. `true` needs a
493
- * `job_id`: the bridge refuses `own_only: true` with `job_id: null` as
494
- * unusable. Bridges before 6.1.0 ignore the key.
495
484
  */
496
485
  export const cloudCancel = z.object({
497
486
  type: z.literal('cancel'),
498
487
  request_id: z.string().min(1).max(64),
499
488
  slug,
500
489
  job_id: z.uuid().nullable(),
501
- own_only: z.boolean().optional(),
502
490
  });
503
491
  /**
504
492
  * The ROS 2 `action_msgs/srv/CancelGoal` return codes: `0` `ERROR_NONE` (the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetless/contracts",
3
- "version": "5.1.0-next.2",
3
+ "version": "5.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",