@camstack/addon-mqtt-broker 1.1.18 → 1.1.20

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.
@@ -4673,7 +4673,7 @@ function _instanceof(cls, params = {}) {
4673
4673
  return inst;
4674
4674
  }
4675
4675
  //#endregion
4676
- //#region ../types/dist/sleep-CZDdRBua.mjs
4676
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4677
4677
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4678
4678
  EventCategory["SystemBoot"] = "system.boot";
4679
4679
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -4859,6 +4859,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4859
4859
  */
4860
4860
  EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
4861
4861
  /**
4862
+ * The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
4863
+ * Emitted by addon-pipeline-orchestrator whenever it (re)derives node
4864
+ * capabilities — at boot, on agent online/offline, and on an ingest-node
4865
+ * flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
4866
+ * keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
4867
+ * cross-process `getIngestOwner` query (push the authority's decision instead
4868
+ * of polling it on the hot path). Idempotent state — re-emitted on every
4869
+ * topology change, so a dropped event self-heals on the next one (plus the
4870
+ * broker's long backstop reconcile query).
4871
+ */
4872
+ EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
4873
+ /**
4862
4874
  * Periodic snapshot of per-node pipeline-runner load
4863
4875
  * (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
4864
4876
  * subscribe instead of polling `pipelineRunner.getLocalLoad`.
@@ -5382,10 +5394,6 @@ function hydrateField(field, values) {
5382
5394
  };
5383
5395
  }
5384
5396
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5385
- if (field.type === "password") return {
5386
- ...field,
5387
- value: ""
5388
- };
5389
5397
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5390
5398
  return {
5391
5399
  ...field,
@@ -6769,6 +6777,9 @@ function method(input, output, options) {
6769
6777
  timeoutMs: options?.timeoutMs
6770
6778
  };
6771
6779
  }
6780
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6781
+ var VersionOutputSchema$1 = object({ version: string() });
6782
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6772
6783
  var StaticDirOutputSchema = object({ staticDir: string() });
6773
6784
  var VersionOutputSchema = object({ version: string() });
6774
6785
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -6938,6 +6949,36 @@ var ModelFormatsSchema = object({
6938
6949
  tflite: ModelFormatEntrySchema.optional(),
6939
6950
  pt: ModelFormatEntrySchema.optional()
6940
6951
  });
6952
+ /**
6953
+ * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
6954
+ * the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
6955
+ * grouped Family→Tier→Variant picker renders identically in the config UI and
6956
+ * in the pipeline/device steppers. The flat `id` stays the source of truth for
6957
+ * resolution/download/persistence; this is a presentation overlay resolved back
6958
+ * to an `id`.
6959
+ */
6960
+ var ModelVariantGroupSchema = object({
6961
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
6962
+ family: string(),
6963
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
6964
+ tier: string(),
6965
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
6966
+ precision: _enum(["fp32", "int8"]).optional(),
6967
+ /**
6968
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
6969
+ * latency-optimized export (e.g. ReLU-activation variant) — the slot the
6970
+ * future performance variants plug into.
6971
+ */
6972
+ optimization: _enum(["standard", "fast"]).optional(),
6973
+ /**
6974
+ * Input-resolution axis (square input side, px). Omit ⇒ the family's native
6975
+ * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
6976
+ * cheap latency lever — especially on Apple ANE and the Intel N100 — at a
6977
+ * small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
6978
+ * the group so the selector can offer it as a variant axis.
6979
+ */
6980
+ resolution: number().int().positive().optional()
6981
+ });
6941
6982
  var ModelCatalogEntrySchema = object({
6942
6983
  id: string(),
6943
6984
  name: string(),
@@ -6967,7 +7008,43 @@ var ModelCatalogEntrySchema = object({
6967
7008
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6968
7009
  * Downloaded into the same modelsDir alongside the model file.
6969
7010
  */
6970
- extraFiles: array(ModelExtraFileSchema).readonly().optional()
7011
+ extraFiles: array(ModelExtraFileSchema).readonly().optional(),
7012
+ /**
7013
+ * LEGACY entry — retained in the catalog so a persisted operator selection
7014
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
7015
+ * model list and excluded from the auto format-default pick. Set on the
7016
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
7017
+ * the active lineup stays the coherent curated ladder without deleting a
7018
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
7019
+ * an explicit legacy id that has a build for the node's format.
7020
+ */
7021
+ legacy: boolean().optional(),
7022
+ /**
7023
+ * Measured quality/latency metadata — populated from the benchmark addon on
7024
+ * the real node classes. Absent = not yet measured (most entries today; the
7025
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
7026
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
7027
+ */
7028
+ metrics: object({
7029
+ map50: number().optional(),
7030
+ p95LatencyMs: record(string(), number()).optional()
7031
+ }).optional(),
7032
+ /**
7033
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
7034
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
7035
+ * the retraining addon and any future commercial distribution.
7036
+ */
7037
+ license: string().optional(),
7038
+ /**
7039
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
7040
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
7041
+ * of a family's sizes and quantizations collapse into one grouped picker
7042
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
7043
+ * (legacy / custom models) — never shown in the grouped selector. The flat
7044
+ * `id` stays the source of truth for resolution/download/persistence; grouping
7045
+ * is a presentation overlay resolved back to an `id`.
7046
+ */
7047
+ group: ModelVariantGroupSchema.optional()
6971
7048
  });
6972
7049
  var ConvertTargetSchema = discriminatedUnion("format", [object({
6973
7050
  format: literal("openvino"),
@@ -7028,8 +7105,8 @@ var RecordingModeSchema = _enum([
7028
7105
  "onAudioThreshold"
7029
7106
  ]);
7030
7107
  /**
7031
- * First-class, authoritative per-camera storage mode — the netta choice the UI
7032
- * reads directly (never inferred from `rules`):
7108
+ * First-class, authoritative per-camera storage mode — the explicit choice the
7109
+ * UI reads directly (never inferred from `rules`):
7033
7110
  * - `off` — not recording.
7034
7111
  * - `events` — record only around triggers (motion / audio threshold),
7035
7112
  * with pre/post-buffer.
@@ -8677,26 +8754,13 @@ DeviceType.Light, method(object({
8677
8754
  percentage: number().min(0).max(100),
8678
8755
  lastChangedAt: number()
8679
8756
  });
8757
+ /** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
8680
8758
  var StreamFormatSchema = _enum([
8681
8759
  "webrtc",
8682
8760
  "hls",
8683
8761
  "mjpeg",
8684
8762
  "rtsp"
8685
8763
  ]);
8686
- var StreamInfoSchema = object({
8687
- streamId: string(),
8688
- format: StreamFormatSchema,
8689
- url: string().nullable(),
8690
- active: boolean()
8691
- });
8692
- method(object({
8693
- streamId: string(),
8694
- sourceUrl: string(),
8695
- codec: string().optional()
8696
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
8697
- streamId: string(),
8698
- format: StreamFormatSchema
8699
- }), string().nullable()), method(_void(), array(StreamInfoSchema));
8700
8764
  var RtspRestreamEntrySchema = object({
8701
8765
  brokerId: string(),
8702
8766
  url: string(),
@@ -9361,7 +9425,7 @@ var ConsumablesStatusSchema = object({
9361
9425
  })),
9362
9426
  lastChangedAt: number()
9363
9427
  });
9364
- DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, method(object({
9428
+ Object.values(DeviceType), method(object({
9365
9429
  deviceId: number().int().nonnegative(),
9366
9430
  key: string().min(1)
9367
9431
  }), _void(), {
@@ -10276,7 +10340,7 @@ var BoundingBoxSchema = object({
10276
10340
  w: number(),
10277
10341
  h: number()
10278
10342
  });
10279
- var SpatialDetectionSchema = object({
10343
+ object({
10280
10344
  class: string(),
10281
10345
  originalClass: string(),
10282
10346
  score: number(),
@@ -10411,7 +10475,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
10411
10475
  enabled: boolean(),
10412
10476
  modelId: string(),
10413
10477
  children: array(PipelineDefaultStepSchema).readonly(),
10414
- engine: PipelineEngineChoiceSchema.optional(),
10415
10478
  group: string().optional(),
10416
10479
  settings: record(string(), unknown()).optional()
10417
10480
  }));
@@ -10436,7 +10499,9 @@ var PipelineModelOptionSchema = object({
10436
10499
  formats: record(string(), object({
10437
10500
  downloaded: boolean(),
10438
10501
  sizeMB: number()
10439
- }))
10502
+ })),
10503
+ group: ModelVariantGroupSchema.optional(),
10504
+ legacy: boolean().optional()
10440
10505
  });
10441
10506
  var ConfigFieldBridge = custom();
10442
10507
  var PipelineAddonSchemaSchema = object({
@@ -10466,11 +10531,6 @@ var PipelineSchemaSchema = object({
10466
10531
  selectedEngine: PipelineEngineChoiceSchema,
10467
10532
  slots: array(PipelineSlotSchemaSchema).readonly()
10468
10533
  });
10469
- var DetectorOutputSchema = object({
10470
- detections: array(SpatialDetectionSchema).readonly(),
10471
- inferenceMs: number(),
10472
- modelId: string()
10473
- });
10474
10534
  var EngineProvisioningSchema = object({
10475
10535
  runtimeId: _enum([
10476
10536
  "onnx",
@@ -10487,15 +10547,42 @@ var EngineProvisioningSchema = object({
10487
10547
  ]),
10488
10548
  progress: number().optional(),
10489
10549
  error: string().optional(),
10490
- nextRetryAt: number().optional()
10550
+ nextRetryAt: number().optional(),
10551
+ /**
10552
+ * Gate A (config-correctness gate at engine change): human-readable
10553
+ * config issues surfaced EAGERLY when the node's engine changes — model
10554
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
10555
+ * has a <format> build"). Additive/optional: informational only, never
10556
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
10557
+ * Absent/empty when the node-default tree resolves cleanly.
10558
+ */
10559
+ configIssues: array(string()).optional()
10491
10560
  });
10492
10561
  var PipelineStepInputSchema = lazy(() => object({
10493
10562
  addonId: string(),
10494
- modelId: string(),
10563
+ modelId: string().optional(),
10495
10564
  enabled: boolean().default(true),
10496
10565
  children: array(PipelineStepInputSchema).optional(),
10497
10566
  settings: record(string(), unknown()).optional()
10498
10567
  }));
10568
+ var ModelSubstitutionSchema = object({
10569
+ addonId: string(),
10570
+ chosen: string(),
10571
+ running: string(),
10572
+ format: string()
10573
+ });
10574
+ var PipelineValidationIssueSchema = object({
10575
+ addonId: string(),
10576
+ kind: _enum(["unknown-addon", "no-format-build"]),
10577
+ detail: string()
10578
+ });
10579
+ var PipelineValidationResultSchema = object({
10580
+ ok: boolean(),
10581
+ issues: array(PipelineValidationIssueSchema).readonly(),
10582
+ substitutions: array(ModelSubstitutionSchema).readonly(),
10583
+ /** The node's `currentEngine.format` this validation ran against. */
10584
+ format: string()
10585
+ });
10499
10586
  var ReferenceImageEntrySchema = object({
10500
10587
  filename: string(),
10501
10588
  stepIds: array(string()).readonly().optional()
@@ -10566,7 +10653,13 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10566
10653
  })) }), object({ success: literal(true) }), {
10567
10654
  kind: "mutation",
10568
10655
  auth: "admin"
10569
- }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10656
+ }), method(object({ nodeId: string() }), object({
10657
+ success: literal(true),
10658
+ clearedDevices: number()
10659
+ }), {
10660
+ kind: "mutation",
10661
+ auth: "admin"
10662
+ }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10570
10663
  name: string(),
10571
10664
  steps: array(PipelineTemplateStepSchema).readonly(),
10572
10665
  engine: PipelineEngineChoiceSchema
@@ -10583,10 +10676,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10583
10676
  modelId: string(),
10584
10677
  format: ModelFormatSchema$1
10585
10678
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10586
- addonId: string(),
10587
- frame: FrameInputSchema,
10588
- config: record(string(), unknown()).optional()
10589
- }), DetectorOutputSchema), method(object({
10590
10679
  engine: PipelineEngineChoiceSchema.optional(),
10591
10680
  steps: array(PipelineStepInputSchema).min(1),
10592
10681
  frame: FrameInputSchema.optional(),
@@ -10826,6 +10915,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10826
10915
  kind: literal("remote-restream"),
10827
10916
  /** The camera's source-owner node (slice 1: always the hub). */
10828
10917
  ownerNodeId: string(),
10918
+ /**
10919
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
10920
+ * per-node `reachableHost` override (Cluster UI). When present the runner
10921
+ * dials THIS host for the owner's restream, in preference to the
10922
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
10923
+ */
10924
+ ownerReachableHost: string().optional(),
10829
10925
  /** Operator override for the owner host the runner dials. */
10830
10926
  hubHostnameOverride: string().optional()
10831
10927
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -10834,13 +10930,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10834
10930
  * specific runner instance via `attachCamera`. Carries everything the
10835
10931
  * runner needs to subscribe to the local broker and execute inference.
10836
10932
  *
10837
- * Stateless-pipeline model: the full pipeline content (`engine`, `steps`,
10838
- * optional `audio`) travels with the attach payload. The runner keeps it
10839
- * in RAM for the lifetime of the attach — on rebalance, edit, or
10840
- * restart the orchestrator re-sends the latest snapshot.
10841
- *
10842
- * `engine`/`steps`/`audio` are optional during the additive migration
10843
- * window; once orchestrator + UI are migrated they become required.
10933
+ * Stateless-pipeline model: the pipeline content (`steps`, optional
10934
+ * `audio`) travels with the attach payload. The runner keeps it in RAM
10935
+ * for the lifetime of the attach — on rebalance, edit, or restart the
10936
+ * orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
10937
+ * node-local, resolved by the executing runner at dispatch time.
10844
10938
  */
10845
10939
  var RunnerCameraConfigSchema = object({
10846
10940
  deviceId: number(),
@@ -10891,14 +10985,11 @@ var RunnerCameraConfigSchema = object({
10891
10985
  */
10892
10986
  motionSources: MotionSourcesSchema.default(["analyzer"]),
10893
10987
  pipelineEnabled: boolean().default(true),
10894
- /** Engine choice for video steps (runtime+backend+format). */
10895
- engine: PipelineEngineChoiceSchema.optional(),
10896
10988
  /** Ordered tree of video steps. Absent → runner skips video detection. */
10897
10989
  steps: array(PipelineStepInputSchema).readonly().optional(),
10898
10990
  /** Audio classification branch. `enabled:false` disables, null skips. */
10899
10991
  audio: object({
10900
- engine: PipelineEngineChoiceSchema,
10901
- modelId: string(),
10992
+ modelId: string().optional(),
10902
10993
  enabled: boolean()
10903
10994
  }).nullable().optional(),
10904
10995
  /**
@@ -12279,7 +12370,9 @@ var AddonPageDeclarationSchema$1 = object({
12279
12370
  icon: string(),
12280
12371
  path: string(),
12281
12372
  remoteName: string(),
12282
- bundle: string()
12373
+ bundle: string(),
12374
+ section: string().optional(),
12375
+ sectionLabel: string().optional()
12283
12376
  });
12284
12377
  var AddonPageInfoSchema = object({
12285
12378
  addonId: string(),
@@ -12319,7 +12412,18 @@ var AddonPageDeclarationSchema = object({
12319
12412
  * the static-file route can compute an mtime-based cache-buster URL
12320
12413
  * without a separate filesystem stat.
12321
12414
  */
12322
- bundle: string()
12415
+ bundle: string(),
12416
+ /**
12417
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12418
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12419
+ * Any OTHER string creates (or joins) a custom section rendered after
12420
+ * the built-in groups; its label comes from `sectionLabel` (first
12421
+ * declaration wins), falling back to the id. Absent → the legacy
12422
+ * "Addon Pages" group.
12423
+ */
12424
+ section: string().optional(),
12425
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12426
+ sectionLabel: string().optional()
12323
12427
  });
12324
12428
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12325
12429
  var AddonHttpRouteSchema = object({
@@ -12535,6 +12639,17 @@ var WidgetMetadataSchema = object({
12535
12639
  deviceContext: boolean().default(false),
12536
12640
  integrationContext: boolean().default(false)
12537
12641
  }),
12642
+ /**
12643
+ * Loadable BEFORE authentication. The normal widget registry listing
12644
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
12645
+ * (the login page) cannot discover a widget through it. A widget that
12646
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
12647
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
12648
+ * login-method contribution channel (see `login-method.cap.ts`) rather
12649
+ * than the authenticated registry, and its bundle is served by the
12650
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
12651
+ */
12652
+ preAuth: boolean().optional().default(false),
12538
12653
  /** Dashboard placement HINTS (operator can override per instance). */
12539
12654
  defaultSize: WidgetSizeEnum.default("md"),
12540
12655
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -12836,6 +12951,66 @@ method(object({
12836
12951
  password: string()
12837
12952
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
12838
12953
  /**
12954
+ * `login-method` — collection cap through which auth addons contribute
12955
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
12956
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
12957
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
12958
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
12959
+ * procedure aggregates them for the unauthenticated login page.
12960
+ *
12961
+ * A contribution is a discriminated union on `kind`:
12962
+ *
12963
+ * - `redirect` — a declarative button. The login page renders a generic
12964
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
12965
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
12966
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
12967
+ * login page needs NO change.
12968
+ *
12969
+ * - `widget` — a Module-Federation widget the login page mounts (via
12970
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
12971
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
12972
+ * addon bundle. The referenced widget also declares `preAuth: true` in
12973
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
12974
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
12975
+ *
12976
+ * Every contribution carries a `stage`:
12977
+ * - `primary` — shown on the first credentials screen (OIDC /
12978
+ * magic-link buttons; a future usernameless passkey).
12979
+ * - `second-factor` — shown AFTER the password leg, gated on the
12980
+ * returned `factors` (passkey-as-2FA today).
12981
+ *
12982
+ * `mount: skip` — the cap is read server-side by the core auth router
12983
+ * (`registry.getCollection('login-method')`), never mounted as its own
12984
+ * tRPC router.
12985
+ */
12986
+ /** When a login method renders in the two-phase login flow. */
12987
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
12988
+ /** One login-method contribution — redirect button OR pre-auth widget. */
12989
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
12990
+ kind: literal("redirect"),
12991
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
12992
+ id: string(),
12993
+ /** Operator-facing button label. */
12994
+ label: string(),
12995
+ /** lucide-react icon name. */
12996
+ icon: string().optional(),
12997
+ /** Addon-owned HTTP route the button navigates to (GET). */
12998
+ startUrl: string(),
12999
+ stage: LoginStageEnum
13000
+ }), object({
13001
+ kind: literal("widget"),
13002
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
13003
+ id: string(),
13004
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
13005
+ addonId: string(),
13006
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
13007
+ bundle: string(),
13008
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
13009
+ remote: WidgetRemoteSchema,
13010
+ stage: LoginStageEnum
13011
+ })]);
13012
+ method(_void(), array(LoginMethodContributionSchema).readonly());
13013
+ /**
12839
13014
  * Orchestrator-side destination metadata. The orchestrator computes
12840
13015
  * `id = <addonId>:<subId>` from its provider lookup so consumers
12841
13016
  * (admin UI, restore flow) see one canonical key.
@@ -15192,11 +15367,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15192
15367
  timestamp: number()
15193
15368
  });
15194
15369
  var CameraPipelineConfigSchema = object({
15195
- engine: PipelineEngineChoiceSchema,
15370
+ engine: PipelineEngineChoiceSchema.optional(),
15196
15371
  steps: array(PipelineStepInputSchema).readonly(),
15197
15372
  audio: object({
15198
- engine: PipelineEngineChoiceSchema,
15199
- modelId: string(),
15373
+ engine: PipelineEngineChoiceSchema.optional(),
15374
+ modelId: string().optional(),
15200
15375
  enabled: boolean(),
15201
15376
  settings: record(string(), unknown()).readonly().optional()
15202
15377
  }).nullable().optional()
@@ -15211,7 +15386,7 @@ var PipelineTemplateSchema = object({
15211
15386
  });
15212
15387
  var AgentAddonConfigSchema = object({
15213
15388
  enabled: boolean(),
15214
- modelId: string(),
15389
+ modelId: string().optional(),
15215
15390
  settings: record(string(), unknown()).readonly()
15216
15391
  });
15217
15392
  var AgentPipelineSettingsSchema = object({
@@ -15221,12 +15396,25 @@ var AgentPipelineSettingsSchema = object({
15221
15396
  detectWeight: number().positive().optional(),
15222
15397
  /** Node is eligible to run the detection pipeline (decode + inference). */
15223
15398
  detect: boolean().optional(),
15224
- /** Node is eligible to host decoder sessions. */
15399
+ /**
15400
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15401
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15402
+ * the schema ONLY so persisted stores written before the removal still
15403
+ * parse — no code reads it and no write path emits it.
15404
+ */
15225
15405
  decode: boolean().optional(),
15226
15406
  /** Node is eligible to run audio-analyzer sessions. */
15227
15407
  audio: boolean().optional(),
15228
15408
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
15229
- ingest: boolean().optional()
15409
+ ingest: boolean().optional(),
15410
+ /**
15411
+ * Operator override for the LAN host a cross-node decoder dials to reach
15412
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
15413
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
15414
+ * it already uses to reach the hub). Set this only when the auto-detected
15415
+ * address is wrong (multi-homed host, NAT, custom interface).
15416
+ */
15417
+ reachableHost: string().optional()
15230
15418
  });
15231
15419
  var CameraPipelineForAgentSchema = object({
15232
15420
  steps: array(PipelineStepInputSchema).readonly(),
@@ -15274,25 +15462,6 @@ var PipelineAssignmentSchema = object({
15274
15462
  assignedAt: number()
15275
15463
  });
15276
15464
  /**
15277
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15278
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15279
- * → co-located with pipeline → capacity).
15280
- */
15281
- var DecoderAssignmentSchema = object({
15282
- deviceId: number(),
15283
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15284
- decoderNodeId: string(),
15285
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15286
- pinned: boolean(),
15287
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15288
- reason: _enum([
15289
- "manual",
15290
- "co-located",
15291
- "capacity",
15292
- "hardware-affinity"
15293
- ])
15294
- });
15295
- /**
15296
15465
  * Per-agent load summary surfaced to the load balancer + dashboards.
15297
15466
  * Aggregated from each runner's `getLocalLoad` cap call.
15298
15467
  */
@@ -15332,6 +15501,15 @@ var GlobalMetricsSchema = object({
15332
15501
  * capability providers.
15333
15502
  */
15334
15503
  var CapabilityBindingsSchema = record(string(), string());
15504
+ /**
15505
+ * The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
15506
+ * its LAN-reachable host, if one is registered. See `getIngestOwner`.
15507
+ */
15508
+ var IngestOwnerSchema = object({
15509
+ ownerNodeId: string(),
15510
+ reachableHost: string().optional(),
15511
+ configIssue: string().optional()
15512
+ });
15335
15513
  /** Source block — always present; derives from the stream catalog. */
15336
15514
  var CameraSourceStatusSchema = object({ streams: array(object({
15337
15515
  camStreamId: string(),
@@ -15346,6 +15524,14 @@ var CameraAssignmentStatusSchema = object({
15346
15524
  detectionNodeId: string().nullable(),
15347
15525
  decoderNodeId: string().nullable(),
15348
15526
  audioNodeId: string().nullable(),
15527
+ /**
15528
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
15529
+ * hosts the broker/restream) — the cluster ingest owner today
15530
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
15531
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
15532
+ * broker block below was read from (pinned). Nullable only pre-wiring.
15533
+ */
15534
+ sourceNodeId: string().nullable(),
15349
15535
  pinned: object({
15350
15536
  detection: boolean(),
15351
15537
  decoder: boolean(),
@@ -15478,16 +15664,7 @@ method(object({
15478
15664
  }), object({ success: literal(true) }), {
15479
15665
  kind: "mutation",
15480
15666
  auth: "admin"
15481
- }), method(object({
15482
- deviceId: number(),
15483
- nodeId: string()
15484
- }), _void(), {
15485
- kind: "mutation",
15486
- auth: "admin"
15487
- }), method(object({ deviceId: number() }), _void(), {
15488
- kind: "mutation",
15489
- auth: "admin"
15490
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15667
+ }), method(_void(), IngestOwnerSchema), method(object({
15491
15668
  deviceId: number(),
15492
15669
  nodeId: string()
15493
15670
  }), object({ success: literal(true) }), {
@@ -15508,10 +15685,7 @@ method(object({
15508
15685
  nodeId: string(),
15509
15686
  pinned: boolean(),
15510
15687
  assignedAt: number()
15511
- }))), method(object({
15512
- deviceId: number(),
15513
- pipelineNodeId: string().optional()
15514
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15688
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15515
15689
  nodeId: string(),
15516
15690
  settings: AgentPipelineSettingsSchema
15517
15691
  })).readonly()), method(object({
@@ -15541,12 +15715,26 @@ method(object({
15541
15715
  }), method(object({
15542
15716
  agentNodeId: string(),
15543
15717
  detect: boolean().nullable().optional(),
15544
- decode: boolean().nullable().optional(),
15545
15718
  audio: boolean().nullable().optional(),
15546
15719
  ingest: boolean().nullable().optional()
15547
15720
  }), object({ success: literal(true) }), {
15548
15721
  kind: "mutation",
15549
15722
  auth: "admin"
15723
+ }), method(object({
15724
+ agentNodeId: string(),
15725
+ reachableHost: string().nullable()
15726
+ }), object({ success: literal(true) }), {
15727
+ kind: "mutation",
15728
+ auth: "admin"
15729
+ }), method(object({ agentNodeId: string() }), object({
15730
+ success: literal(true),
15731
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
15732
+ effectiveModelId: string().nullable(),
15733
+ /** Number of cameras whose node-scoped overrides were cleared. */
15734
+ clearedCameraOverrides: number()
15735
+ }), {
15736
+ kind: "mutation",
15737
+ auth: "admin"
15550
15738
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15551
15739
  deviceId: number(),
15552
15740
  addonId: string(),
@@ -15591,22 +15779,131 @@ method(object({
15591
15779
  kind: "mutation",
15592
15780
  auth: "admin"
15593
15781
  });
15594
- var RegisteredStreamSchema = object({
15595
- streamId: string(),
15596
- label: string().optional(),
15597
- codec: string(),
15598
- type: _enum(["video", "audio"]),
15599
- sourceUrl: string()
15782
+ /**
15783
+ * server-management — per-NODE singleton capability for a node's ROOT
15784
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
15785
+ * agents).
15786
+ *
15787
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
15788
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
15789
+ * version describes the node. Updates install into
15790
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
15791
+ * starter (probation boot + auto-rollback to N-1).
15792
+ *
15793
+ * Providers:
15794
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
15795
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
15796
+ * unpinned calls.
15797
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
15798
+ * the synthetic `agent-runtime` addonId and declared in the agent's
15799
+ * `$hub.registerNode` manifest.
15800
+ *
15801
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
15802
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
15803
+ * SDK) routes the call to that node's provider via the standard remote
15804
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
15805
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
15806
+ *
15807
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
15808
+ */
15809
+ /**
15810
+ * Where the running hub's code was loaded from:
15811
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
15812
+ * plain resolution and runtime updates are refused.
15813
+ * - `baked` — the immutable image seed closure (no data-dir root active).
15814
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
15815
+ */
15816
+ var ServerBootModeSchema = _enum([
15817
+ "workspace",
15818
+ "baked",
15819
+ "data-root"
15820
+ ]);
15821
+ /**
15822
+ * Update lifecycle state:
15823
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
15824
+ * - `pending-restart` — a version is staged and the node has NOT yet
15825
+ * restarted onto it (still running the OLD version).
15826
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
15827
+ * (it is the active probation boot) and is waiting to confirm boot-health.
15828
+ * Apply/rollback are refused in this state and the node must NOT be
15829
+ * manually restarted, or the probation boot auto-rolls-back.
15830
+ */
15831
+ var ServerUpdateStateSchema = _enum([
15832
+ "idle",
15833
+ "checking",
15834
+ "staging",
15835
+ "pending-restart",
15836
+ "awaiting-confirmation"
15837
+ ]);
15838
+ var ServerRollbackInfoSchema = object({
15839
+ /** The version that failed (or was manually rolled back). */
15840
+ fromVersion: string(),
15841
+ /** The version rolled back to; null = the baked seed. */
15842
+ toVersion: string().nullable(),
15843
+ atMs: number(),
15844
+ reason: string()
15600
15845
  });
15601
- var ExposedResourceSchema = object({
15602
- streamId: string(),
15603
- format: string(),
15604
- value: string()
15846
+ var ServerPackageStatusSchema = object({
15847
+ /** Root package name (`@camstack/server` on the hub). */
15848
+ packageName: string(),
15849
+ /** Version of the code the running process ACTUALLY loaded. */
15850
+ runningVersion: string().nullable(),
15851
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
15852
+ nodeRuntimeVersion: string().nullable(),
15853
+ /** Active data-dir root version; null when booted from seed/workspace. */
15854
+ activeVersion: string().nullable(),
15855
+ /** N-1 version kept for rollback; null when no previous version exists. */
15856
+ previousVersion: string().nullable(),
15857
+ /** Version of the immutable baked seed closure (image fallback). */
15858
+ seedVersion: string().nullable(),
15859
+ /** Latest registry version from the most recent check (null = never checked). */
15860
+ latestVersion: string().nullable(),
15861
+ updateAvailable: boolean(),
15862
+ bootMode: ServerBootModeSchema,
15863
+ updateState: ServerUpdateStateSchema,
15864
+ /** Version staged + awaiting its probation boot, when one is pending. */
15865
+ pendingVersion: string().nullable(),
15866
+ /** Set when the last freshly-activated version failed its boot health-check. */
15867
+ rolledBack: ServerRollbackInfoSchema.nullable(),
15868
+ /**
15869
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
15870
+ * hub is running from the baked seed (or workspace) while installed data-dir
15871
+ * versions are being IGNORED. Surfaced as a warning in the UI.
15872
+ */
15873
+ stateFileCorrupt: boolean(),
15874
+ lastCheckedAtMs: number().nullable()
15875
+ });
15876
+ var ServerUpdateCheckResultSchema = object({
15877
+ packageName: string(),
15878
+ runningVersion: string().nullable(),
15879
+ latestVersion: string().nullable(),
15880
+ updateAvailable: boolean(),
15881
+ checkedAtMs: number(),
15882
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
15883
+ error: string().nullable()
15884
+ });
15885
+ var ServerUpdateActionResultSchema = object({
15886
+ accepted: boolean(),
15887
+ targetVersion: string().nullable(),
15888
+ /** True when a graceful restart was scheduled to apply the change. */
15889
+ restarting: boolean(),
15890
+ message: string()
15891
+ });
15892
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
15893
+ kind: "mutation",
15894
+ auth: "admin"
15895
+ }), method(object({
15896
+ /** Explicit target version; omitted = latest from the registry. */
15897
+ version: string().optional() }), ServerUpdateActionResultSchema, {
15898
+ kind: "mutation",
15899
+ auth: "admin"
15900
+ }), method(_void(), ServerUpdateActionResultSchema, {
15901
+ kind: "mutation",
15902
+ auth: "admin"
15903
+ }), method(_void(), ServerUpdateActionResultSchema, {
15904
+ kind: "mutation",
15905
+ auth: "admin"
15605
15906
  });
15606
- method(object({
15607
- deviceId: number(),
15608
- streams: array(RegisteredStreamSchema).readonly()
15609
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
15610
15907
  /**
15611
15908
  * Query filter for settings-store collections.
15612
15909
  */
@@ -15759,9 +16056,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
15759
16056
  /**
15760
16057
  * A single device snapshot returned as base64 JPEG/PNG.
15761
16058
  *
15762
- * Shared with the `snapshot-provider` collection cap the orchestrator
15763
- * receives the same shape from each native provider and from the
15764
- * broker-based fallback.
16059
+ * The `SnapshotAddon` wrapper returns this shape whether the frame came from
16060
+ * the device-native provider (onboard capture) or from the stream-broker
16061
+ * prebuffer fallback.
15765
16062
  */
15766
16063
  var SnapshotImageSchema = object({
15767
16064
  base64: string(),
@@ -15793,10 +16090,6 @@ DeviceType.Camera, method(object({
15793
16090
  kind: "mutation",
15794
16091
  auth: "admin"
15795
16092
  });
15796
- method(object({ deviceId: number() }), boolean()), method(object({
15797
- deviceId: number(),
15798
- streamId: string().optional()
15799
- }), SnapshotImageSchema.nullable());
15800
16093
  /**
15801
16094
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
15802
16095
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16157,9 +16450,10 @@ method(object({
16157
16450
  auth: "admin"
16158
16451
  });
16159
16452
  /**
16160
- * Optional client-side hints sent at session creation to help the
16161
- * provider pick the best native source. All fields are optional —
16162
- * a viewer that knows nothing still gets a sane default.
16453
+ * Optional client-side hints sent at session creation to help the provider
16454
+ * pick the best native source. All fields optional — a viewer that knows
16455
+ * nothing still gets a sane default. (Relocated from the retired `webrtc`
16456
+ * collection cap; this `webrtc-session` cap is the live signaling surface.)
16163
16457
  */
16164
16458
  var webrtcClientHintsSchema = object({
16165
16459
  viewportWidth: number().int().positive().optional(),
@@ -16170,22 +16464,6 @@ var webrtcClientHintsSchema = object({
16170
16464
  /** Hard tier override; takes precedence over scoring when registered. */
16171
16465
  prefersTier: string().optional()
16172
16466
  }).partial();
16173
- method(object({
16174
- streamId: string(),
16175
- sdpOffer: string()
16176
- }), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
16177
- streamId: string(),
16178
- codec: string()
16179
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
16180
- streamId: string(),
16181
- hints: webrtcClientHintsSchema.optional()
16182
- }), object({
16183
- sessionId: string(),
16184
- sdpOffer: string()
16185
- }), { kind: "mutation" }), method(object({
16186
- sessionId: string(),
16187
- sdpAnswer: string()
16188
- }), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
16189
16467
  /**
16190
16468
  * Discriminated target for a WebRTC session. The client sends this
16191
16469
  * structured object instead of building / parsing brokerId strings;
@@ -16672,7 +16950,15 @@ var FrameworkPackageStatusSchema = object({
16672
16950
  latestVersion: string().nullable(),
16673
16951
  hasUpdate: boolean(),
16674
16952
  /** Optional manifest description for the row tooltip. */
16675
- description: string().optional()
16953
+ description: string().optional(),
16954
+ /**
16955
+ * Content build-id (md5 of the resolved `dist/` tree) of the code the hub
16956
+ * ACTUALLY loaded. Framework packages ship code changes without always
16957
+ * bumping `currentVersion`, so semver alone hides "same version, new code".
16958
+ * `null` when the dist can't be hashed (not installed / empty). The admin-UI
16959
+ * surfaces this so a stale-code hub is visible even at an unchanged version.
16960
+ */
16961
+ buildId: string().nullable()
16676
16962
  });
16677
16963
  var LogStreamEntrySchema = object({
16678
16964
  timestamp: string(),
@@ -17605,6 +17891,16 @@ var TopologyCategorySchema = object({
17605
17891
  healthy: number(),
17606
17892
  addons: array(TopologyCategoryAddonSchema).readonly()
17607
17893
  });
17894
+ /**
17895
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
17896
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
17897
+ * version visibility for the Server management surface. Nullable: offline
17898
+ * rows and pre-phase-2 nodes report none.
17899
+ */
17900
+ var TopologyRootPackageSchema = object({
17901
+ name: string(),
17902
+ version: string()
17903
+ });
17608
17904
  var TopologyNodeSchema = object({
17609
17905
  id: string(),
17610
17906
  name: string(),
@@ -17628,7 +17924,8 @@ var TopologyNodeSchema = object({
17628
17924
  status: string()
17629
17925
  })).readonly(),
17630
17926
  processes: array(TopologyProcessSchema).readonly(),
17631
- categories: array(TopologyCategorySchema).readonly()
17927
+ categories: array(TopologyCategorySchema).readonly(),
17928
+ rootPackage: TopologyRootPackageSchema.nullable()
17632
17929
  });
17633
17930
  var CapUsageEdgeSchema = object({
17634
17931
  callerAddonId: string(),
@@ -20428,6 +20725,12 @@ Object.freeze({
20428
20725
  addonId: null,
20429
20726
  access: "create"
20430
20727
  },
20728
+ "loginMethod.getLoginMethods": {
20729
+ capName: "login-method",
20730
+ capScope: "system",
20731
+ addonId: null,
20732
+ access: "view"
20733
+ },
20431
20734
  "mediaPlayer.next": {
20432
20735
  capName: "media-player",
20433
20736
  capScope: "device",
@@ -21058,23 +21361,23 @@ Object.freeze({
21058
21361
  addonId: null,
21059
21362
  access: "create"
21060
21363
  },
21061
- "pipelineExecutor.deleteModel": {
21364
+ "pipelineExecutor.clearDeviceOverrides": {
21062
21365
  capName: "pipeline-executor",
21063
21366
  capScope: "system",
21064
21367
  addonId: null,
21065
21368
  access: "delete"
21066
21369
  },
21067
- "pipelineExecutor.deleteTemplate": {
21370
+ "pipelineExecutor.deleteModel": {
21068
21371
  capName: "pipeline-executor",
21069
21372
  capScope: "system",
21070
21373
  addonId: null,
21071
21374
  access: "delete"
21072
21375
  },
21073
- "pipelineExecutor.detect": {
21376
+ "pipelineExecutor.deleteTemplate": {
21074
21377
  capName: "pipeline-executor",
21075
21378
  capScope: "system",
21076
21379
  addonId: null,
21077
- access: "view"
21380
+ access: "delete"
21078
21381
  },
21079
21382
  "pipelineExecutor.downloadModel": {
21080
21383
  capName: "pipeline-executor",
@@ -21268,13 +21571,13 @@ Object.freeze({
21268
21571
  addonId: null,
21269
21572
  access: "create"
21270
21573
  },
21271
- "pipelineOrchestrator.assignAudio": {
21272
- capName: "pipeline-orchestrator",
21574
+ "pipelineExecutor.validatePipeline": {
21575
+ capName: "pipeline-executor",
21273
21576
  capScope: "system",
21274
21577
  addonId: null,
21275
- access: "create"
21578
+ access: "view"
21276
21579
  },
21277
- "pipelineOrchestrator.assignDecoder": {
21580
+ "pipelineOrchestrator.assignAudio": {
21278
21581
  capName: "pipeline-orchestrator",
21279
21582
  capScope: "system",
21280
21583
  addonId: null,
@@ -21358,19 +21661,13 @@ Object.freeze({
21358
21661
  addonId: null,
21359
21662
  access: "view"
21360
21663
  },
21361
- "pipelineOrchestrator.getDecoderAssignment": {
21362
- capName: "pipeline-orchestrator",
21363
- capScope: "system",
21364
- addonId: null,
21365
- access: "view"
21366
- },
21367
- "pipelineOrchestrator.getDecoderAssignments": {
21664
+ "pipelineOrchestrator.getGlobalMetrics": {
21368
21665
  capName: "pipeline-orchestrator",
21369
21666
  capScope: "system",
21370
21667
  addonId: null,
21371
21668
  access: "view"
21372
21669
  },
21373
- "pipelineOrchestrator.getGlobalMetrics": {
21670
+ "pipelineOrchestrator.getIngestOwner": {
21374
21671
  capName: "pipeline-orchestrator",
21375
21672
  capScope: "system",
21376
21673
  addonId: null,
@@ -21412,6 +21709,12 @@ Object.freeze({
21412
21709
  addonId: null,
21413
21710
  access: "delete"
21414
21711
  },
21712
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
21713
+ capName: "pipeline-orchestrator",
21714
+ capScope: "system",
21715
+ addonId: null,
21716
+ access: "delete"
21717
+ },
21415
21718
  "pipelineOrchestrator.resolvePipeline": {
21416
21719
  capName: "pipeline-orchestrator",
21417
21720
  capScope: "system",
@@ -21448,37 +21751,37 @@ Object.freeze({
21448
21751
  addonId: null,
21449
21752
  access: "create"
21450
21753
  },
21451
- "pipelineOrchestrator.setCameraPipelineForAgent": {
21754
+ "pipelineOrchestrator.setAgentReachableHost": {
21452
21755
  capName: "pipeline-orchestrator",
21453
21756
  capScope: "system",
21454
21757
  addonId: null,
21455
21758
  access: "create"
21456
21759
  },
21457
- "pipelineOrchestrator.setCameraStepOverride": {
21760
+ "pipelineOrchestrator.setCameraPipelineForAgent": {
21458
21761
  capName: "pipeline-orchestrator",
21459
21762
  capScope: "system",
21460
21763
  addonId: null,
21461
21764
  access: "create"
21462
21765
  },
21463
- "pipelineOrchestrator.setCameraStepToggle": {
21766
+ "pipelineOrchestrator.setCameraStepOverride": {
21464
21767
  capName: "pipeline-orchestrator",
21465
21768
  capScope: "system",
21466
21769
  addonId: null,
21467
21770
  access: "create"
21468
21771
  },
21469
- "pipelineOrchestrator.setCapabilityBinding": {
21772
+ "pipelineOrchestrator.setCameraStepToggle": {
21470
21773
  capName: "pipeline-orchestrator",
21471
21774
  capScope: "system",
21472
21775
  addonId: null,
21473
21776
  access: "create"
21474
21777
  },
21475
- "pipelineOrchestrator.unassignAudio": {
21778
+ "pipelineOrchestrator.setCapabilityBinding": {
21476
21779
  capName: "pipeline-orchestrator",
21477
21780
  capScope: "system",
21478
21781
  addonId: null,
21479
21782
  access: "create"
21480
21783
  },
21481
- "pipelineOrchestrator.unassignDecoder": {
21784
+ "pipelineOrchestrator.unassignAudio": {
21482
21785
  capName: "pipeline-orchestrator",
21483
21786
  capScope: "system",
21484
21787
  addonId: null,
@@ -21778,33 +22081,45 @@ Object.freeze({
21778
22081
  addonId: null,
21779
22082
  access: "create"
21780
22083
  },
21781
- "restreamer.getExposedResources": {
21782
- capName: "restreamer",
22084
+ "scriptRunner.run": {
22085
+ capName: "script-runner",
22086
+ capScope: "device",
22087
+ addonId: null,
22088
+ access: "create"
22089
+ },
22090
+ "scriptRunner.stop": {
22091
+ capName: "script-runner",
22092
+ capScope: "device",
22093
+ addonId: null,
22094
+ access: "create"
22095
+ },
22096
+ "serverManagement.applyServerUpdate": {
22097
+ capName: "server-management",
21783
22098
  capScope: "system",
21784
22099
  addonId: null,
21785
- access: "view"
22100
+ access: "create"
21786
22101
  },
21787
- "restreamer.registerDevice": {
21788
- capName: "restreamer",
22102
+ "serverManagement.checkServerUpdate": {
22103
+ capName: "server-management",
21789
22104
  capScope: "system",
21790
22105
  addonId: null,
21791
22106
  access: "create"
21792
22107
  },
21793
- "restreamer.unregisterDevice": {
21794
- capName: "restreamer",
22108
+ "serverManagement.getServerPackageStatus": {
22109
+ capName: "server-management",
21795
22110
  capScope: "system",
21796
22111
  addonId: null,
21797
- access: "delete"
22112
+ access: "view"
21798
22113
  },
21799
- "scriptRunner.run": {
21800
- capName: "script-runner",
21801
- capScope: "device",
22114
+ "serverManagement.restartServer": {
22115
+ capName: "server-management",
22116
+ capScope: "system",
21802
22117
  addonId: null,
21803
22118
  access: "create"
21804
22119
  },
21805
- "scriptRunner.stop": {
21806
- capName: "script-runner",
21807
- capScope: "device",
22120
+ "serverManagement.rollbackServerUpdate": {
22121
+ capName: "server-management",
22122
+ capScope: "system",
21808
22123
  addonId: null,
21809
22124
  access: "create"
21810
22125
  },
@@ -21898,18 +22213,6 @@ Object.freeze({
21898
22213
  addonId: null,
21899
22214
  access: "create"
21900
22215
  },
21901
- "snapshotProvider.getSnapshot": {
21902
- capName: "snapshot-provider",
21903
- capScope: "system",
21904
- addonId: null,
21905
- access: "view"
21906
- },
21907
- "snapshotProvider.supportsDevice": {
21908
- capName: "snapshot-provider",
21909
- capScope: "system",
21910
- addonId: null,
21911
- access: "view"
21912
- },
21913
22216
  "ssoBridge.signBridgeToken": {
21914
22217
  capName: "sso-bridge",
21915
22218
  capScope: "system",
@@ -22336,30 +22639,6 @@ Object.freeze({
22336
22639
  addonId: null,
22337
22640
  access: "view"
22338
22641
  },
22339
- "streamingEngine.getStreamUrl": {
22340
- capName: "streaming-engine",
22341
- capScope: "system",
22342
- addonId: null,
22343
- access: "view"
22344
- },
22345
- "streamingEngine.listStreams": {
22346
- capName: "streaming-engine",
22347
- capScope: "system",
22348
- addonId: null,
22349
- access: "view"
22350
- },
22351
- "streamingEngine.registerStream": {
22352
- capName: "streaming-engine",
22353
- capScope: "system",
22354
- addonId: null,
22355
- access: "create"
22356
- },
22357
- "streamingEngine.unregisterStream": {
22358
- capName: "streaming-engine",
22359
- capScope: "system",
22360
- addonId: null,
22361
- access: "delete"
22362
- },
22363
22642
  "streamParams.getConfigSchema": {
22364
22643
  capName: "stream-params",
22365
22644
  capScope: "device",
@@ -22708,6 +22987,18 @@ Object.freeze({
22708
22987
  addonId: null,
22709
22988
  access: "view"
22710
22989
  },
22990
+ "viewerUi.getStaticDir": {
22991
+ capName: "viewer-ui",
22992
+ capScope: "system",
22993
+ addonId: null,
22994
+ access: "view"
22995
+ },
22996
+ "viewerUi.getVersion": {
22997
+ capName: "viewer-ui",
22998
+ capScope: "system",
22999
+ addonId: null,
23000
+ access: "view"
23001
+ },
22711
23002
  "waterHeater.setAway": {
22712
23003
  capName: "water-heater",
22713
23004
  capScope: "device",
@@ -22726,54 +23017,6 @@ Object.freeze({
22726
23017
  addonId: null,
22727
23018
  access: "create"
22728
23019
  },
22729
- "webrtc.closeSession": {
22730
- capName: "webrtc",
22731
- capScope: "system",
22732
- addonId: null,
22733
- access: "create"
22734
- },
22735
- "webrtc.createSession": {
22736
- capName: "webrtc",
22737
- capScope: "system",
22738
- addonId: null,
22739
- access: "create"
22740
- },
22741
- "webrtc.handleAnswer": {
22742
- capName: "webrtc",
22743
- capScope: "system",
22744
- addonId: null,
22745
- access: "create"
22746
- },
22747
- "webrtc.handleOffer": {
22748
- capName: "webrtc",
22749
- capScope: "system",
22750
- addonId: null,
22751
- access: "create"
22752
- },
22753
- "webrtc.hasAdaptiveBitrate": {
22754
- capName: "webrtc",
22755
- capScope: "system",
22756
- addonId: null,
22757
- access: "view"
22758
- },
22759
- "webrtc.registerStream": {
22760
- capName: "webrtc",
22761
- capScope: "system",
22762
- addonId: null,
22763
- access: "create"
22764
- },
22765
- "webrtc.supportsStream": {
22766
- capName: "webrtc",
22767
- capScope: "system",
22768
- addonId: null,
22769
- access: "view"
22770
- },
22771
- "webrtc.unregisterStream": {
22772
- capName: "webrtc",
22773
- capScope: "system",
22774
- addonId: null,
22775
- access: "delete"
22776
- },
22777
23020
  "webrtcSession.addIceCandidate": {
22778
23021
  capName: "webrtc-session",
22779
23022
  capScope: "device",