@camstack/addon-export-hap 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.
@@ -4639,7 +4639,7 @@ function _instanceof(cls, params = {}) {
4639
4639
  return inst;
4640
4640
  }
4641
4641
  //#endregion
4642
- //#region ../types/dist/sleep-CZDdRBua.mjs
4642
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4643
4643
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4644
4644
  EventCategory["SystemBoot"] = "system.boot";
4645
4645
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -4825,6 +4825,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4825
4825
  */
4826
4826
  EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
4827
4827
  /**
4828
+ * The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
4829
+ * Emitted by addon-pipeline-orchestrator whenever it (re)derives node
4830
+ * capabilities — at boot, on agent online/offline, and on an ingest-node
4831
+ * flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
4832
+ * keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
4833
+ * cross-process `getIngestOwner` query (push the authority's decision instead
4834
+ * of polling it on the hot path). Idempotent state — re-emitted on every
4835
+ * topology change, so a dropped event self-heals on the next one (plus the
4836
+ * broker's long backstop reconcile query).
4837
+ */
4838
+ EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
4839
+ /**
4828
4840
  * Periodic snapshot of per-node pipeline-runner load
4829
4841
  * (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
4830
4842
  * subscribe instead of polling `pipelineRunner.getLocalLoad`.
@@ -5348,10 +5360,6 @@ function hydrateField(field, values) {
5348
5360
  };
5349
5361
  }
5350
5362
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5351
- if (field.type === "password") return {
5352
- ...field,
5353
- value: ""
5354
- };
5355
5363
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5356
5364
  return {
5357
5365
  ...field,
@@ -6735,6 +6743,9 @@ function method(input, output, options) {
6735
6743
  timeoutMs: options?.timeoutMs
6736
6744
  };
6737
6745
  }
6746
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6747
+ var VersionOutputSchema$1 = object({ version: string() });
6748
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6738
6749
  var StaticDirOutputSchema = object({ staticDir: string() });
6739
6750
  var VersionOutputSchema = object({ version: string() });
6740
6751
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -6904,6 +6915,36 @@ var ModelFormatsSchema = object({
6904
6915
  tflite: ModelFormatEntrySchema.optional(),
6905
6916
  pt: ModelFormatEntrySchema.optional()
6906
6917
  });
6918
+ /**
6919
+ * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
6920
+ * the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
6921
+ * grouped Family→Tier→Variant picker renders identically in the config UI and
6922
+ * in the pipeline/device steppers. The flat `id` stays the source of truth for
6923
+ * resolution/download/persistence; this is a presentation overlay resolved back
6924
+ * to an `id`.
6925
+ */
6926
+ var ModelVariantGroupSchema = object({
6927
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
6928
+ family: string(),
6929
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
6930
+ tier: string(),
6931
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
6932
+ precision: _enum(["fp32", "int8"]).optional(),
6933
+ /**
6934
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
6935
+ * latency-optimized export (e.g. ReLU-activation variant) — the slot the
6936
+ * future performance variants plug into.
6937
+ */
6938
+ optimization: _enum(["standard", "fast"]).optional(),
6939
+ /**
6940
+ * Input-resolution axis (square input side, px). Omit ⇒ the family's native
6941
+ * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
6942
+ * cheap latency lever — especially on Apple ANE and the Intel N100 — at a
6943
+ * small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
6944
+ * the group so the selector can offer it as a variant axis.
6945
+ */
6946
+ resolution: number().int().positive().optional()
6947
+ });
6907
6948
  var ModelCatalogEntrySchema = object({
6908
6949
  id: string(),
6909
6950
  name: string(),
@@ -6933,7 +6974,43 @@ var ModelCatalogEntrySchema = object({
6933
6974
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6934
6975
  * Downloaded into the same modelsDir alongside the model file.
6935
6976
  */
6936
- extraFiles: array(ModelExtraFileSchema).readonly().optional()
6977
+ extraFiles: array(ModelExtraFileSchema).readonly().optional(),
6978
+ /**
6979
+ * LEGACY entry — retained in the catalog so a persisted operator selection
6980
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
6981
+ * model list and excluded from the auto format-default pick. Set on the
6982
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
6983
+ * the active lineup stays the coherent curated ladder without deleting a
6984
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
6985
+ * an explicit legacy id that has a build for the node's format.
6986
+ */
6987
+ legacy: boolean().optional(),
6988
+ /**
6989
+ * Measured quality/latency metadata — populated from the benchmark addon on
6990
+ * the real node classes. Absent = not yet measured (most entries today; the
6991
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
6992
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
6993
+ */
6994
+ metrics: object({
6995
+ map50: number().optional(),
6996
+ p95LatencyMs: record(string(), number()).optional()
6997
+ }).optional(),
6998
+ /**
6999
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
7000
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
7001
+ * the retraining addon and any future commercial distribution.
7002
+ */
7003
+ license: string().optional(),
7004
+ /**
7005
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
7006
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
7007
+ * of a family's sizes and quantizations collapse into one grouped picker
7008
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
7009
+ * (legacy / custom models) — never shown in the grouped selector. The flat
7010
+ * `id` stays the source of truth for resolution/download/persistence; grouping
7011
+ * is a presentation overlay resolved back to an `id`.
7012
+ */
7013
+ group: ModelVariantGroupSchema.optional()
6937
7014
  });
6938
7015
  var ConvertTargetSchema = discriminatedUnion("format", [object({
6939
7016
  format: literal("openvino"),
@@ -6994,8 +7071,8 @@ var RecordingModeSchema = _enum([
6994
7071
  "onAudioThreshold"
6995
7072
  ]);
6996
7073
  /**
6997
- * First-class, authoritative per-camera storage mode — the netta choice the UI
6998
- * reads directly (never inferred from `rules`):
7074
+ * First-class, authoritative per-camera storage mode — the explicit choice the
7075
+ * UI reads directly (never inferred from `rules`):
6999
7076
  * - `off` — not recording.
7000
7077
  * - `events` — record only around triggers (motion / audio threshold),
7001
7078
  * with pre/post-buffer.
@@ -8697,26 +8774,13 @@ DeviceType.Light, method(object({
8697
8774
  percentage: number().min(0).max(100),
8698
8775
  lastChangedAt: number()
8699
8776
  });
8777
+ /** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
8700
8778
  var StreamFormatSchema = _enum([
8701
8779
  "webrtc",
8702
8780
  "hls",
8703
8781
  "mjpeg",
8704
8782
  "rtsp"
8705
8783
  ]);
8706
- var StreamInfoSchema = object({
8707
- streamId: string(),
8708
- format: StreamFormatSchema,
8709
- url: string().nullable(),
8710
- active: boolean()
8711
- });
8712
- method(object({
8713
- streamId: string(),
8714
- sourceUrl: string(),
8715
- codec: string().optional()
8716
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
8717
- streamId: string(),
8718
- format: StreamFormatSchema
8719
- }), string().nullable()), method(_void(), array(StreamInfoSchema));
8720
8784
  var RtspRestreamEntrySchema = object({
8721
8785
  brokerId: string(),
8722
8786
  url: string(),
@@ -9381,7 +9445,7 @@ var ConsumablesStatusSchema = object({
9381
9445
  })),
9382
9446
  lastChangedAt: number()
9383
9447
  });
9384
- 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({
9448
+ Object.values(DeviceType), method(object({
9385
9449
  deviceId: number().int().nonnegative(),
9386
9450
  key: string().min(1)
9387
9451
  }), _void(), {
@@ -10296,7 +10360,7 @@ var BoundingBoxSchema = object({
10296
10360
  w: number(),
10297
10361
  h: number()
10298
10362
  });
10299
- var SpatialDetectionSchema = object({
10363
+ object({
10300
10364
  class: string(),
10301
10365
  originalClass: string(),
10302
10366
  score: number(),
@@ -10431,7 +10495,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
10431
10495
  enabled: boolean(),
10432
10496
  modelId: string(),
10433
10497
  children: array(PipelineDefaultStepSchema).readonly(),
10434
- engine: PipelineEngineChoiceSchema.optional(),
10435
10498
  group: string().optional(),
10436
10499
  settings: record(string(), unknown()).optional()
10437
10500
  }));
@@ -10456,7 +10519,9 @@ var PipelineModelOptionSchema = object({
10456
10519
  formats: record(string(), object({
10457
10520
  downloaded: boolean(),
10458
10521
  sizeMB: number()
10459
- }))
10522
+ })),
10523
+ group: ModelVariantGroupSchema.optional(),
10524
+ legacy: boolean().optional()
10460
10525
  });
10461
10526
  var ConfigFieldBridge = custom();
10462
10527
  var PipelineAddonSchemaSchema = object({
@@ -10486,11 +10551,6 @@ var PipelineSchemaSchema = object({
10486
10551
  selectedEngine: PipelineEngineChoiceSchema,
10487
10552
  slots: array(PipelineSlotSchemaSchema).readonly()
10488
10553
  });
10489
- var DetectorOutputSchema = object({
10490
- detections: array(SpatialDetectionSchema).readonly(),
10491
- inferenceMs: number(),
10492
- modelId: string()
10493
- });
10494
10554
  var EngineProvisioningSchema = object({
10495
10555
  runtimeId: _enum([
10496
10556
  "onnx",
@@ -10507,15 +10567,42 @@ var EngineProvisioningSchema = object({
10507
10567
  ]),
10508
10568
  progress: number().optional(),
10509
10569
  error: string().optional(),
10510
- nextRetryAt: number().optional()
10570
+ nextRetryAt: number().optional(),
10571
+ /**
10572
+ * Gate A (config-correctness gate at engine change): human-readable
10573
+ * config issues surfaced EAGERLY when the node's engine changes — model
10574
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
10575
+ * has a <format> build"). Additive/optional: informational only, never
10576
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
10577
+ * Absent/empty when the node-default tree resolves cleanly.
10578
+ */
10579
+ configIssues: array(string()).optional()
10511
10580
  });
10512
10581
  var PipelineStepInputSchema = lazy(() => object({
10513
10582
  addonId: string(),
10514
- modelId: string(),
10583
+ modelId: string().optional(),
10515
10584
  enabled: boolean().default(true),
10516
10585
  children: array(PipelineStepInputSchema).optional(),
10517
10586
  settings: record(string(), unknown()).optional()
10518
10587
  }));
10588
+ var ModelSubstitutionSchema = object({
10589
+ addonId: string(),
10590
+ chosen: string(),
10591
+ running: string(),
10592
+ format: string()
10593
+ });
10594
+ var PipelineValidationIssueSchema = object({
10595
+ addonId: string(),
10596
+ kind: _enum(["unknown-addon", "no-format-build"]),
10597
+ detail: string()
10598
+ });
10599
+ var PipelineValidationResultSchema = object({
10600
+ ok: boolean(),
10601
+ issues: array(PipelineValidationIssueSchema).readonly(),
10602
+ substitutions: array(ModelSubstitutionSchema).readonly(),
10603
+ /** The node's `currentEngine.format` this validation ran against. */
10604
+ format: string()
10605
+ });
10519
10606
  var ReferenceImageEntrySchema = object({
10520
10607
  filename: string(),
10521
10608
  stepIds: array(string()).readonly().optional()
@@ -10586,7 +10673,13 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10586
10673
  })) }), object({ success: literal(true) }), {
10587
10674
  kind: "mutation",
10588
10675
  auth: "admin"
10589
- }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10676
+ }), method(object({ nodeId: string() }), object({
10677
+ success: literal(true),
10678
+ clearedDevices: number()
10679
+ }), {
10680
+ kind: "mutation",
10681
+ auth: "admin"
10682
+ }), 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({
10590
10683
  name: string(),
10591
10684
  steps: array(PipelineTemplateStepSchema).readonly(),
10592
10685
  engine: PipelineEngineChoiceSchema
@@ -10603,10 +10696,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10603
10696
  modelId: string(),
10604
10697
  format: ModelFormatSchema$1
10605
10698
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10606
- addonId: string(),
10607
- frame: FrameInputSchema,
10608
- config: record(string(), unknown()).optional()
10609
- }), DetectorOutputSchema), method(object({
10610
10699
  engine: PipelineEngineChoiceSchema.optional(),
10611
10700
  steps: array(PipelineStepInputSchema).min(1),
10612
10701
  frame: FrameInputSchema.optional(),
@@ -10846,6 +10935,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10846
10935
  kind: literal("remote-restream"),
10847
10936
  /** The camera's source-owner node (slice 1: always the hub). */
10848
10937
  ownerNodeId: string(),
10938
+ /**
10939
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
10940
+ * per-node `reachableHost` override (Cluster UI). When present the runner
10941
+ * dials THIS host for the owner's restream, in preference to the
10942
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
10943
+ */
10944
+ ownerReachableHost: string().optional(),
10849
10945
  /** Operator override for the owner host the runner dials. */
10850
10946
  hubHostnameOverride: string().optional()
10851
10947
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -10854,13 +10950,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10854
10950
  * specific runner instance via `attachCamera`. Carries everything the
10855
10951
  * runner needs to subscribe to the local broker and execute inference.
10856
10952
  *
10857
- * Stateless-pipeline model: the full pipeline content (`engine`, `steps`,
10858
- * optional `audio`) travels with the attach payload. The runner keeps it
10859
- * in RAM for the lifetime of the attach — on rebalance, edit, or
10860
- * restart the orchestrator re-sends the latest snapshot.
10861
- *
10862
- * `engine`/`steps`/`audio` are optional during the additive migration
10863
- * window; once orchestrator + UI are migrated they become required.
10953
+ * Stateless-pipeline model: the pipeline content (`steps`, optional
10954
+ * `audio`) travels with the attach payload. The runner keeps it in RAM
10955
+ * for the lifetime of the attach — on rebalance, edit, or restart the
10956
+ * orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
10957
+ * node-local, resolved by the executing runner at dispatch time.
10864
10958
  */
10865
10959
  var RunnerCameraConfigSchema = object({
10866
10960
  deviceId: number(),
@@ -10911,14 +11005,11 @@ var RunnerCameraConfigSchema = object({
10911
11005
  */
10912
11006
  motionSources: MotionSourcesSchema.default(["analyzer"]),
10913
11007
  pipelineEnabled: boolean().default(true),
10914
- /** Engine choice for video steps (runtime+backend+format). */
10915
- engine: PipelineEngineChoiceSchema.optional(),
10916
11008
  /** Ordered tree of video steps. Absent → runner skips video detection. */
10917
11009
  steps: array(PipelineStepInputSchema).readonly().optional(),
10918
11010
  /** Audio classification branch. `enabled:false` disables, null skips. */
10919
11011
  audio: object({
10920
- engine: PipelineEngineChoiceSchema,
10921
- modelId: string(),
11012
+ modelId: string().optional(),
10922
11013
  enabled: boolean()
10923
11014
  }).nullable().optional(),
10924
11015
  /**
@@ -12299,7 +12390,9 @@ var AddonPageDeclarationSchema$1 = object({
12299
12390
  icon: string(),
12300
12391
  path: string(),
12301
12392
  remoteName: string(),
12302
- bundle: string()
12393
+ bundle: string(),
12394
+ section: string().optional(),
12395
+ sectionLabel: string().optional()
12303
12396
  });
12304
12397
  var AddonPageInfoSchema = object({
12305
12398
  addonId: string(),
@@ -12339,7 +12432,18 @@ var AddonPageDeclarationSchema = object({
12339
12432
  * the static-file route can compute an mtime-based cache-buster URL
12340
12433
  * without a separate filesystem stat.
12341
12434
  */
12342
- bundle: string()
12435
+ bundle: string(),
12436
+ /**
12437
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12438
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12439
+ * Any OTHER string creates (or joins) a custom section rendered after
12440
+ * the built-in groups; its label comes from `sectionLabel` (first
12441
+ * declaration wins), falling back to the id. Absent → the legacy
12442
+ * "Addon Pages" group.
12443
+ */
12444
+ section: string().optional(),
12445
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12446
+ sectionLabel: string().optional()
12343
12447
  });
12344
12448
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12345
12449
  var AddonHttpRouteSchema = object({
@@ -12555,6 +12659,17 @@ var WidgetMetadataSchema = object({
12555
12659
  deviceContext: boolean().default(false),
12556
12660
  integrationContext: boolean().default(false)
12557
12661
  }),
12662
+ /**
12663
+ * Loadable BEFORE authentication. The normal widget registry listing
12664
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
12665
+ * (the login page) cannot discover a widget through it. A widget that
12666
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
12667
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
12668
+ * login-method contribution channel (see `login-method.cap.ts`) rather
12669
+ * than the authenticated registry, and its bundle is served by the
12670
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
12671
+ */
12672
+ preAuth: boolean().optional().default(false),
12558
12673
  /** Dashboard placement HINTS (operator can override per instance). */
12559
12674
  defaultSize: WidgetSizeEnum.default("md"),
12560
12675
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -12856,6 +12971,66 @@ method(object({
12856
12971
  password: string()
12857
12972
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
12858
12973
  /**
12974
+ * `login-method` — collection cap through which auth addons contribute
12975
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
12976
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
12977
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
12978
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
12979
+ * procedure aggregates them for the unauthenticated login page.
12980
+ *
12981
+ * A contribution is a discriminated union on `kind`:
12982
+ *
12983
+ * - `redirect` — a declarative button. The login page renders a generic
12984
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
12985
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
12986
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
12987
+ * login page needs NO change.
12988
+ *
12989
+ * - `widget` — a Module-Federation widget the login page mounts (via
12990
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
12991
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
12992
+ * addon bundle. The referenced widget also declares `preAuth: true` in
12993
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
12994
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
12995
+ *
12996
+ * Every contribution carries a `stage`:
12997
+ * - `primary` — shown on the first credentials screen (OIDC /
12998
+ * magic-link buttons; a future usernameless passkey).
12999
+ * - `second-factor` — shown AFTER the password leg, gated on the
13000
+ * returned `factors` (passkey-as-2FA today).
13001
+ *
13002
+ * `mount: skip` — the cap is read server-side by the core auth router
13003
+ * (`registry.getCollection('login-method')`), never mounted as its own
13004
+ * tRPC router.
13005
+ */
13006
+ /** When a login method renders in the two-phase login flow. */
13007
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
13008
+ /** One login-method contribution — redirect button OR pre-auth widget. */
13009
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
13010
+ kind: literal("redirect"),
13011
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
13012
+ id: string(),
13013
+ /** Operator-facing button label. */
13014
+ label: string(),
13015
+ /** lucide-react icon name. */
13016
+ icon: string().optional(),
13017
+ /** Addon-owned HTTP route the button navigates to (GET). */
13018
+ startUrl: string(),
13019
+ stage: LoginStageEnum
13020
+ }), object({
13021
+ kind: literal("widget"),
13022
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
13023
+ id: string(),
13024
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
13025
+ addonId: string(),
13026
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
13027
+ bundle: string(),
13028
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
13029
+ remote: WidgetRemoteSchema,
13030
+ stage: LoginStageEnum
13031
+ })]);
13032
+ method(_void(), array(LoginMethodContributionSchema).readonly());
13033
+ /**
12859
13034
  * Orchestrator-side destination metadata. The orchestrator computes
12860
13035
  * `id = <addonId>:<subId>` from its provider lookup so consumers
12861
13036
  * (admin UI, restore flow) see one canonical key.
@@ -15169,11 +15344,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15169
15344
  timestamp: number()
15170
15345
  });
15171
15346
  var CameraPipelineConfigSchema = object({
15172
- engine: PipelineEngineChoiceSchema,
15347
+ engine: PipelineEngineChoiceSchema.optional(),
15173
15348
  steps: array(PipelineStepInputSchema).readonly(),
15174
15349
  audio: object({
15175
- engine: PipelineEngineChoiceSchema,
15176
- modelId: string(),
15350
+ engine: PipelineEngineChoiceSchema.optional(),
15351
+ modelId: string().optional(),
15177
15352
  enabled: boolean(),
15178
15353
  settings: record(string(), unknown()).readonly().optional()
15179
15354
  }).nullable().optional()
@@ -15188,7 +15363,7 @@ var PipelineTemplateSchema = object({
15188
15363
  });
15189
15364
  var AgentAddonConfigSchema = object({
15190
15365
  enabled: boolean(),
15191
- modelId: string(),
15366
+ modelId: string().optional(),
15192
15367
  settings: record(string(), unknown()).readonly()
15193
15368
  });
15194
15369
  var AgentPipelineSettingsSchema = object({
@@ -15198,12 +15373,25 @@ var AgentPipelineSettingsSchema = object({
15198
15373
  detectWeight: number().positive().optional(),
15199
15374
  /** Node is eligible to run the detection pipeline (decode + inference). */
15200
15375
  detect: boolean().optional(),
15201
- /** Node is eligible to host decoder sessions. */
15376
+ /**
15377
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15378
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15379
+ * the schema ONLY so persisted stores written before the removal still
15380
+ * parse — no code reads it and no write path emits it.
15381
+ */
15202
15382
  decode: boolean().optional(),
15203
15383
  /** Node is eligible to run audio-analyzer sessions. */
15204
15384
  audio: boolean().optional(),
15205
15385
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
15206
- ingest: boolean().optional()
15386
+ ingest: boolean().optional(),
15387
+ /**
15388
+ * Operator override for the LAN host a cross-node decoder dials to reach
15389
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
15390
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
15391
+ * it already uses to reach the hub). Set this only when the auto-detected
15392
+ * address is wrong (multi-homed host, NAT, custom interface).
15393
+ */
15394
+ reachableHost: string().optional()
15207
15395
  });
15208
15396
  var CameraPipelineForAgentSchema = object({
15209
15397
  steps: array(PipelineStepInputSchema).readonly(),
@@ -15251,25 +15439,6 @@ var PipelineAssignmentSchema = object({
15251
15439
  assignedAt: number()
15252
15440
  });
15253
15441
  /**
15254
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15255
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15256
- * → co-located with pipeline → capacity).
15257
- */
15258
- var DecoderAssignmentSchema = object({
15259
- deviceId: number(),
15260
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15261
- decoderNodeId: string(),
15262
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15263
- pinned: boolean(),
15264
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15265
- reason: _enum([
15266
- "manual",
15267
- "co-located",
15268
- "capacity",
15269
- "hardware-affinity"
15270
- ])
15271
- });
15272
- /**
15273
15442
  * Per-agent load summary surfaced to the load balancer + dashboards.
15274
15443
  * Aggregated from each runner's `getLocalLoad` cap call.
15275
15444
  */
@@ -15309,6 +15478,15 @@ var GlobalMetricsSchema = object({
15309
15478
  * capability providers.
15310
15479
  */
15311
15480
  var CapabilityBindingsSchema = record(string(), string());
15481
+ /**
15482
+ * The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
15483
+ * its LAN-reachable host, if one is registered. See `getIngestOwner`.
15484
+ */
15485
+ var IngestOwnerSchema = object({
15486
+ ownerNodeId: string(),
15487
+ reachableHost: string().optional(),
15488
+ configIssue: string().optional()
15489
+ });
15312
15490
  /** Source block — always present; derives from the stream catalog. */
15313
15491
  var CameraSourceStatusSchema = object({ streams: array(object({
15314
15492
  camStreamId: string(),
@@ -15323,6 +15501,14 @@ var CameraAssignmentStatusSchema = object({
15323
15501
  detectionNodeId: string().nullable(),
15324
15502
  decoderNodeId: string().nullable(),
15325
15503
  audioNodeId: string().nullable(),
15504
+ /**
15505
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
15506
+ * hosts the broker/restream) — the cluster ingest owner today
15507
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
15508
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
15509
+ * broker block below was read from (pinned). Nullable only pre-wiring.
15510
+ */
15511
+ sourceNodeId: string().nullable(),
15326
15512
  pinned: object({
15327
15513
  detection: boolean(),
15328
15514
  decoder: boolean(),
@@ -15455,16 +15641,7 @@ method(object({
15455
15641
  }), object({ success: literal(true) }), {
15456
15642
  kind: "mutation",
15457
15643
  auth: "admin"
15458
- }), method(object({
15459
- deviceId: number(),
15460
- nodeId: string()
15461
- }), _void(), {
15462
- kind: "mutation",
15463
- auth: "admin"
15464
- }), method(object({ deviceId: number() }), _void(), {
15465
- kind: "mutation",
15466
- auth: "admin"
15467
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15644
+ }), method(_void(), IngestOwnerSchema), method(object({
15468
15645
  deviceId: number(),
15469
15646
  nodeId: string()
15470
15647
  }), object({ success: literal(true) }), {
@@ -15485,10 +15662,7 @@ method(object({
15485
15662
  nodeId: string(),
15486
15663
  pinned: boolean(),
15487
15664
  assignedAt: number()
15488
- }))), method(object({
15489
- deviceId: number(),
15490
- pipelineNodeId: string().optional()
15491
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15665
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15492
15666
  nodeId: string(),
15493
15667
  settings: AgentPipelineSettingsSchema
15494
15668
  })).readonly()), method(object({
@@ -15518,12 +15692,26 @@ method(object({
15518
15692
  }), method(object({
15519
15693
  agentNodeId: string(),
15520
15694
  detect: boolean().nullable().optional(),
15521
- decode: boolean().nullable().optional(),
15522
15695
  audio: boolean().nullable().optional(),
15523
15696
  ingest: boolean().nullable().optional()
15524
15697
  }), object({ success: literal(true) }), {
15525
15698
  kind: "mutation",
15526
15699
  auth: "admin"
15700
+ }), method(object({
15701
+ agentNodeId: string(),
15702
+ reachableHost: string().nullable()
15703
+ }), object({ success: literal(true) }), {
15704
+ kind: "mutation",
15705
+ auth: "admin"
15706
+ }), method(object({ agentNodeId: string() }), object({
15707
+ success: literal(true),
15708
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
15709
+ effectiveModelId: string().nullable(),
15710
+ /** Number of cameras whose node-scoped overrides were cleared. */
15711
+ clearedCameraOverrides: number()
15712
+ }), {
15713
+ kind: "mutation",
15714
+ auth: "admin"
15527
15715
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15528
15716
  deviceId: number(),
15529
15717
  addonId: string(),
@@ -15568,22 +15756,131 @@ method(object({
15568
15756
  kind: "mutation",
15569
15757
  auth: "admin"
15570
15758
  });
15571
- var RegisteredStreamSchema = object({
15572
- streamId: string(),
15573
- label: string().optional(),
15574
- codec: string(),
15575
- type: _enum(["video", "audio"]),
15576
- sourceUrl: string()
15759
+ /**
15760
+ * server-management — per-NODE singleton capability for a node's ROOT
15761
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
15762
+ * agents).
15763
+ *
15764
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
15765
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
15766
+ * version describes the node. Updates install into
15767
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
15768
+ * starter (probation boot + auto-rollback to N-1).
15769
+ *
15770
+ * Providers:
15771
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
15772
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
15773
+ * unpinned calls.
15774
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
15775
+ * the synthetic `agent-runtime` addonId and declared in the agent's
15776
+ * `$hub.registerNode` manifest.
15777
+ *
15778
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
15779
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
15780
+ * SDK) routes the call to that node's provider via the standard remote
15781
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
15782
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
15783
+ *
15784
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
15785
+ */
15786
+ /**
15787
+ * Where the running hub's code was loaded from:
15788
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
15789
+ * plain resolution and runtime updates are refused.
15790
+ * - `baked` — the immutable image seed closure (no data-dir root active).
15791
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
15792
+ */
15793
+ var ServerBootModeSchema = _enum([
15794
+ "workspace",
15795
+ "baked",
15796
+ "data-root"
15797
+ ]);
15798
+ /**
15799
+ * Update lifecycle state:
15800
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
15801
+ * - `pending-restart` — a version is staged and the node has NOT yet
15802
+ * restarted onto it (still running the OLD version).
15803
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
15804
+ * (it is the active probation boot) and is waiting to confirm boot-health.
15805
+ * Apply/rollback are refused in this state and the node must NOT be
15806
+ * manually restarted, or the probation boot auto-rolls-back.
15807
+ */
15808
+ var ServerUpdateStateSchema = _enum([
15809
+ "idle",
15810
+ "checking",
15811
+ "staging",
15812
+ "pending-restart",
15813
+ "awaiting-confirmation"
15814
+ ]);
15815
+ var ServerRollbackInfoSchema = object({
15816
+ /** The version that failed (or was manually rolled back). */
15817
+ fromVersion: string(),
15818
+ /** The version rolled back to; null = the baked seed. */
15819
+ toVersion: string().nullable(),
15820
+ atMs: number(),
15821
+ reason: string()
15577
15822
  });
15578
- var ExposedResourceSchema = object({
15579
- streamId: string(),
15580
- format: string(),
15581
- value: string()
15823
+ var ServerPackageStatusSchema = object({
15824
+ /** Root package name (`@camstack/server` on the hub). */
15825
+ packageName: string(),
15826
+ /** Version of the code the running process ACTUALLY loaded. */
15827
+ runningVersion: string().nullable(),
15828
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
15829
+ nodeRuntimeVersion: string().nullable(),
15830
+ /** Active data-dir root version; null when booted from seed/workspace. */
15831
+ activeVersion: string().nullable(),
15832
+ /** N-1 version kept for rollback; null when no previous version exists. */
15833
+ previousVersion: string().nullable(),
15834
+ /** Version of the immutable baked seed closure (image fallback). */
15835
+ seedVersion: string().nullable(),
15836
+ /** Latest registry version from the most recent check (null = never checked). */
15837
+ latestVersion: string().nullable(),
15838
+ updateAvailable: boolean(),
15839
+ bootMode: ServerBootModeSchema,
15840
+ updateState: ServerUpdateStateSchema,
15841
+ /** Version staged + awaiting its probation boot, when one is pending. */
15842
+ pendingVersion: string().nullable(),
15843
+ /** Set when the last freshly-activated version failed its boot health-check. */
15844
+ rolledBack: ServerRollbackInfoSchema.nullable(),
15845
+ /**
15846
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
15847
+ * hub is running from the baked seed (or workspace) while installed data-dir
15848
+ * versions are being IGNORED. Surfaced as a warning in the UI.
15849
+ */
15850
+ stateFileCorrupt: boolean(),
15851
+ lastCheckedAtMs: number().nullable()
15852
+ });
15853
+ var ServerUpdateCheckResultSchema = object({
15854
+ packageName: string(),
15855
+ runningVersion: string().nullable(),
15856
+ latestVersion: string().nullable(),
15857
+ updateAvailable: boolean(),
15858
+ checkedAtMs: number(),
15859
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
15860
+ error: string().nullable()
15861
+ });
15862
+ var ServerUpdateActionResultSchema = object({
15863
+ accepted: boolean(),
15864
+ targetVersion: string().nullable(),
15865
+ /** True when a graceful restart was scheduled to apply the change. */
15866
+ restarting: boolean(),
15867
+ message: string()
15868
+ });
15869
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
15870
+ kind: "mutation",
15871
+ auth: "admin"
15872
+ }), method(object({
15873
+ /** Explicit target version; omitted = latest from the registry. */
15874
+ version: string().optional() }), ServerUpdateActionResultSchema, {
15875
+ kind: "mutation",
15876
+ auth: "admin"
15877
+ }), method(_void(), ServerUpdateActionResultSchema, {
15878
+ kind: "mutation",
15879
+ auth: "admin"
15880
+ }), method(_void(), ServerUpdateActionResultSchema, {
15881
+ kind: "mutation",
15882
+ auth: "admin"
15582
15883
  });
15583
- method(object({
15584
- deviceId: number(),
15585
- streams: array(RegisteredStreamSchema).readonly()
15586
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
15587
15884
  /**
15588
15885
  * Query filter for settings-store collections.
15589
15886
  */
@@ -15736,9 +16033,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
15736
16033
  /**
15737
16034
  * A single device snapshot returned as base64 JPEG/PNG.
15738
16035
  *
15739
- * Shared with the `snapshot-provider` collection cap the orchestrator
15740
- * receives the same shape from each native provider and from the
15741
- * broker-based fallback.
16036
+ * The `SnapshotAddon` wrapper returns this shape whether the frame came from
16037
+ * the device-native provider (onboard capture) or from the stream-broker
16038
+ * prebuffer fallback.
15742
16039
  */
15743
16040
  var SnapshotImageSchema = object({
15744
16041
  base64: string(),
@@ -15770,10 +16067,6 @@ DeviceType.Camera, method(object({
15770
16067
  kind: "mutation",
15771
16068
  auth: "admin"
15772
16069
  });
15773
- method(object({ deviceId: number() }), boolean()), method(object({
15774
- deviceId: number(),
15775
- streamId: string().optional()
15776
- }), SnapshotImageSchema.nullable());
15777
16070
  /**
15778
16071
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
15779
16072
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16134,9 +16427,10 @@ method(object({
16134
16427
  auth: "admin"
16135
16428
  });
16136
16429
  /**
16137
- * Optional client-side hints sent at session creation to help the
16138
- * provider pick the best native source. All fields are optional —
16139
- * a viewer that knows nothing still gets a sane default.
16430
+ * Optional client-side hints sent at session creation to help the provider
16431
+ * pick the best native source. All fields optional — a viewer that knows
16432
+ * nothing still gets a sane default. (Relocated from the retired `webrtc`
16433
+ * collection cap; this `webrtc-session` cap is the live signaling surface.)
16140
16434
  */
16141
16435
  var webrtcClientHintsSchema = object({
16142
16436
  viewportWidth: number().int().positive().optional(),
@@ -16147,22 +16441,6 @@ var webrtcClientHintsSchema = object({
16147
16441
  /** Hard tier override; takes precedence over scoring when registered. */
16148
16442
  prefersTier: string().optional()
16149
16443
  }).partial();
16150
- method(object({
16151
- streamId: string(),
16152
- sdpOffer: string()
16153
- }), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
16154
- streamId: string(),
16155
- codec: string()
16156
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
16157
- streamId: string(),
16158
- hints: webrtcClientHintsSchema.optional()
16159
- }), object({
16160
- sessionId: string(),
16161
- sdpOffer: string()
16162
- }), { kind: "mutation" }), method(object({
16163
- sessionId: string(),
16164
- sdpAnswer: string()
16165
- }), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
16166
16444
  /**
16167
16445
  * Discriminated target for a WebRTC session. The client sends this
16168
16446
  * structured object instead of building / parsing brokerId strings;
@@ -16649,7 +16927,15 @@ var FrameworkPackageStatusSchema = object({
16649
16927
  latestVersion: string().nullable(),
16650
16928
  hasUpdate: boolean(),
16651
16929
  /** Optional manifest description for the row tooltip. */
16652
- description: string().optional()
16930
+ description: string().optional(),
16931
+ /**
16932
+ * Content build-id (md5 of the resolved `dist/` tree) of the code the hub
16933
+ * ACTUALLY loaded. Framework packages ship code changes without always
16934
+ * bumping `currentVersion`, so semver alone hides "same version, new code".
16935
+ * `null` when the dist can't be hashed (not installed / empty). The admin-UI
16936
+ * surfaces this so a stale-code hub is visible even at an unchanged version.
16937
+ */
16938
+ buildId: string().nullable()
16653
16939
  });
16654
16940
  var LogStreamEntrySchema = object({
16655
16941
  timestamp: string(),
@@ -17582,6 +17868,16 @@ var TopologyCategorySchema = object({
17582
17868
  healthy: number(),
17583
17869
  addons: array(TopologyCategoryAddonSchema).readonly()
17584
17870
  });
17871
+ /**
17872
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
17873
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
17874
+ * version visibility for the Server management surface. Nullable: offline
17875
+ * rows and pre-phase-2 nodes report none.
17876
+ */
17877
+ var TopologyRootPackageSchema = object({
17878
+ name: string(),
17879
+ version: string()
17880
+ });
17585
17881
  var TopologyNodeSchema = object({
17586
17882
  id: string(),
17587
17883
  name: string(),
@@ -17605,7 +17901,8 @@ var TopologyNodeSchema = object({
17605
17901
  status: string()
17606
17902
  })).readonly(),
17607
17903
  processes: array(TopologyProcessSchema).readonly(),
17608
- categories: array(TopologyCategorySchema).readonly()
17904
+ categories: array(TopologyCategorySchema).readonly(),
17905
+ rootPackage: TopologyRootPackageSchema.nullable()
17609
17906
  });
17610
17907
  var CapUsageEdgeSchema = object({
17611
17908
  callerAddonId: string(),
@@ -20405,6 +20702,12 @@ Object.freeze({
20405
20702
  addonId: null,
20406
20703
  access: "create"
20407
20704
  },
20705
+ "loginMethod.getLoginMethods": {
20706
+ capName: "login-method",
20707
+ capScope: "system",
20708
+ addonId: null,
20709
+ access: "view"
20710
+ },
20408
20711
  "mediaPlayer.next": {
20409
20712
  capName: "media-player",
20410
20713
  capScope: "device",
@@ -21035,23 +21338,23 @@ Object.freeze({
21035
21338
  addonId: null,
21036
21339
  access: "create"
21037
21340
  },
21038
- "pipelineExecutor.deleteModel": {
21341
+ "pipelineExecutor.clearDeviceOverrides": {
21039
21342
  capName: "pipeline-executor",
21040
21343
  capScope: "system",
21041
21344
  addonId: null,
21042
21345
  access: "delete"
21043
21346
  },
21044
- "pipelineExecutor.deleteTemplate": {
21347
+ "pipelineExecutor.deleteModel": {
21045
21348
  capName: "pipeline-executor",
21046
21349
  capScope: "system",
21047
21350
  addonId: null,
21048
21351
  access: "delete"
21049
21352
  },
21050
- "pipelineExecutor.detect": {
21353
+ "pipelineExecutor.deleteTemplate": {
21051
21354
  capName: "pipeline-executor",
21052
21355
  capScope: "system",
21053
21356
  addonId: null,
21054
- access: "view"
21357
+ access: "delete"
21055
21358
  },
21056
21359
  "pipelineExecutor.downloadModel": {
21057
21360
  capName: "pipeline-executor",
@@ -21245,13 +21548,13 @@ Object.freeze({
21245
21548
  addonId: null,
21246
21549
  access: "create"
21247
21550
  },
21248
- "pipelineOrchestrator.assignAudio": {
21249
- capName: "pipeline-orchestrator",
21551
+ "pipelineExecutor.validatePipeline": {
21552
+ capName: "pipeline-executor",
21250
21553
  capScope: "system",
21251
21554
  addonId: null,
21252
- access: "create"
21555
+ access: "view"
21253
21556
  },
21254
- "pipelineOrchestrator.assignDecoder": {
21557
+ "pipelineOrchestrator.assignAudio": {
21255
21558
  capName: "pipeline-orchestrator",
21256
21559
  capScope: "system",
21257
21560
  addonId: null,
@@ -21335,19 +21638,13 @@ Object.freeze({
21335
21638
  addonId: null,
21336
21639
  access: "view"
21337
21640
  },
21338
- "pipelineOrchestrator.getDecoderAssignment": {
21339
- capName: "pipeline-orchestrator",
21340
- capScope: "system",
21341
- addonId: null,
21342
- access: "view"
21343
- },
21344
- "pipelineOrchestrator.getDecoderAssignments": {
21641
+ "pipelineOrchestrator.getGlobalMetrics": {
21345
21642
  capName: "pipeline-orchestrator",
21346
21643
  capScope: "system",
21347
21644
  addonId: null,
21348
21645
  access: "view"
21349
21646
  },
21350
- "pipelineOrchestrator.getGlobalMetrics": {
21647
+ "pipelineOrchestrator.getIngestOwner": {
21351
21648
  capName: "pipeline-orchestrator",
21352
21649
  capScope: "system",
21353
21650
  addonId: null,
@@ -21389,6 +21686,12 @@ Object.freeze({
21389
21686
  addonId: null,
21390
21687
  access: "delete"
21391
21688
  },
21689
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
21690
+ capName: "pipeline-orchestrator",
21691
+ capScope: "system",
21692
+ addonId: null,
21693
+ access: "delete"
21694
+ },
21392
21695
  "pipelineOrchestrator.resolvePipeline": {
21393
21696
  capName: "pipeline-orchestrator",
21394
21697
  capScope: "system",
@@ -21425,37 +21728,37 @@ Object.freeze({
21425
21728
  addonId: null,
21426
21729
  access: "create"
21427
21730
  },
21428
- "pipelineOrchestrator.setCameraPipelineForAgent": {
21731
+ "pipelineOrchestrator.setAgentReachableHost": {
21429
21732
  capName: "pipeline-orchestrator",
21430
21733
  capScope: "system",
21431
21734
  addonId: null,
21432
21735
  access: "create"
21433
21736
  },
21434
- "pipelineOrchestrator.setCameraStepOverride": {
21737
+ "pipelineOrchestrator.setCameraPipelineForAgent": {
21435
21738
  capName: "pipeline-orchestrator",
21436
21739
  capScope: "system",
21437
21740
  addonId: null,
21438
21741
  access: "create"
21439
21742
  },
21440
- "pipelineOrchestrator.setCameraStepToggle": {
21743
+ "pipelineOrchestrator.setCameraStepOverride": {
21441
21744
  capName: "pipeline-orchestrator",
21442
21745
  capScope: "system",
21443
21746
  addonId: null,
21444
21747
  access: "create"
21445
21748
  },
21446
- "pipelineOrchestrator.setCapabilityBinding": {
21749
+ "pipelineOrchestrator.setCameraStepToggle": {
21447
21750
  capName: "pipeline-orchestrator",
21448
21751
  capScope: "system",
21449
21752
  addonId: null,
21450
21753
  access: "create"
21451
21754
  },
21452
- "pipelineOrchestrator.unassignAudio": {
21755
+ "pipelineOrchestrator.setCapabilityBinding": {
21453
21756
  capName: "pipeline-orchestrator",
21454
21757
  capScope: "system",
21455
21758
  addonId: null,
21456
21759
  access: "create"
21457
21760
  },
21458
- "pipelineOrchestrator.unassignDecoder": {
21761
+ "pipelineOrchestrator.unassignAudio": {
21459
21762
  capName: "pipeline-orchestrator",
21460
21763
  capScope: "system",
21461
21764
  addonId: null,
@@ -21755,33 +22058,45 @@ Object.freeze({
21755
22058
  addonId: null,
21756
22059
  access: "create"
21757
22060
  },
21758
- "restreamer.getExposedResources": {
21759
- capName: "restreamer",
22061
+ "scriptRunner.run": {
22062
+ capName: "script-runner",
22063
+ capScope: "device",
22064
+ addonId: null,
22065
+ access: "create"
22066
+ },
22067
+ "scriptRunner.stop": {
22068
+ capName: "script-runner",
22069
+ capScope: "device",
22070
+ addonId: null,
22071
+ access: "create"
22072
+ },
22073
+ "serverManagement.applyServerUpdate": {
22074
+ capName: "server-management",
21760
22075
  capScope: "system",
21761
22076
  addonId: null,
21762
- access: "view"
22077
+ access: "create"
21763
22078
  },
21764
- "restreamer.registerDevice": {
21765
- capName: "restreamer",
22079
+ "serverManagement.checkServerUpdate": {
22080
+ capName: "server-management",
21766
22081
  capScope: "system",
21767
22082
  addonId: null,
21768
22083
  access: "create"
21769
22084
  },
21770
- "restreamer.unregisterDevice": {
21771
- capName: "restreamer",
22085
+ "serverManagement.getServerPackageStatus": {
22086
+ capName: "server-management",
21772
22087
  capScope: "system",
21773
22088
  addonId: null,
21774
- access: "delete"
22089
+ access: "view"
21775
22090
  },
21776
- "scriptRunner.run": {
21777
- capName: "script-runner",
21778
- capScope: "device",
22091
+ "serverManagement.restartServer": {
22092
+ capName: "server-management",
22093
+ capScope: "system",
21779
22094
  addonId: null,
21780
22095
  access: "create"
21781
22096
  },
21782
- "scriptRunner.stop": {
21783
- capName: "script-runner",
21784
- capScope: "device",
22097
+ "serverManagement.rollbackServerUpdate": {
22098
+ capName: "server-management",
22099
+ capScope: "system",
21785
22100
  addonId: null,
21786
22101
  access: "create"
21787
22102
  },
@@ -21875,18 +22190,6 @@ Object.freeze({
21875
22190
  addonId: null,
21876
22191
  access: "create"
21877
22192
  },
21878
- "snapshotProvider.getSnapshot": {
21879
- capName: "snapshot-provider",
21880
- capScope: "system",
21881
- addonId: null,
21882
- access: "view"
21883
- },
21884
- "snapshotProvider.supportsDevice": {
21885
- capName: "snapshot-provider",
21886
- capScope: "system",
21887
- addonId: null,
21888
- access: "view"
21889
- },
21890
22193
  "ssoBridge.signBridgeToken": {
21891
22194
  capName: "sso-bridge",
21892
22195
  capScope: "system",
@@ -22313,30 +22616,6 @@ Object.freeze({
22313
22616
  addonId: null,
22314
22617
  access: "view"
22315
22618
  },
22316
- "streamingEngine.getStreamUrl": {
22317
- capName: "streaming-engine",
22318
- capScope: "system",
22319
- addonId: null,
22320
- access: "view"
22321
- },
22322
- "streamingEngine.listStreams": {
22323
- capName: "streaming-engine",
22324
- capScope: "system",
22325
- addonId: null,
22326
- access: "view"
22327
- },
22328
- "streamingEngine.registerStream": {
22329
- capName: "streaming-engine",
22330
- capScope: "system",
22331
- addonId: null,
22332
- access: "create"
22333
- },
22334
- "streamingEngine.unregisterStream": {
22335
- capName: "streaming-engine",
22336
- capScope: "system",
22337
- addonId: null,
22338
- access: "delete"
22339
- },
22340
22619
  "streamParams.getConfigSchema": {
22341
22620
  capName: "stream-params",
22342
22621
  capScope: "device",
@@ -22685,6 +22964,18 @@ Object.freeze({
22685
22964
  addonId: null,
22686
22965
  access: "view"
22687
22966
  },
22967
+ "viewerUi.getStaticDir": {
22968
+ capName: "viewer-ui",
22969
+ capScope: "system",
22970
+ addonId: null,
22971
+ access: "view"
22972
+ },
22973
+ "viewerUi.getVersion": {
22974
+ capName: "viewer-ui",
22975
+ capScope: "system",
22976
+ addonId: null,
22977
+ access: "view"
22978
+ },
22688
22979
  "waterHeater.setAway": {
22689
22980
  capName: "water-heater",
22690
22981
  capScope: "device",
@@ -22703,54 +22994,6 @@ Object.freeze({
22703
22994
  addonId: null,
22704
22995
  access: "create"
22705
22996
  },
22706
- "webrtc.closeSession": {
22707
- capName: "webrtc",
22708
- capScope: "system",
22709
- addonId: null,
22710
- access: "create"
22711
- },
22712
- "webrtc.createSession": {
22713
- capName: "webrtc",
22714
- capScope: "system",
22715
- addonId: null,
22716
- access: "create"
22717
- },
22718
- "webrtc.handleAnswer": {
22719
- capName: "webrtc",
22720
- capScope: "system",
22721
- addonId: null,
22722
- access: "create"
22723
- },
22724
- "webrtc.handleOffer": {
22725
- capName: "webrtc",
22726
- capScope: "system",
22727
- addonId: null,
22728
- access: "create"
22729
- },
22730
- "webrtc.hasAdaptiveBitrate": {
22731
- capName: "webrtc",
22732
- capScope: "system",
22733
- addonId: null,
22734
- access: "view"
22735
- },
22736
- "webrtc.registerStream": {
22737
- capName: "webrtc",
22738
- capScope: "system",
22739
- addonId: null,
22740
- access: "create"
22741
- },
22742
- "webrtc.supportsStream": {
22743
- capName: "webrtc",
22744
- capScope: "system",
22745
- addonId: null,
22746
- access: "view"
22747
- },
22748
- "webrtc.unregisterStream": {
22749
- capName: "webrtc",
22750
- capScope: "system",
22751
- addonId: null,
22752
- access: "delete"
22753
- },
22754
22997
  "webrtcSession.addIceCandidate": {
22755
22998
  capName: "webrtc-session",
22756
22999
  capScope: "device",