@fleetless/sdk 3.0.1 → 3.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/dist/index.js CHANGED
@@ -114,7 +114,7 @@ var HttpClient = class {
114
114
  * RequestOptionsFor<P>` would type-check by construction — the cast
115
115
  * bypasses the very check this exists to add, which is the identical
116
116
  * "special case that quietly exempts calls from the general rule" shape
117
- * this file has already been caught by once. Every current call site to a route
117
+ * this file has already made once. Every current call site to a route
118
118
  * with no body already passes `{}` explicitly for exactly this reason.
119
119
  */
120
120
  async request(path, options) {
@@ -304,7 +304,7 @@ function createAssetsApi(http) {
304
304
  finish(
305
305
  null,
306
306
  new Error(
307
- `createMeshLoader and prepareUrdfScene were both installed on the same LoadingManager for robot ${robotId}. Use one or the other on a given manager, not both \u2014 see the README.`
307
+ `createMeshLoader and prepareUrdfScene were both installed on the same LoadingManager for robot ${robotId}. Use one or the other on a given manager, not both \u2014 see the SDK reference.`
308
308
  )
309
309
  );
310
310
  return;
@@ -411,7 +411,7 @@ function createAssetsApi(http) {
411
411
  };
412
412
  }
413
413
 
414
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/common.js
414
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/common.js
415
415
  import { z } from "zod";
416
416
  var SLUG_RULE = "A name is lower-case: it starts with a letter, continues with letters and digits, and joins further words with a single underscore \u2014 `battery_voltage`. Capitals, dashes, dots, spaces, a leading digit and a doubled or trailing underscore are all refused.";
417
417
  var slug = z.string().min(2).max(63).regex(/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/, SLUG_RULE);
@@ -435,7 +435,7 @@ var applyError = z.object({
435
435
  details: z.record(z.string(), z.unknown()).optional()
436
436
  });
437
437
 
438
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/mcp.js
438
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/mcp.js
439
439
  import { z as z2 } from "zod";
440
440
  function mcpAppEndpointPath(appIdentifier2) {
441
441
  return `/mcp/${appIdentifier2}`;
@@ -484,10 +484,10 @@ var mcpRolePreviewResponse = z2.object({
484
484
  });
485
485
  var MCP_ASSET_LINK_TTL_MS = 15 * 60 * 1e3;
486
486
 
487
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/protocol.js
487
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/protocol.js
488
488
  import { z as z8 } from "zod";
489
489
 
490
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/assets.js
490
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/assets.js
491
491
  import { z as z3 } from "zod";
492
492
  var assetKind = z3.enum(["urdf", "mesh", "texture", "other"]);
493
493
  var asset = z3.object({
@@ -745,10 +745,10 @@ var assetSyncBusyDetails = z3.object({
745
745
  started_at_ms: z3.number().int().nonnegative()
746
746
  });
747
747
 
748
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/config.js
748
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/config.js
749
749
  import { z as z5 } from "zod";
750
750
 
751
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/alerts.js
751
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/alerts.js
752
752
  import { z as z4 } from "zod";
753
753
  var alertRowCondition = z4.discriminatedUnion("kind", [
754
754
  z4.strictObject({
@@ -818,7 +818,7 @@ var putDatapointDisplayRequest = z4.object({
818
818
  y_max: z4.number().finite().nullable()
819
819
  }).strict();
820
820
 
821
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/config.js
821
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/config.js
822
822
  var RTSP_URL_RULE = "The URL has to begin with `rtsp://` or `rtsps://` \u2014 `rtsp://cam-1.plant.local/stream1`. No other scheme is accepted: the bridge opens this with a library that would equally honour `file:`.";
823
823
  var MJPEG_URL_RULE = "The URL has to begin with `http://` or `https://` \u2014 `http://cam-1.plant.local/video.mjpg`. No other scheme is accepted: the bridge opens this with a library that would equally serve `file:`.";
824
824
  var DEVICE_PATH_RULE = "A capture device is a path under `/dev/`, and the character straight after it is a letter or a digit \u2014 `/dev/video0`, or a stable `/dev/v4l/by-id/...` symlink. Nothing outside `/dev/` is accepted: the string reaches OpenCV, which would as happily open an ordinary file.";
@@ -1865,7 +1865,7 @@ var configState = z5.object({
1865
1865
  applied_errors: z5.array(applyError).nullable()
1866
1866
  });
1867
1867
 
1868
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/introspection.js
1868
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/introspection.js
1869
1869
  import { z as z6 } from "zod";
1870
1870
  var rosGraphEntry = z6.object({
1871
1871
  name: rosName,
@@ -1904,7 +1904,7 @@ var typeDefinition = z6.discriminatedUnion("kind", [
1904
1904
  })
1905
1905
  ]);
1906
1906
 
1907
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/jobs.js
1907
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/jobs.js
1908
1908
  import { z as z7 } from "zod";
1909
1909
  var jobState = z7.enum(["running", "succeeded", "failed", "cancelled", "lost"]);
1910
1910
  var job = z7.object({
@@ -2122,7 +2122,7 @@ var jobRunSummary = z7.object({
2122
2122
  since_ms: z7.number().int().nonnegative()
2123
2123
  });
2124
2124
 
2125
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/protocol.js
2125
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/protocol.js
2126
2126
  var MAX_PATIENCE_MS = 12e4;
2127
2127
  var MIN_PATIENCE_MS = 1e3;
2128
2128
  var activeJob = z8.object({
@@ -2521,11 +2521,11 @@ var bridgeCameraState = z8.object({
2521
2521
  request_id: z8.string().min(1).max(64).nullable()
2522
2522
  });
2523
2523
 
2524
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/config-issues.js
2524
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/config-issues.js
2525
2525
  var EXPOSURE_SECTIONS = ["datapoints", "actions", "services", "publishers", "cameras"];
2526
2526
  var EXPOSURE_SECTION_NAMES = new Set(EXPOSURE_SECTIONS);
2527
2527
 
2528
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/rest.js
2528
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/rest.js
2529
2529
  import { z as z9 } from "zod";
2530
2530
  var robot = z9.object({
2531
2531
  id: z9.uuid().meta({
@@ -3285,13 +3285,13 @@ var slugUsageResponse = z9.object({
3285
3285
  alert_count: z9.number().int().nonnegative()
3286
3286
  });
3287
3287
 
3288
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/realtime.js
3288
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/realtime.js
3289
3289
  import { z as z14 } from "zod";
3290
3290
 
3291
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/client-auth.js
3291
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/client-auth.js
3292
3292
  import { z as z13 } from "zod";
3293
3293
 
3294
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/apps.js
3294
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/apps.js
3295
3295
  import { z as z10 } from "zod";
3296
3296
  var appIdentifier = slug;
3297
3297
  var app = z10.object({
@@ -3473,10 +3473,10 @@ var rolePermissions = z10.object({
3473
3473
  })
3474
3474
  });
3475
3475
 
3476
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/app-users.js
3476
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/app-users.js
3477
3477
  import { z as z12 } from "zod";
3478
3478
 
3479
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/identity.js
3479
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/identity.js
3480
3480
  import { z as z11 } from "zod";
3481
3481
  var password = z11.string().min(12).max(256);
3482
3482
  var USER_DISPLAY_NAME_MAX = 120;
@@ -3638,7 +3638,7 @@ var authMeResponse = z11.object({ org, user: fleetlessUser });
3638
3638
  var patchOrgRequest = z11.object({ name: z11.string().min(1).max(120) }).strict();
3639
3639
  var patchAuthMeRequest = z11.object({ display_name: z11.string().min(1).max(USER_DISPLAY_NAME_MAX).nullable() }).strict();
3640
3640
 
3641
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/app-users.js
3641
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/app-users.js
3642
3642
  var APP_USER_DISPLAY_NAME_MAX = 120;
3643
3643
  var providerSlug = z12.string().max(40).regex(/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/, "a provider slug is lowercase and hyphen-separated, starting with a letter");
3644
3644
  var appUserStatus = z12.enum(["pending_verification", "active", "blocked"]);
@@ -3889,7 +3889,7 @@ var mailOutcome = z12.object({
3889
3889
  })
3890
3890
  });
3891
3891
 
3892
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/client-auth.js
3892
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/client-auth.js
3893
3893
  var clientLoginRequest = z13.object({
3894
3894
  app_identifier: appIdentifier.meta({
3895
3895
  description: "The app being logged in to, as its globally unique identifier \u2014 the lowercase, underscore-separated string the developer chose when the app was created. There is no organisation context at login, so this is what decides which app the credentials are checked for."
@@ -4078,7 +4078,7 @@ var clientIdentity = z13.object({
4078
4078
  })
4079
4079
  });
4080
4080
 
4081
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/realtime.js
4081
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/realtime.js
4082
4082
  var clientAuth = z14.object({
4083
4083
  type: z14.literal("auth"),
4084
4084
  token: z14.string().min(1)
@@ -4356,7 +4356,7 @@ var orgEventDropped = z14.object({
4356
4356
  dropped: z14.number().int().positive()
4357
4357
  }).strict();
4358
4358
 
4359
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/audit.js
4359
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/audit.js
4360
4360
  import { z as z15 } from "zod";
4361
4361
  var auditActor = z15.object({
4362
4362
  kind: z15.enum(["developer", "end_user", "app_user", "server_key", "bridge"]),
@@ -4487,7 +4487,7 @@ var auditListResponse = z15.object({
4487
4487
  next_cursor: z15.number().int().positive().nullable()
4488
4488
  });
4489
4489
 
4490
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/errors.js
4490
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/errors.js
4491
4491
  import { z as z16 } from "zod";
4492
4492
  var apiError = z16.object({
4493
4493
  code: z16.string().min(1),
@@ -4504,7 +4504,7 @@ var parameterInvalidDetails = z16.object({
4504
4504
  violations: z16.array(parameterViolation).min(1)
4505
4505
  });
4506
4506
 
4507
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/oauth.js
4507
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/oauth.js
4508
4508
  import { z as z17 } from "zod";
4509
4509
  var oauthErrorCode = z17.enum([
4510
4510
  "invalid_request",
@@ -4725,7 +4725,7 @@ var oauthAuthorizeQuery = z17.object({
4725
4725
  description: "The authorization request an MCP client sends, per RFC 6749 \xA74.1.1 with mandatory PKCE. The handler reads it parameter by parameter rather than through one parse, because the answers differ: `client_id` and `redirect_uri` are refused flat, with no redirect, since until both are confirmed there is no trusted target to bounce a browser to, and everything after them is reported to the client's own callback as query parameters."
4726
4726
  });
4727
4727
 
4728
- // node_modules/.pnpm/@fleetless+contracts@1.0.4/node_modules/@fleetless/contracts/dist/routes.js
4728
+ // node_modules/.pnpm/@fleetless+contracts@1.0.5/node_modules/@fleetless/contracts/dist/routes.js
4729
4729
  var MCP_APP = MCP_APP_PATHS(":appIdentifier");
4730
4730
  var APP_IDENTIFIER = {
4731
4731
  name: "appIdentifier",
@@ -6325,7 +6325,7 @@ var ROUTES = [
6325
6325
  response: null,
6326
6326
  errors: ["not_found", "unauthorized", "forbidden"],
6327
6327
  transport: "http",
6328
- notes: "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions \u2014 the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance \u2014 so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* \u2014 one answer for two states, which is one answer for two states. Registering the verb lets the endpoint say \"this app's server is here; this verb is not part of it\". The central `/mcp` registers neither verb and does not need to: its path takes no parameter, so nothing can misread its `404`. \n\n**The `405` body is the transport's JSON-RPC error object, not the `apiError` envelope.** The three codes above are the refusals that come *first* \u2014 the app, its switch, then the bearer, in the order `POST` describes \u2014 and they are `apiError` because they are answered before the transport is reached at all. If this server ever becomes stateful, this row and the `DELETE` beside it are where that lands, and the cloud's route-manifest test is what would make both repositories notice."
6328
+ notes: "MCP's Streamable HTTP gives this path three verbs: `POST` carries JSON-RPC, `GET` opens the server-initiated SSE stream, and `DELETE` ends a session. This server has no sessions \u2014 the argument is in `MCP_PROTOCOL_VERSION`'s own note, and a per-process session map is what breaks at the second cloud instance \u2014 so `GET` and `DELETE` answer `405`, which is what a client is built to fall back from. \n\n**The `405` is this cloud's own answer, not the SDK's**, and the two differ: MCP SDK 1.30.0 opens an SSE stream on `GET` (`handleGetRequest`) and answers `200` on `DELETE` (`handleDeleteRequest`), neither of which a stateless server has any business doing, so the cloud writes the `405` itself in the transport's own JSON-RPC error shape with `Allow: POST`. \n\n**The row exists so that the `405` is not a `404`.** An unregistered verb answers `404`, and at a path whose last segment is an app identifier a `404` already means *no such app* \u2014 so an unregistered verb and an unknown app would answer identically. Registering the verb lets the endpoint say \"this app's server is here; this verb is not part of it\". The central `/mcp` registers neither verb and does not need to: its path takes no parameter, so nothing can misread its `404`. \n\n**The `405` body is the transport's JSON-RPC error object, not the `apiError` envelope.** The three codes above are the refusals that come *first* \u2014 the app, its switch, then the bearer, in the order `POST` describes \u2014 and they are `apiError` because they are answered before the transport is reached at all. If this server ever becomes stateful, this row and the `DELETE` beside it are where that lands, and the cloud's route-manifest test is what would make both repositories notice."
6329
6329
  },
6330
6330
  {
6331
6331
  method: "DELETE",
@@ -7290,7 +7290,7 @@ var ROUTES = [
7290
7290
  response: jobRunListResponse,
7291
7291
  errors: [...CLIENT_GUARD, "invalid_uuid", "not_found", "capability_required", "validation_error"],
7292
7292
  transport: "http",
7293
- notes: "Needs the `action_history` capability, and **this route is what makes that switch mean something** \u2014 it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug and The router matches a static segment first, so a robot with a service literally slugged `history` can no longer be **read** through `GET /api/robots/:id/jobs/:slug`; invoking, cancelling and the listing are unaffected. And a run row names its actor by email address, so an end user holding this capability learns which other people have been driving the machine. `robot_id` in the query is shared with the org-wide read; a *different* one here is refused rather than quietly answered about the robot in the path."
7293
+ notes: "Needs the `action_history` capability, and **this route is what makes that switch mean something** \u2014 it was unkeepable while nothing durable recorded what had run. Two residuals worth stating rather than implying away. `history` is a syntactically valid slug, and a static segment matches before a parameter, so a robot with a service literally slugged `history` can no longer be **read** through `GET /api/robots/:id/jobs/:slug`; invoking, cancelling and the listing are unaffected. And a run row names its actor by email address, so an end user holding this capability learns which other people have been driving the machine. `robot_id` in the query is shared with the org-wide read; a *different* one here is refused rather than quietly answered about the robot in the path."
7294
7294
  },
7295
7295
  {
7296
7296
  method: "POST",
@@ -8302,21 +8302,21 @@ function assertValidJobId(jobId) {
8302
8302
  if (jobId === void 0 || jobId === null || typeof jobId === "string") return;
8303
8303
  throw new FleetlessError(
8304
8304
  "invalid_option",
8305
- `cancel()'s third argument must be a job id (string), null, or omitted \u2014 got ${typeof jobId === "object" ? "an object" : typeof jobId}. If you are passing an options object (e.g. {timeoutMs}) as the third argument, note the signature changed in this release: cancel(robotId, slug) is unchanged, but a third positional argument is now the job id to cancel and options moved to a fourth argument \u2014 cancel(robotId, slug, jobId, options). See the README's Actions section.`
8305
+ `cancel()'s third argument must be a job id (string), null, or omitted \u2014 got ${typeof jobId === "object" ? "an object" : typeof jobId}. If you are passing an options object (e.g. {timeoutMs}) as the third argument, note the signature changed in this release: cancel(robotId, slug) is unchanged, but a third positional argument is now the job id to cancel and options moved to a fourth argument \u2014 cancel(robotId, slug, jobId, options). See the Actions section of the SDK reference at https://docs.fleetless.dev/reference/sdk/`
8306
8306
  );
8307
8307
  }
8308
8308
  function createRealtimeCommandTransport(channel) {
8309
8309
  return {
8310
- // Declared `async` deliberately, unlike `cancel`/`publish` below: it is
8310
+ // Declared `async` deliberately, unlike `cancel`/`publish` below: it's
8311
8311
  // the only one of the three that can refuse *before* sending anything
8312
- // (resolveLocalWaitMs's `invalid_option`, D3a), and every caller of
8313
- // this interface — starting with this file's own `sendCommand` callers
8314
- // — is entitled to assume `CommandTransport.invoke` always returns a
8315
- // promise rather than throwing synchronously. Without `async` here, a
8316
- // synchronous throw from `resolveLocalWaitMs` would escape as a thrown
8317
- // exception instead of a rejection, breaking that assumption for any
8318
- // caller that isn't itself inside an `async` function (e.g. a test
8319
- // calling this transport directly).
8312
+ // (`resolveLocalWaitMs`'s `invalid_option`), and every caller of this
8313
+ // interface — starting with this file's own `sendCommand` callers —
8314
+ // assumes `CommandTransport.invoke` always returns a promise, never
8315
+ // throws synchronously. Without `async` here, a synchronous throw from
8316
+ // `resolveLocalWaitMs` would escape as a thrown exception instead of a
8317
+ // rejection, breaking that assumption for a caller that isn't itself
8318
+ // inside an `async` function (e.g. a test calling this transport
8319
+ // directly).
8320
8320
  async invoke(robotId, slug2, params, options) {
8321
8321
  const timeoutMs = resolveLocalWaitMs(options ?? {}, DEFAULT_COMMAND_TIMEOUT_MS);
8322
8322
  const frame = {
@@ -8516,12 +8516,11 @@ var RealtimeChannel = class {
8516
8516
  }
8517
8517
  /**
8518
8518
  * Increments on every successful authentication (first connect and every
8519
- * reconnect). A command sent on one physical socket can only ever be
8520
- * answered on that socket — comparing the epoch captured at send time
8521
- * against the current one is how a caller (see `commands.ts`) tells "still
8522
- * waiting on the connection it was sent over" from "that connection is
8523
- * gone and a new one has taken its place", the moment it happens rather
8524
- * than after a timeout elapses.
8519
+ * reconnect). A command sent on one socket can only be answered on that
8520
+ * socket — comparing the epoch at send time against the current one is
8521
+ * how a caller (see `commands.ts`) tells "still waiting on the connection
8522
+ * it was sent over" from "that connection is gone and a new one has taken
8523
+ * its place", the moment it happens rather than after a timeout elapses.
8525
8524
  */
8526
8525
  get connectionEpoch() {
8527
8526
  return this.#connectionEpoch;
@@ -8822,7 +8821,7 @@ function createSlugSubscriptions(channel) {
8822
8821
  // src/token-store.ts
8823
8822
  var InMemoryTokenStore = class {
8824
8823
  #session = null;
8825
- /** Creates an empty store. Nothing is loaded from anywhere — a client built with it starts logged out. */
8824
+ /** Nothing is loaded from anywhere — a client built with it starts logged out. */
8826
8825
  constructor() {
8827
8826
  }
8828
8827
  /** Returns the session held in memory, or `null` if there is none. */
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "@fleetless/sdk",
3
- "version": "3.0.1",
4
- "description": "The official TypeScript SDK for Fleetless client apps \u2014 a ROS 2 robot as a REST and realtime API, cameras, jobs, and the app's own user accounts, federated sign-in and MCP consent.",
3
+ "version": "3.0.3",
4
+ "description": "The official TypeScript SDK for Fleetless client apps — a ROS 2 robot as a REST and realtime API, cameras, jobs, and the app's own user accounts, federated sign-in and MCP consent.",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "Dehne Robotik GmbH",
8
8
  "email": "hello@fleetless.dev",
9
9
  "url": "https://dehne-robotik.de"
10
10
  },
11
+ "homepage": "https://docs.fleetless.dev/reference/sdk/",
11
12
  "repository": {
12
13
  "type": "git",
13
14
  "url": "https://github.com/fleetless/sdk"
14
15
  },
15
- "homepage": "https://docs.fleetless.dev/reference/sdk/",
16
16
  "bugs": {
17
- "url": "https://github.com/fleetless/sdk/issues",
18
17
  "email": "hello@fleetless.dev"
19
18
  },
20
19
  "keywords": [
@@ -65,17 +64,19 @@
65
64
  "scripts": {
66
65
  "build": "tsup && node scripts/stamp-dist.mjs",
67
66
  "prepare": "tsup && node scripts/stamp-dist.mjs",
67
+ "prepublishOnly": "node scripts/refuse-manual-publish.mjs",
68
68
  "typecheck": "tsc --noEmit",
69
69
  "test": "vitest run",
70
70
  "test:pack": "node scripts/verify-published-types.mjs",
71
71
  "verify:live": "node scripts/verify-live.mjs",
72
- "verify:history": "node scripts/verify-history.mjs"
72
+ "verify:history": "node scripts/verify-history.mjs",
73
+ "verify:commits": "node scripts/verify-commit-messages.mjs"
73
74
  },
74
75
  "dependencies": {
75
76
  "zod": "^4.0.0"
76
77
  },
77
78
  "devDependencies": {
78
- "@fleetless/contracts": "1.0.4",
79
+ "@fleetless/contracts": "1.0.5",
79
80
  "@types/node": "^22.20.1",
80
81
  "tsup": "^8.3.0",
81
82
  "typedoc": "0.28.20",