@camstack/addon-remote-storage 1.1.20 → 1.1.21

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.
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-CZDdRBua.mjs
4632
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -4815,6 +4815,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4815
4815
  */
4816
4816
  EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
4817
4817
  /**
4818
+ * The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
4819
+ * Emitted by addon-pipeline-orchestrator whenever it (re)derives node
4820
+ * capabilities — at boot, on agent online/offline, and on an ingest-node
4821
+ * flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
4822
+ * keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
4823
+ * cross-process `getIngestOwner` query (push the authority's decision instead
4824
+ * of polling it on the hot path). Idempotent state — re-emitted on every
4825
+ * topology change, so a dropped event self-heals on the next one (plus the
4826
+ * broker's long backstop reconcile query).
4827
+ */
4828
+ EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
4829
+ /**
4818
4830
  * Periodic snapshot of per-node pipeline-runner load
4819
4831
  * (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
4820
4832
  * subscribe instead of polling `pipelineRunner.getLocalLoad`.
@@ -5338,10 +5350,6 @@ function hydrateField(field, values) {
5338
5350
  };
5339
5351
  }
5340
5352
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5341
- if (field.type === "password") return {
5342
- ...field,
5343
- value: ""
5344
- };
5345
5353
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5346
5354
  return {
5347
5355
  ...field,
@@ -6725,6 +6733,9 @@ function method(input, output, options) {
6725
6733
  timeoutMs: options?.timeoutMs
6726
6734
  };
6727
6735
  }
6736
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6737
+ var VersionOutputSchema$1 = object({ version: string() });
6738
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6728
6739
  var StaticDirOutputSchema = object({ staticDir: string() });
6729
6740
  var VersionOutputSchema = object({ version: string() });
6730
6741
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -6894,6 +6905,36 @@ var ModelFormatsSchema = object({
6894
6905
  tflite: ModelFormatEntrySchema.optional(),
6895
6906
  pt: ModelFormatEntrySchema.optional()
6896
6907
  });
6908
+ /**
6909
+ * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
6910
+ * the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
6911
+ * grouped Family→Tier→Variant picker renders identically in the config UI and
6912
+ * in the pipeline/device steppers. The flat `id` stays the source of truth for
6913
+ * resolution/download/persistence; this is a presentation overlay resolved back
6914
+ * to an `id`.
6915
+ */
6916
+ var ModelVariantGroupSchema = object({
6917
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
6918
+ family: string(),
6919
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
6920
+ tier: string(),
6921
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
6922
+ precision: _enum(["fp32", "int8"]).optional(),
6923
+ /**
6924
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
6925
+ * latency-optimized export (e.g. ReLU-activation variant) — the slot the
6926
+ * future performance variants plug into.
6927
+ */
6928
+ optimization: _enum(["standard", "fast"]).optional(),
6929
+ /**
6930
+ * Input-resolution axis (square input side, px). Omit ⇒ the family's native
6931
+ * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
6932
+ * cheap latency lever — especially on Apple ANE and the Intel N100 — at a
6933
+ * small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
6934
+ * the group so the selector can offer it as a variant axis.
6935
+ */
6936
+ resolution: number().int().positive().optional()
6937
+ });
6897
6938
  var ModelCatalogEntrySchema = object({
6898
6939
  id: string(),
6899
6940
  name: string(),
@@ -6923,7 +6964,43 @@ var ModelCatalogEntrySchema = object({
6923
6964
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6924
6965
  * Downloaded into the same modelsDir alongside the model file.
6925
6966
  */
6926
- extraFiles: array(ModelExtraFileSchema).readonly().optional()
6967
+ extraFiles: array(ModelExtraFileSchema).readonly().optional(),
6968
+ /**
6969
+ * LEGACY entry — retained in the catalog so a persisted operator selection
6970
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
6971
+ * model list and excluded from the auto format-default pick. Set on the
6972
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
6973
+ * the active lineup stays the coherent curated ladder without deleting a
6974
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
6975
+ * an explicit legacy id that has a build for the node's format.
6976
+ */
6977
+ legacy: boolean().optional(),
6978
+ /**
6979
+ * Measured quality/latency metadata — populated from the benchmark addon on
6980
+ * the real node classes. Absent = not yet measured (most entries today; the
6981
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
6982
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
6983
+ */
6984
+ metrics: object({
6985
+ map50: number().optional(),
6986
+ p95LatencyMs: record(string(), number()).optional()
6987
+ }).optional(),
6988
+ /**
6989
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
6990
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
6991
+ * the retraining addon and any future commercial distribution.
6992
+ */
6993
+ license: string().optional(),
6994
+ /**
6995
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
6996
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
6997
+ * of a family's sizes and quantizations collapse into one grouped picker
6998
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
6999
+ * (legacy / custom models) — never shown in the grouped selector. The flat
7000
+ * `id` stays the source of truth for resolution/download/persistence; grouping
7001
+ * is a presentation overlay resolved back to an `id`.
7002
+ */
7003
+ group: ModelVariantGroupSchema.optional()
6927
7004
  });
6928
7005
  var ConvertTargetSchema = discriminatedUnion("format", [object({
6929
7006
  format: literal("openvino"),
@@ -6984,8 +7061,8 @@ var RecordingModeSchema = _enum([
6984
7061
  "onAudioThreshold"
6985
7062
  ]);
6986
7063
  /**
6987
- * First-class, authoritative per-camera storage mode — the netta choice the UI
6988
- * reads directly (never inferred from `rules`):
7064
+ * First-class, authoritative per-camera storage mode — the explicit choice the
7065
+ * UI reads directly (never inferred from `rules`):
6989
7066
  * - `off` — not recording.
6990
7067
  * - `events` — record only around triggers (motion / audio threshold),
6991
7068
  * with pre/post-buffer.
@@ -8633,26 +8710,13 @@ DeviceType.Light, method(object({
8633
8710
  percentage: number().min(0).max(100),
8634
8711
  lastChangedAt: number()
8635
8712
  });
8713
+ /** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
8636
8714
  var StreamFormatSchema = _enum([
8637
8715
  "webrtc",
8638
8716
  "hls",
8639
8717
  "mjpeg",
8640
8718
  "rtsp"
8641
8719
  ]);
8642
- var StreamInfoSchema = object({
8643
- streamId: string(),
8644
- format: StreamFormatSchema,
8645
- url: string().nullable(),
8646
- active: boolean()
8647
- });
8648
- method(object({
8649
- streamId: string(),
8650
- sourceUrl: string(),
8651
- codec: string().optional()
8652
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
8653
- streamId: string(),
8654
- format: StreamFormatSchema
8655
- }), string().nullable()), method(_void(), array(StreamInfoSchema));
8656
8720
  var RtspRestreamEntrySchema = object({
8657
8721
  brokerId: string(),
8658
8722
  url: string(),
@@ -9317,7 +9381,7 @@ var ConsumablesStatusSchema = object({
9317
9381
  })),
9318
9382
  lastChangedAt: number()
9319
9383
  });
9320
- 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({
9384
+ Object.values(DeviceType), method(object({
9321
9385
  deviceId: number().int().nonnegative(),
9322
9386
  key: string().min(1)
9323
9387
  }), _void(), {
@@ -10232,7 +10296,7 @@ var BoundingBoxSchema = object({
10232
10296
  w: number(),
10233
10297
  h: number()
10234
10298
  });
10235
- var SpatialDetectionSchema = object({
10299
+ object({
10236
10300
  class: string(),
10237
10301
  originalClass: string(),
10238
10302
  score: number(),
@@ -10367,7 +10431,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
10367
10431
  enabled: boolean(),
10368
10432
  modelId: string(),
10369
10433
  children: array(PipelineDefaultStepSchema).readonly(),
10370
- engine: PipelineEngineChoiceSchema.optional(),
10371
10434
  group: string().optional(),
10372
10435
  settings: record(string(), unknown()).optional()
10373
10436
  }));
@@ -10392,7 +10455,9 @@ var PipelineModelOptionSchema = object({
10392
10455
  formats: record(string(), object({
10393
10456
  downloaded: boolean(),
10394
10457
  sizeMB: number()
10395
- }))
10458
+ })),
10459
+ group: ModelVariantGroupSchema.optional(),
10460
+ legacy: boolean().optional()
10396
10461
  });
10397
10462
  var ConfigFieldBridge = custom();
10398
10463
  var PipelineAddonSchemaSchema = object({
@@ -10422,11 +10487,6 @@ var PipelineSchemaSchema = object({
10422
10487
  selectedEngine: PipelineEngineChoiceSchema,
10423
10488
  slots: array(PipelineSlotSchemaSchema).readonly()
10424
10489
  });
10425
- var DetectorOutputSchema = object({
10426
- detections: array(SpatialDetectionSchema).readonly(),
10427
- inferenceMs: number(),
10428
- modelId: string()
10429
- });
10430
10490
  var EngineProvisioningSchema = object({
10431
10491
  runtimeId: _enum([
10432
10492
  "onnx",
@@ -10443,15 +10503,42 @@ var EngineProvisioningSchema = object({
10443
10503
  ]),
10444
10504
  progress: number().optional(),
10445
10505
  error: string().optional(),
10446
- nextRetryAt: number().optional()
10506
+ nextRetryAt: number().optional(),
10507
+ /**
10508
+ * Gate A (config-correctness gate at engine change): human-readable
10509
+ * config issues surfaced EAGERLY when the node's engine changes — model
10510
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
10511
+ * has a <format> build"). Additive/optional: informational only, never
10512
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
10513
+ * Absent/empty when the node-default tree resolves cleanly.
10514
+ */
10515
+ configIssues: array(string()).optional()
10447
10516
  });
10448
10517
  var PipelineStepInputSchema = lazy(() => object({
10449
10518
  addonId: string(),
10450
- modelId: string(),
10519
+ modelId: string().optional(),
10451
10520
  enabled: boolean().default(true),
10452
10521
  children: array(PipelineStepInputSchema).optional(),
10453
10522
  settings: record(string(), unknown()).optional()
10454
10523
  }));
10524
+ var ModelSubstitutionSchema = object({
10525
+ addonId: string(),
10526
+ chosen: string(),
10527
+ running: string(),
10528
+ format: string()
10529
+ });
10530
+ var PipelineValidationIssueSchema = object({
10531
+ addonId: string(),
10532
+ kind: _enum(["unknown-addon", "no-format-build"]),
10533
+ detail: string()
10534
+ });
10535
+ var PipelineValidationResultSchema = object({
10536
+ ok: boolean(),
10537
+ issues: array(PipelineValidationIssueSchema).readonly(),
10538
+ substitutions: array(ModelSubstitutionSchema).readonly(),
10539
+ /** The node's `currentEngine.format` this validation ran against. */
10540
+ format: string()
10541
+ });
10455
10542
  var ReferenceImageEntrySchema = object({
10456
10543
  filename: string(),
10457
10544
  stepIds: array(string()).readonly().optional()
@@ -10522,7 +10609,13 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10522
10609
  })) }), object({ success: literal(true) }), {
10523
10610
  kind: "mutation",
10524
10611
  auth: "admin"
10525
- }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10612
+ }), method(object({ nodeId: string() }), object({
10613
+ success: literal(true),
10614
+ clearedDevices: number()
10615
+ }), {
10616
+ kind: "mutation",
10617
+ auth: "admin"
10618
+ }), 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({
10526
10619
  name: string(),
10527
10620
  steps: array(PipelineTemplateStepSchema).readonly(),
10528
10621
  engine: PipelineEngineChoiceSchema
@@ -10539,10 +10632,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10539
10632
  modelId: string(),
10540
10633
  format: ModelFormatSchema$1
10541
10634
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10542
- addonId: string(),
10543
- frame: FrameInputSchema,
10544
- config: record(string(), unknown()).optional()
10545
- }), DetectorOutputSchema), method(object({
10546
10635
  engine: PipelineEngineChoiceSchema.optional(),
10547
10636
  steps: array(PipelineStepInputSchema).min(1),
10548
10637
  frame: FrameInputSchema.optional(),
@@ -10782,6 +10871,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10782
10871
  kind: literal("remote-restream"),
10783
10872
  /** The camera's source-owner node (slice 1: always the hub). */
10784
10873
  ownerNodeId: string(),
10874
+ /**
10875
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
10876
+ * per-node `reachableHost` override (Cluster UI). When present the runner
10877
+ * dials THIS host for the owner's restream, in preference to the
10878
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
10879
+ */
10880
+ ownerReachableHost: string().optional(),
10785
10881
  /** Operator override for the owner host the runner dials. */
10786
10882
  hubHostnameOverride: string().optional()
10787
10883
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -10790,13 +10886,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10790
10886
  * specific runner instance via `attachCamera`. Carries everything the
10791
10887
  * runner needs to subscribe to the local broker and execute inference.
10792
10888
  *
10793
- * Stateless-pipeline model: the full pipeline content (`engine`, `steps`,
10794
- * optional `audio`) travels with the attach payload. The runner keeps it
10795
- * in RAM for the lifetime of the attach — on rebalance, edit, or
10796
- * restart the orchestrator re-sends the latest snapshot.
10797
- *
10798
- * `engine`/`steps`/`audio` are optional during the additive migration
10799
- * window; once orchestrator + UI are migrated they become required.
10889
+ * Stateless-pipeline model: the pipeline content (`steps`, optional
10890
+ * `audio`) travels with the attach payload. The runner keeps it in RAM
10891
+ * for the lifetime of the attach — on rebalance, edit, or restart the
10892
+ * orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
10893
+ * node-local, resolved by the executing runner at dispatch time.
10800
10894
  */
10801
10895
  var RunnerCameraConfigSchema = object({
10802
10896
  deviceId: number(),
@@ -10847,14 +10941,11 @@ var RunnerCameraConfigSchema = object({
10847
10941
  */
10848
10942
  motionSources: MotionSourcesSchema.default(["analyzer"]),
10849
10943
  pipelineEnabled: boolean().default(true),
10850
- /** Engine choice for video steps (runtime+backend+format). */
10851
- engine: PipelineEngineChoiceSchema.optional(),
10852
10944
  /** Ordered tree of video steps. Absent → runner skips video detection. */
10853
10945
  steps: array(PipelineStepInputSchema).readonly().optional(),
10854
10946
  /** Audio classification branch. `enabled:false` disables, null skips. */
10855
10947
  audio: object({
10856
- engine: PipelineEngineChoiceSchema,
10857
- modelId: string(),
10948
+ modelId: string().optional(),
10858
10949
  enabled: boolean()
10859
10950
  }).nullable().optional(),
10860
10951
  /**
@@ -12235,7 +12326,9 @@ var AddonPageDeclarationSchema$1 = object({
12235
12326
  icon: string(),
12236
12327
  path: string(),
12237
12328
  remoteName: string(),
12238
- bundle: string()
12329
+ bundle: string(),
12330
+ section: string().optional(),
12331
+ sectionLabel: string().optional()
12239
12332
  });
12240
12333
  var AddonPageInfoSchema = object({
12241
12334
  addonId: string(),
@@ -12275,7 +12368,18 @@ var AddonPageDeclarationSchema = object({
12275
12368
  * the static-file route can compute an mtime-based cache-buster URL
12276
12369
  * without a separate filesystem stat.
12277
12370
  */
12278
- bundle: string()
12371
+ bundle: string(),
12372
+ /**
12373
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12374
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12375
+ * Any OTHER string creates (or joins) a custom section rendered after
12376
+ * the built-in groups; its label comes from `sectionLabel` (first
12377
+ * declaration wins), falling back to the id. Absent → the legacy
12378
+ * "Addon Pages" group.
12379
+ */
12380
+ section: string().optional(),
12381
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12382
+ sectionLabel: string().optional()
12279
12383
  });
12280
12384
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12281
12385
  var AddonHttpRouteSchema = object({
@@ -12491,6 +12595,17 @@ var WidgetMetadataSchema = object({
12491
12595
  deviceContext: boolean().default(false),
12492
12596
  integrationContext: boolean().default(false)
12493
12597
  }),
12598
+ /**
12599
+ * Loadable BEFORE authentication. The normal widget registry listing
12600
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
12601
+ * (the login page) cannot discover a widget through it. A widget that
12602
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
12603
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
12604
+ * login-method contribution channel (see `login-method.cap.ts`) rather
12605
+ * than the authenticated registry, and its bundle is served by the
12606
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
12607
+ */
12608
+ preAuth: boolean().optional().default(false),
12494
12609
  /** Dashboard placement HINTS (operator can override per instance). */
12495
12610
  defaultSize: WidgetSizeEnum.default("md"),
12496
12611
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -12792,6 +12907,66 @@ method(object({
12792
12907
  password: string()
12793
12908
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
12794
12909
  /**
12910
+ * `login-method` — collection cap through which auth addons contribute
12911
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
12912
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
12913
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
12914
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
12915
+ * procedure aggregates them for the unauthenticated login page.
12916
+ *
12917
+ * A contribution is a discriminated union on `kind`:
12918
+ *
12919
+ * - `redirect` — a declarative button. The login page renders a generic
12920
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
12921
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
12922
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
12923
+ * login page needs NO change.
12924
+ *
12925
+ * - `widget` — a Module-Federation widget the login page mounts (via
12926
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
12927
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
12928
+ * addon bundle. The referenced widget also declares `preAuth: true` in
12929
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
12930
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
12931
+ *
12932
+ * Every contribution carries a `stage`:
12933
+ * - `primary` — shown on the first credentials screen (OIDC /
12934
+ * magic-link buttons; a future usernameless passkey).
12935
+ * - `second-factor` — shown AFTER the password leg, gated on the
12936
+ * returned `factors` (passkey-as-2FA today).
12937
+ *
12938
+ * `mount: skip` — the cap is read server-side by the core auth router
12939
+ * (`registry.getCollection('login-method')`), never mounted as its own
12940
+ * tRPC router.
12941
+ */
12942
+ /** When a login method renders in the two-phase login flow. */
12943
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
12944
+ /** One login-method contribution — redirect button OR pre-auth widget. */
12945
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
12946
+ kind: literal("redirect"),
12947
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
12948
+ id: string(),
12949
+ /** Operator-facing button label. */
12950
+ label: string(),
12951
+ /** lucide-react icon name. */
12952
+ icon: string().optional(),
12953
+ /** Addon-owned HTTP route the button navigates to (GET). */
12954
+ startUrl: string(),
12955
+ stage: LoginStageEnum
12956
+ }), object({
12957
+ kind: literal("widget"),
12958
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
12959
+ id: string(),
12960
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
12961
+ addonId: string(),
12962
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
12963
+ bundle: string(),
12964
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
12965
+ remote: WidgetRemoteSchema,
12966
+ stage: LoginStageEnum
12967
+ })]);
12968
+ method(_void(), array(LoginMethodContributionSchema).readonly());
12969
+ /**
12795
12970
  * Orchestrator-side destination metadata. The orchestrator computes
12796
12971
  * `id = <addonId>:<subId>` from its provider lookup so consumers
12797
12972
  * (admin UI, restore flow) see one canonical key.
@@ -15080,11 +15255,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15080
15255
  timestamp: number()
15081
15256
  });
15082
15257
  var CameraPipelineConfigSchema = object({
15083
- engine: PipelineEngineChoiceSchema,
15258
+ engine: PipelineEngineChoiceSchema.optional(),
15084
15259
  steps: array(PipelineStepInputSchema).readonly(),
15085
15260
  audio: object({
15086
- engine: PipelineEngineChoiceSchema,
15087
- modelId: string(),
15261
+ engine: PipelineEngineChoiceSchema.optional(),
15262
+ modelId: string().optional(),
15088
15263
  enabled: boolean(),
15089
15264
  settings: record(string(), unknown()).readonly().optional()
15090
15265
  }).nullable().optional()
@@ -15099,7 +15274,7 @@ var PipelineTemplateSchema = object({
15099
15274
  });
15100
15275
  var AgentAddonConfigSchema = object({
15101
15276
  enabled: boolean(),
15102
- modelId: string(),
15277
+ modelId: string().optional(),
15103
15278
  settings: record(string(), unknown()).readonly()
15104
15279
  });
15105
15280
  var AgentPipelineSettingsSchema = object({
@@ -15109,12 +15284,25 @@ var AgentPipelineSettingsSchema = object({
15109
15284
  detectWeight: number().positive().optional(),
15110
15285
  /** Node is eligible to run the detection pipeline (decode + inference). */
15111
15286
  detect: boolean().optional(),
15112
- /** Node is eligible to host decoder sessions. */
15287
+ /**
15288
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15289
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15290
+ * the schema ONLY so persisted stores written before the removal still
15291
+ * parse — no code reads it and no write path emits it.
15292
+ */
15113
15293
  decode: boolean().optional(),
15114
15294
  /** Node is eligible to run audio-analyzer sessions. */
15115
15295
  audio: boolean().optional(),
15116
15296
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
15117
- ingest: boolean().optional()
15297
+ ingest: boolean().optional(),
15298
+ /**
15299
+ * Operator override for the LAN host a cross-node decoder dials to reach
15300
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
15301
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
15302
+ * it already uses to reach the hub). Set this only when the auto-detected
15303
+ * address is wrong (multi-homed host, NAT, custom interface).
15304
+ */
15305
+ reachableHost: string().optional()
15118
15306
  });
15119
15307
  var CameraPipelineForAgentSchema = object({
15120
15308
  steps: array(PipelineStepInputSchema).readonly(),
@@ -15162,25 +15350,6 @@ var PipelineAssignmentSchema = object({
15162
15350
  assignedAt: number()
15163
15351
  });
15164
15352
  /**
15165
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15166
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15167
- * → co-located with pipeline → capacity).
15168
- */
15169
- var DecoderAssignmentSchema = object({
15170
- deviceId: number(),
15171
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15172
- decoderNodeId: string(),
15173
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15174
- pinned: boolean(),
15175
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15176
- reason: _enum([
15177
- "manual",
15178
- "co-located",
15179
- "capacity",
15180
- "hardware-affinity"
15181
- ])
15182
- });
15183
- /**
15184
15353
  * Per-agent load summary surfaced to the load balancer + dashboards.
15185
15354
  * Aggregated from each runner's `getLocalLoad` cap call.
15186
15355
  */
@@ -15220,6 +15389,15 @@ var GlobalMetricsSchema = object({
15220
15389
  * capability providers.
15221
15390
  */
15222
15391
  var CapabilityBindingsSchema = record(string(), string());
15392
+ /**
15393
+ * The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
15394
+ * its LAN-reachable host, if one is registered. See `getIngestOwner`.
15395
+ */
15396
+ var IngestOwnerSchema = object({
15397
+ ownerNodeId: string(),
15398
+ reachableHost: string().optional(),
15399
+ configIssue: string().optional()
15400
+ });
15223
15401
  /** Source block — always present; derives from the stream catalog. */
15224
15402
  var CameraSourceStatusSchema = object({ streams: array(object({
15225
15403
  camStreamId: string(),
@@ -15234,6 +15412,14 @@ var CameraAssignmentStatusSchema = object({
15234
15412
  detectionNodeId: string().nullable(),
15235
15413
  decoderNodeId: string().nullable(),
15236
15414
  audioNodeId: string().nullable(),
15415
+ /**
15416
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
15417
+ * hosts the broker/restream) — the cluster ingest owner today
15418
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
15419
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
15420
+ * broker block below was read from (pinned). Nullable only pre-wiring.
15421
+ */
15422
+ sourceNodeId: string().nullable(),
15237
15423
  pinned: object({
15238
15424
  detection: boolean(),
15239
15425
  decoder: boolean(),
@@ -15366,16 +15552,7 @@ method(object({
15366
15552
  }), object({ success: literal(true) }), {
15367
15553
  kind: "mutation",
15368
15554
  auth: "admin"
15369
- }), method(object({
15370
- deviceId: number(),
15371
- nodeId: string()
15372
- }), _void(), {
15373
- kind: "mutation",
15374
- auth: "admin"
15375
- }), method(object({ deviceId: number() }), _void(), {
15376
- kind: "mutation",
15377
- auth: "admin"
15378
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15555
+ }), method(_void(), IngestOwnerSchema), method(object({
15379
15556
  deviceId: number(),
15380
15557
  nodeId: string()
15381
15558
  }), object({ success: literal(true) }), {
@@ -15396,10 +15573,7 @@ method(object({
15396
15573
  nodeId: string(),
15397
15574
  pinned: boolean(),
15398
15575
  assignedAt: number()
15399
- }))), method(object({
15400
- deviceId: number(),
15401
- pipelineNodeId: string().optional()
15402
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15576
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15403
15577
  nodeId: string(),
15404
15578
  settings: AgentPipelineSettingsSchema
15405
15579
  })).readonly()), method(object({
@@ -15429,12 +15603,26 @@ method(object({
15429
15603
  }), method(object({
15430
15604
  agentNodeId: string(),
15431
15605
  detect: boolean().nullable().optional(),
15432
- decode: boolean().nullable().optional(),
15433
15606
  audio: boolean().nullable().optional(),
15434
15607
  ingest: boolean().nullable().optional()
15435
15608
  }), object({ success: literal(true) }), {
15436
15609
  kind: "mutation",
15437
15610
  auth: "admin"
15611
+ }), method(object({
15612
+ agentNodeId: string(),
15613
+ reachableHost: string().nullable()
15614
+ }), object({ success: literal(true) }), {
15615
+ kind: "mutation",
15616
+ auth: "admin"
15617
+ }), method(object({ agentNodeId: string() }), object({
15618
+ success: literal(true),
15619
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
15620
+ effectiveModelId: string().nullable(),
15621
+ /** Number of cameras whose node-scoped overrides were cleared. */
15622
+ clearedCameraOverrides: number()
15623
+ }), {
15624
+ kind: "mutation",
15625
+ auth: "admin"
15438
15626
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15439
15627
  deviceId: number(),
15440
15628
  addonId: string(),
@@ -15479,22 +15667,131 @@ method(object({
15479
15667
  kind: "mutation",
15480
15668
  auth: "admin"
15481
15669
  });
15482
- var RegisteredStreamSchema = object({
15483
- streamId: string(),
15484
- label: string().optional(),
15485
- codec: string(),
15486
- type: _enum(["video", "audio"]),
15487
- sourceUrl: string()
15670
+ /**
15671
+ * server-management — per-NODE singleton capability for a node's ROOT
15672
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
15673
+ * agents).
15674
+ *
15675
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
15676
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
15677
+ * version describes the node. Updates install into
15678
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
15679
+ * starter (probation boot + auto-rollback to N-1).
15680
+ *
15681
+ * Providers:
15682
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
15683
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
15684
+ * unpinned calls.
15685
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
15686
+ * the synthetic `agent-runtime` addonId and declared in the agent's
15687
+ * `$hub.registerNode` manifest.
15688
+ *
15689
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
15690
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
15691
+ * SDK) routes the call to that node's provider via the standard remote
15692
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
15693
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
15694
+ *
15695
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
15696
+ */
15697
+ /**
15698
+ * Where the running hub's code was loaded from:
15699
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
15700
+ * plain resolution and runtime updates are refused.
15701
+ * - `baked` — the immutable image seed closure (no data-dir root active).
15702
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
15703
+ */
15704
+ var ServerBootModeSchema = _enum([
15705
+ "workspace",
15706
+ "baked",
15707
+ "data-root"
15708
+ ]);
15709
+ /**
15710
+ * Update lifecycle state:
15711
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
15712
+ * - `pending-restart` — a version is staged and the node has NOT yet
15713
+ * restarted onto it (still running the OLD version).
15714
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
15715
+ * (it is the active probation boot) and is waiting to confirm boot-health.
15716
+ * Apply/rollback are refused in this state and the node must NOT be
15717
+ * manually restarted, or the probation boot auto-rolls-back.
15718
+ */
15719
+ var ServerUpdateStateSchema = _enum([
15720
+ "idle",
15721
+ "checking",
15722
+ "staging",
15723
+ "pending-restart",
15724
+ "awaiting-confirmation"
15725
+ ]);
15726
+ var ServerRollbackInfoSchema = object({
15727
+ /** The version that failed (or was manually rolled back). */
15728
+ fromVersion: string(),
15729
+ /** The version rolled back to; null = the baked seed. */
15730
+ toVersion: string().nullable(),
15731
+ atMs: number(),
15732
+ reason: string()
15488
15733
  });
15489
- var ExposedResourceSchema = object({
15490
- streamId: string(),
15491
- format: string(),
15492
- value: string()
15734
+ var ServerPackageStatusSchema = object({
15735
+ /** Root package name (`@camstack/server` on the hub). */
15736
+ packageName: string(),
15737
+ /** Version of the code the running process ACTUALLY loaded. */
15738
+ runningVersion: string().nullable(),
15739
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
15740
+ nodeRuntimeVersion: string().nullable(),
15741
+ /** Active data-dir root version; null when booted from seed/workspace. */
15742
+ activeVersion: string().nullable(),
15743
+ /** N-1 version kept for rollback; null when no previous version exists. */
15744
+ previousVersion: string().nullable(),
15745
+ /** Version of the immutable baked seed closure (image fallback). */
15746
+ seedVersion: string().nullable(),
15747
+ /** Latest registry version from the most recent check (null = never checked). */
15748
+ latestVersion: string().nullable(),
15749
+ updateAvailable: boolean(),
15750
+ bootMode: ServerBootModeSchema,
15751
+ updateState: ServerUpdateStateSchema,
15752
+ /** Version staged + awaiting its probation boot, when one is pending. */
15753
+ pendingVersion: string().nullable(),
15754
+ /** Set when the last freshly-activated version failed its boot health-check. */
15755
+ rolledBack: ServerRollbackInfoSchema.nullable(),
15756
+ /**
15757
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
15758
+ * hub is running from the baked seed (or workspace) while installed data-dir
15759
+ * versions are being IGNORED. Surfaced as a warning in the UI.
15760
+ */
15761
+ stateFileCorrupt: boolean(),
15762
+ lastCheckedAtMs: number().nullable()
15763
+ });
15764
+ var ServerUpdateCheckResultSchema = object({
15765
+ packageName: string(),
15766
+ runningVersion: string().nullable(),
15767
+ latestVersion: string().nullable(),
15768
+ updateAvailable: boolean(),
15769
+ checkedAtMs: number(),
15770
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
15771
+ error: string().nullable()
15772
+ });
15773
+ var ServerUpdateActionResultSchema = object({
15774
+ accepted: boolean(),
15775
+ targetVersion: string().nullable(),
15776
+ /** True when a graceful restart was scheduled to apply the change. */
15777
+ restarting: boolean(),
15778
+ message: string()
15779
+ });
15780
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
15781
+ kind: "mutation",
15782
+ auth: "admin"
15783
+ }), method(object({
15784
+ /** Explicit target version; omitted = latest from the registry. */
15785
+ version: string().optional() }), ServerUpdateActionResultSchema, {
15786
+ kind: "mutation",
15787
+ auth: "admin"
15788
+ }), method(_void(), ServerUpdateActionResultSchema, {
15789
+ kind: "mutation",
15790
+ auth: "admin"
15791
+ }), method(_void(), ServerUpdateActionResultSchema, {
15792
+ kind: "mutation",
15793
+ auth: "admin"
15493
15794
  });
15494
- method(object({
15495
- deviceId: number(),
15496
- streams: array(RegisteredStreamSchema).readonly()
15497
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
15498
15795
  /**
15499
15796
  * Query filter for settings-store collections.
15500
15797
  */
@@ -15647,9 +15944,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
15647
15944
  /**
15648
15945
  * A single device snapshot returned as base64 JPEG/PNG.
15649
15946
  *
15650
- * Shared with the `snapshot-provider` collection cap the orchestrator
15651
- * receives the same shape from each native provider and from the
15652
- * broker-based fallback.
15947
+ * The `SnapshotAddon` wrapper returns this shape whether the frame came from
15948
+ * the device-native provider (onboard capture) or from the stream-broker
15949
+ * prebuffer fallback.
15653
15950
  */
15654
15951
  var SnapshotImageSchema = object({
15655
15952
  base64: string(),
@@ -15681,10 +15978,6 @@ DeviceType.Camera, method(object({
15681
15978
  kind: "mutation",
15682
15979
  auth: "admin"
15683
15980
  });
15684
- method(object({ deviceId: number() }), boolean()), method(object({
15685
- deviceId: number(),
15686
- streamId: string().optional()
15687
- }), SnapshotImageSchema.nullable());
15688
15981
  /**
15689
15982
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
15690
15983
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16090,9 +16383,10 @@ method(object({
16090
16383
  auth: "admin"
16091
16384
  });
16092
16385
  /**
16093
- * Optional client-side hints sent at session creation to help the
16094
- * provider pick the best native source. All fields are optional —
16095
- * a viewer that knows nothing still gets a sane default.
16386
+ * Optional client-side hints sent at session creation to help the provider
16387
+ * pick the best native source. All fields optional — a viewer that knows
16388
+ * nothing still gets a sane default. (Relocated from the retired `webrtc`
16389
+ * collection cap; this `webrtc-session` cap is the live signaling surface.)
16096
16390
  */
16097
16391
  var webrtcClientHintsSchema = object({
16098
16392
  viewportWidth: number().int().positive().optional(),
@@ -16103,22 +16397,6 @@ var webrtcClientHintsSchema = object({
16103
16397
  /** Hard tier override; takes precedence over scoring when registered. */
16104
16398
  prefersTier: string().optional()
16105
16399
  }).partial();
16106
- method(object({
16107
- streamId: string(),
16108
- sdpOffer: string()
16109
- }), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
16110
- streamId: string(),
16111
- codec: string()
16112
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
16113
- streamId: string(),
16114
- hints: webrtcClientHintsSchema.optional()
16115
- }), object({
16116
- sessionId: string(),
16117
- sdpOffer: string()
16118
- }), { kind: "mutation" }), method(object({
16119
- sessionId: string(),
16120
- sdpAnswer: string()
16121
- }), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
16122
16400
  /**
16123
16401
  * Discriminated target for a WebRTC session. The client sends this
16124
16402
  * structured object instead of building / parsing brokerId strings;
@@ -17546,6 +17824,16 @@ var TopologyCategorySchema = object({
17546
17824
  healthy: number(),
17547
17825
  addons: array(TopologyCategoryAddonSchema).readonly()
17548
17826
  });
17827
+ /**
17828
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
17829
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
17830
+ * version visibility for the Server management surface. Nullable: offline
17831
+ * rows and pre-phase-2 nodes report none.
17832
+ */
17833
+ var TopologyRootPackageSchema = object({
17834
+ name: string(),
17835
+ version: string()
17836
+ });
17549
17837
  var TopologyNodeSchema = object({
17550
17838
  id: string(),
17551
17839
  name: string(),
@@ -17569,7 +17857,8 @@ var TopologyNodeSchema = object({
17569
17857
  status: string()
17570
17858
  })).readonly(),
17571
17859
  processes: array(TopologyProcessSchema).readonly(),
17572
- categories: array(TopologyCategorySchema).readonly()
17860
+ categories: array(TopologyCategorySchema).readonly(),
17861
+ rootPackage: TopologyRootPackageSchema.nullable()
17573
17862
  });
17574
17863
  var CapUsageEdgeSchema = object({
17575
17864
  callerAddonId: string(),
@@ -20369,6 +20658,12 @@ Object.freeze({
20369
20658
  addonId: null,
20370
20659
  access: "create"
20371
20660
  },
20661
+ "loginMethod.getLoginMethods": {
20662
+ capName: "login-method",
20663
+ capScope: "system",
20664
+ addonId: null,
20665
+ access: "view"
20666
+ },
20372
20667
  "mediaPlayer.next": {
20373
20668
  capName: "media-player",
20374
20669
  capScope: "device",
@@ -20999,23 +21294,23 @@ Object.freeze({
20999
21294
  addonId: null,
21000
21295
  access: "create"
21001
21296
  },
21002
- "pipelineExecutor.deleteModel": {
21297
+ "pipelineExecutor.clearDeviceOverrides": {
21003
21298
  capName: "pipeline-executor",
21004
21299
  capScope: "system",
21005
21300
  addonId: null,
21006
21301
  access: "delete"
21007
21302
  },
21008
- "pipelineExecutor.deleteTemplate": {
21303
+ "pipelineExecutor.deleteModel": {
21009
21304
  capName: "pipeline-executor",
21010
21305
  capScope: "system",
21011
21306
  addonId: null,
21012
21307
  access: "delete"
21013
21308
  },
21014
- "pipelineExecutor.detect": {
21309
+ "pipelineExecutor.deleteTemplate": {
21015
21310
  capName: "pipeline-executor",
21016
21311
  capScope: "system",
21017
21312
  addonId: null,
21018
- access: "view"
21313
+ access: "delete"
21019
21314
  },
21020
21315
  "pipelineExecutor.downloadModel": {
21021
21316
  capName: "pipeline-executor",
@@ -21209,13 +21504,13 @@ Object.freeze({
21209
21504
  addonId: null,
21210
21505
  access: "create"
21211
21506
  },
21212
- "pipelineOrchestrator.assignAudio": {
21213
- capName: "pipeline-orchestrator",
21507
+ "pipelineExecutor.validatePipeline": {
21508
+ capName: "pipeline-executor",
21214
21509
  capScope: "system",
21215
21510
  addonId: null,
21216
- access: "create"
21511
+ access: "view"
21217
21512
  },
21218
- "pipelineOrchestrator.assignDecoder": {
21513
+ "pipelineOrchestrator.assignAudio": {
21219
21514
  capName: "pipeline-orchestrator",
21220
21515
  capScope: "system",
21221
21516
  addonId: null,
@@ -21299,19 +21594,13 @@ Object.freeze({
21299
21594
  addonId: null,
21300
21595
  access: "view"
21301
21596
  },
21302
- "pipelineOrchestrator.getDecoderAssignment": {
21597
+ "pipelineOrchestrator.getGlobalMetrics": {
21303
21598
  capName: "pipeline-orchestrator",
21304
21599
  capScope: "system",
21305
21600
  addonId: null,
21306
21601
  access: "view"
21307
21602
  },
21308
- "pipelineOrchestrator.getDecoderAssignments": {
21309
- capName: "pipeline-orchestrator",
21310
- capScope: "system",
21311
- addonId: null,
21312
- access: "view"
21313
- },
21314
- "pipelineOrchestrator.getGlobalMetrics": {
21603
+ "pipelineOrchestrator.getIngestOwner": {
21315
21604
  capName: "pipeline-orchestrator",
21316
21605
  capScope: "system",
21317
21606
  addonId: null,
@@ -21353,6 +21642,12 @@ Object.freeze({
21353
21642
  addonId: null,
21354
21643
  access: "delete"
21355
21644
  },
21645
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
21646
+ capName: "pipeline-orchestrator",
21647
+ capScope: "system",
21648
+ addonId: null,
21649
+ access: "delete"
21650
+ },
21356
21651
  "pipelineOrchestrator.resolvePipeline": {
21357
21652
  capName: "pipeline-orchestrator",
21358
21653
  capScope: "system",
@@ -21389,37 +21684,37 @@ Object.freeze({
21389
21684
  addonId: null,
21390
21685
  access: "create"
21391
21686
  },
21392
- "pipelineOrchestrator.setCameraPipelineForAgent": {
21687
+ "pipelineOrchestrator.setAgentReachableHost": {
21393
21688
  capName: "pipeline-orchestrator",
21394
21689
  capScope: "system",
21395
21690
  addonId: null,
21396
21691
  access: "create"
21397
21692
  },
21398
- "pipelineOrchestrator.setCameraStepOverride": {
21693
+ "pipelineOrchestrator.setCameraPipelineForAgent": {
21399
21694
  capName: "pipeline-orchestrator",
21400
21695
  capScope: "system",
21401
21696
  addonId: null,
21402
21697
  access: "create"
21403
21698
  },
21404
- "pipelineOrchestrator.setCameraStepToggle": {
21699
+ "pipelineOrchestrator.setCameraStepOverride": {
21405
21700
  capName: "pipeline-orchestrator",
21406
21701
  capScope: "system",
21407
21702
  addonId: null,
21408
21703
  access: "create"
21409
21704
  },
21410
- "pipelineOrchestrator.setCapabilityBinding": {
21705
+ "pipelineOrchestrator.setCameraStepToggle": {
21411
21706
  capName: "pipeline-orchestrator",
21412
21707
  capScope: "system",
21413
21708
  addonId: null,
21414
21709
  access: "create"
21415
21710
  },
21416
- "pipelineOrchestrator.unassignAudio": {
21711
+ "pipelineOrchestrator.setCapabilityBinding": {
21417
21712
  capName: "pipeline-orchestrator",
21418
21713
  capScope: "system",
21419
21714
  addonId: null,
21420
21715
  access: "create"
21421
21716
  },
21422
- "pipelineOrchestrator.unassignDecoder": {
21717
+ "pipelineOrchestrator.unassignAudio": {
21423
21718
  capName: "pipeline-orchestrator",
21424
21719
  capScope: "system",
21425
21720
  addonId: null,
@@ -21719,33 +22014,45 @@ Object.freeze({
21719
22014
  addonId: null,
21720
22015
  access: "create"
21721
22016
  },
21722
- "restreamer.getExposedResources": {
21723
- capName: "restreamer",
22017
+ "scriptRunner.run": {
22018
+ capName: "script-runner",
22019
+ capScope: "device",
22020
+ addonId: null,
22021
+ access: "create"
22022
+ },
22023
+ "scriptRunner.stop": {
22024
+ capName: "script-runner",
22025
+ capScope: "device",
22026
+ addonId: null,
22027
+ access: "create"
22028
+ },
22029
+ "serverManagement.applyServerUpdate": {
22030
+ capName: "server-management",
21724
22031
  capScope: "system",
21725
22032
  addonId: null,
21726
- access: "view"
22033
+ access: "create"
21727
22034
  },
21728
- "restreamer.registerDevice": {
21729
- capName: "restreamer",
22035
+ "serverManagement.checkServerUpdate": {
22036
+ capName: "server-management",
21730
22037
  capScope: "system",
21731
22038
  addonId: null,
21732
22039
  access: "create"
21733
22040
  },
21734
- "restreamer.unregisterDevice": {
21735
- capName: "restreamer",
22041
+ "serverManagement.getServerPackageStatus": {
22042
+ capName: "server-management",
21736
22043
  capScope: "system",
21737
22044
  addonId: null,
21738
- access: "delete"
22045
+ access: "view"
21739
22046
  },
21740
- "scriptRunner.run": {
21741
- capName: "script-runner",
21742
- capScope: "device",
22047
+ "serverManagement.restartServer": {
22048
+ capName: "server-management",
22049
+ capScope: "system",
21743
22050
  addonId: null,
21744
22051
  access: "create"
21745
22052
  },
21746
- "scriptRunner.stop": {
21747
- capName: "script-runner",
21748
- capScope: "device",
22053
+ "serverManagement.rollbackServerUpdate": {
22054
+ capName: "server-management",
22055
+ capScope: "system",
21749
22056
  addonId: null,
21750
22057
  access: "create"
21751
22058
  },
@@ -21839,18 +22146,6 @@ Object.freeze({
21839
22146
  addonId: null,
21840
22147
  access: "create"
21841
22148
  },
21842
- "snapshotProvider.getSnapshot": {
21843
- capName: "snapshot-provider",
21844
- capScope: "system",
21845
- addonId: null,
21846
- access: "view"
21847
- },
21848
- "snapshotProvider.supportsDevice": {
21849
- capName: "snapshot-provider",
21850
- capScope: "system",
21851
- addonId: null,
21852
- access: "view"
21853
- },
21854
22149
  "ssoBridge.signBridgeToken": {
21855
22150
  capName: "sso-bridge",
21856
22151
  capScope: "system",
@@ -22277,30 +22572,6 @@ Object.freeze({
22277
22572
  addonId: null,
22278
22573
  access: "view"
22279
22574
  },
22280
- "streamingEngine.getStreamUrl": {
22281
- capName: "streaming-engine",
22282
- capScope: "system",
22283
- addonId: null,
22284
- access: "view"
22285
- },
22286
- "streamingEngine.listStreams": {
22287
- capName: "streaming-engine",
22288
- capScope: "system",
22289
- addonId: null,
22290
- access: "view"
22291
- },
22292
- "streamingEngine.registerStream": {
22293
- capName: "streaming-engine",
22294
- capScope: "system",
22295
- addonId: null,
22296
- access: "create"
22297
- },
22298
- "streamingEngine.unregisterStream": {
22299
- capName: "streaming-engine",
22300
- capScope: "system",
22301
- addonId: null,
22302
- access: "delete"
22303
- },
22304
22575
  "streamParams.getConfigSchema": {
22305
22576
  capName: "stream-params",
22306
22577
  capScope: "device",
@@ -22649,6 +22920,18 @@ Object.freeze({
22649
22920
  addonId: null,
22650
22921
  access: "view"
22651
22922
  },
22923
+ "viewerUi.getStaticDir": {
22924
+ capName: "viewer-ui",
22925
+ capScope: "system",
22926
+ addonId: null,
22927
+ access: "view"
22928
+ },
22929
+ "viewerUi.getVersion": {
22930
+ capName: "viewer-ui",
22931
+ capScope: "system",
22932
+ addonId: null,
22933
+ access: "view"
22934
+ },
22652
22935
  "waterHeater.setAway": {
22653
22936
  capName: "water-heater",
22654
22937
  capScope: "device",
@@ -22667,54 +22950,6 @@ Object.freeze({
22667
22950
  addonId: null,
22668
22951
  access: "create"
22669
22952
  },
22670
- "webrtc.closeSession": {
22671
- capName: "webrtc",
22672
- capScope: "system",
22673
- addonId: null,
22674
- access: "create"
22675
- },
22676
- "webrtc.createSession": {
22677
- capName: "webrtc",
22678
- capScope: "system",
22679
- addonId: null,
22680
- access: "create"
22681
- },
22682
- "webrtc.handleAnswer": {
22683
- capName: "webrtc",
22684
- capScope: "system",
22685
- addonId: null,
22686
- access: "create"
22687
- },
22688
- "webrtc.handleOffer": {
22689
- capName: "webrtc",
22690
- capScope: "system",
22691
- addonId: null,
22692
- access: "create"
22693
- },
22694
- "webrtc.hasAdaptiveBitrate": {
22695
- capName: "webrtc",
22696
- capScope: "system",
22697
- addonId: null,
22698
- access: "view"
22699
- },
22700
- "webrtc.registerStream": {
22701
- capName: "webrtc",
22702
- capScope: "system",
22703
- addonId: null,
22704
- access: "create"
22705
- },
22706
- "webrtc.supportsStream": {
22707
- capName: "webrtc",
22708
- capScope: "system",
22709
- addonId: null,
22710
- access: "view"
22711
- },
22712
- "webrtc.unregisterStream": {
22713
- capName: "webrtc",
22714
- capScope: "system",
22715
- addonId: null,
22716
- access: "delete"
22717
- },
22718
22953
  "webrtcSession.addIceCandidate": {
22719
22954
  capName: "webrtc-session",
22720
22955
  capScope: "device",