@fleetless/contracts 5.1.0-next.1 → 5.1.0-next.2

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
@@ -11,14 +11,16 @@ version.
11
11
 
12
12
  ### Added
13
13
 
14
- - **`cancelRejectedDetails`** (`CancelRejectedDetails`): the `details` of a
15
- `cancel_rejected` refusal, `{ goals }` with at least one `{ job_id,
16
- goal_id, return_code }` — every goal the cancel reached, accepted ones
17
- included, with its `CancelGoal` return code (`CANCEL_RETURN_CODES`, or
18
- `null` when that goal's server did not answer). A consumer parses the
19
- refusal instead of reading its shape from prose. Published as the
20
- artifact `cancel-rejected-details`. The wire does not change: the cloud
21
- already sends this shape.
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.
22
24
 
23
25
  ## [5.0.0] — 2026-09-30
24
26
 
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "PROTOCOL_SUNSET_DAYS": 90,
12
- "LATEST_BRIDGE_VERSION": "6.0.0",
12
+ "LATEST_BRIDGE_VERSION": "6.1.0",
13
13
  "CLOSE_ROBOT_DELETED": 4004,
14
14
  "CLOSE_TOKEN_ROTATED": 4005,
15
15
  "JOB_HEARTBEAT_INTERVAL_MS": 1000,
@@ -28,6 +28,9 @@
28
28
  "type": "null"
29
29
  }
30
30
  ]
31
+ },
32
+ "own_only": {
33
+ "type": "boolean"
31
34
  }
32
35
  },
33
36
  "required": [
package/dist/errors.d.ts CHANGED
@@ -44,25 +44,6 @@ 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>;
66
47
  /**
67
48
  * The codes in use today. The wire deliberately allows any string — this
68
49
  * list is the shared vocabulary, not a closed set, so a new refusal never
package/dist/errors.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  import { z } from 'zod';
3
- import { bridgeCancelResultEntry } from './protocol.js';
4
3
  /**
5
4
  * The one error shape of the REST and realtime APIs: a stable
6
5
  * machine-readable code plus a human message; validation errors name the
@@ -39,20 +38,6 @@ export const parameterViolation = z.object({
39
38
  export const parameterInvalidDetails = z.object({
40
39
  violations: z.array(parameterViolation).min(1),
41
40
  });
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
- });
56
41
  /**
57
42
  * The codes in use today. The wire deliberately allows any string — this
58
43
  * 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, cancelRejectedDetails, ERROR_CODES } from './errors.js';
49
- export type { ApiError, ParameterViolation, ParameterInvalidDetails, CancelRejectedDetails, ErrorCode } from './errors.js';
48
+ export { apiError, parameterViolation, parameterInvalidDetails, ERROR_CODES } from './errors.js';
49
+ export type { ApiError, ParameterViolation, ParameterInvalidDetails, 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, cancelRejectedDetails, ERROR_CODES } from './errors.js';
49
+ export { apiError, parameterViolation, parameterInvalidDetails, 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.0.0";
81
+ export declare const LATEST_BRIDGE_VERSION = "6.1.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,12 +642,24 @@ 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.
645
656
  */
646
657
  export declare const cloudCancel: z.ZodObject<{
647
658
  type: z.ZodLiteral<"cancel">;
648
659
  request_id: z.ZodString;
649
660
  slug: z.ZodString;
650
661
  job_id: z.ZodNullable<z.ZodUUID>;
662
+ own_only: z.ZodOptional<z.ZodBoolean>;
651
663
  }, z.core.$strip>;
652
664
  export type CloudCancel = z.infer<typeof cloudCancel>;
653
665
  /**
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.0.0';
82
+ export const LATEST_BRIDGE_VERSION = '6.1.0';
83
83
  const DAY_MS = 24 * 60 * 60 * 1000;
84
84
  function isoDate(date) {
85
85
  return date.toISOString().slice(0, 10);
@@ -481,12 +481,24 @@ 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.
484
495
  */
485
496
  export const cloudCancel = z.object({
486
497
  type: z.literal('cancel'),
487
498
  request_id: z.string().min(1).max(64),
488
499
  slug,
489
500
  job_id: z.uuid().nullable(),
501
+ own_only: z.boolean().optional(),
490
502
  });
491
503
  /**
492
504
  * 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.1",
3
+ "version": "5.1.0-next.2",
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",
@@ -1,46 +0,0 @@
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
- }