camstack 1.1.21 → 1.1.23

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-CZDdRBua.mjs
14525
+ // ../types/dist/sleep-DJaTV2D7.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -15135,13 +15135,25 @@ function method(input, output, options) {
15135
15135
  function event(data) {
15136
15136
  return { data };
15137
15137
  }
15138
- var StaticDirOutputSchema = external_exports.object({ staticDir: external_exports.string() });
15139
- var VersionOutputSchema = external_exports.object({ version: external_exports.string() });
15138
+ var StaticDirOutputSchema$1 = external_exports.object({ staticDir: external_exports.string() });
15139
+ var VersionOutputSchema$1 = external_exports.object({ version: external_exports.string() });
15140
15140
  var adminUiCapability = {
15141
15141
  name: "admin-ui",
15142
15142
  scope: "system",
15143
15143
  mode: "singleton",
15144
15144
  internal: true,
15145
+ methods: {
15146
+ getStaticDir: method(external_exports.void(), StaticDirOutputSchema$1),
15147
+ getVersion: method(external_exports.void(), VersionOutputSchema$1)
15148
+ }
15149
+ };
15150
+ var StaticDirOutputSchema = external_exports.object({ staticDir: external_exports.string() });
15151
+ var VersionOutputSchema = external_exports.object({ version: external_exports.string() });
15152
+ var viewerUiCapability = {
15153
+ name: "viewer-ui",
15154
+ scope: "system",
15155
+ mode: "singleton",
15156
+ internal: true,
15145
15157
  methods: {
15146
15158
  getStaticDir: method(external_exports.void(), StaticDirOutputSchema),
15147
15159
  getVersion: method(external_exports.void(), VersionOutputSchema)
@@ -15322,6 +15334,28 @@ var ModelFormatsSchema = external_exports.object({
15322
15334
  tflite: ModelFormatEntrySchema.optional(),
15323
15335
  pt: ModelFormatEntrySchema.optional()
15324
15336
  });
15337
+ var ModelVariantGroupSchema = external_exports.object({
15338
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
15339
+ family: external_exports.string(),
15340
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
15341
+ tier: external_exports.string(),
15342
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
15343
+ precision: external_exports.enum(["fp32", "int8"]).optional(),
15344
+ /**
15345
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
15346
+ * latency-optimized export (e.g. ReLU-activation variant) — the slot the
15347
+ * future performance variants plug into.
15348
+ */
15349
+ optimization: external_exports.enum(["standard", "fast"]).optional(),
15350
+ /**
15351
+ * Input-resolution axis (square input side, px). Omit ⇒ the family's native
15352
+ * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
15353
+ * cheap latency lever — especially on Apple ANE and the Intel N100 — at a
15354
+ * small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
15355
+ * the group so the selector can offer it as a variant axis.
15356
+ */
15357
+ resolution: external_exports.number().int().positive().optional()
15358
+ });
15325
15359
  var ModelCatalogEntrySchema = external_exports.object({
15326
15360
  id: external_exports.string(),
15327
15361
  name: external_exports.string(),
@@ -15351,7 +15385,43 @@ var ModelCatalogEntrySchema = external_exports.object({
15351
15385
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
15352
15386
  * Downloaded into the same modelsDir alongside the model file.
15353
15387
  */
15354
- extraFiles: external_exports.array(ModelExtraFileSchema).readonly().optional()
15388
+ extraFiles: external_exports.array(ModelExtraFileSchema).readonly().optional(),
15389
+ /**
15390
+ * LEGACY entry — retained in the catalog so a persisted operator selection
15391
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
15392
+ * model list and excluded from the auto format-default pick. Set on the
15393
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
15394
+ * the active lineup stays the coherent curated ladder without deleting a
15395
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
15396
+ * an explicit legacy id that has a build for the node's format.
15397
+ */
15398
+ legacy: external_exports.boolean().optional(),
15399
+ /**
15400
+ * Measured quality/latency metadata — populated from the benchmark addon on
15401
+ * the real node classes. Absent = not yet measured (most entries today; the
15402
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
15403
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
15404
+ */
15405
+ metrics: external_exports.object({
15406
+ map50: external_exports.number().optional(),
15407
+ p95LatencyMs: external_exports.record(external_exports.string(), external_exports.number()).optional()
15408
+ }).optional(),
15409
+ /**
15410
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
15411
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
15412
+ * the retraining addon and any future commercial distribution.
15413
+ */
15414
+ license: external_exports.string().optional(),
15415
+ /**
15416
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
15417
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
15418
+ * of a family's sizes and quantizations collapse into one grouped picker
15419
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
15420
+ * (legacy / custom models) — never shown in the grouped selector. The flat
15421
+ * `id` stays the source of truth for resolution/download/persistence; grouping
15422
+ * is a presentation overlay resolved back to an `id`.
15423
+ */
15424
+ group: ModelVariantGroupSchema.optional()
15355
15425
  });
15356
15426
  var ConvertTargetSchema = external_exports.discriminatedUnion("format", [external_exports.object({
15357
15427
  format: external_exports.literal("openvino"),
@@ -17009,33 +17079,6 @@ var StreamFormatSchema = external_exports.enum([
17009
17079
  "mjpeg",
17010
17080
  "rtsp"
17011
17081
  ]);
17012
- var StreamInfoSchema = external_exports.object({
17013
- streamId: external_exports.string(),
17014
- format: StreamFormatSchema,
17015
- url: external_exports.string().nullable(),
17016
- active: external_exports.boolean()
17017
- });
17018
- var streamingEngineCapability = {
17019
- name: "streaming-engine",
17020
- scope: "system",
17021
- mode: "singleton",
17022
- internal: true,
17023
- methods: {
17024
- registerStream: method(external_exports.object({
17025
- streamId: external_exports.string(),
17026
- sourceUrl: external_exports.string(),
17027
- codec: external_exports.string().optional()
17028
- }), external_exports.void(), { kind: "mutation" }),
17029
- unregisterStream: method(external_exports.object({ streamId: external_exports.string() }), external_exports.void(), { kind: "mutation" }),
17030
- getStreamUrl: method(external_exports.object({
17031
- streamId: external_exports.string(),
17032
- format: StreamFormatSchema
17033
- }), external_exports.string().nullable()),
17034
- listStreams: method(external_exports.void(), external_exports.array(StreamInfoSchema))
17035
- },
17036
- /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
17037
- mount: { kind: "skip" }
17038
- };
17039
17082
  var RtspRestreamEntrySchema = external_exports.object({
17040
17083
  brokerId: external_exports.string(),
17041
17084
  url: external_exports.string(),
@@ -17912,37 +17955,7 @@ var consumablesCapability = {
17912
17955
  scope: "device",
17913
17956
  deviceNative: true,
17914
17957
  mode: "singleton",
17915
- deviceTypes: [
17916
- DeviceType.Camera,
17917
- DeviceType.Hub,
17918
- DeviceType.Light,
17919
- DeviceType.Siren,
17920
- DeviceType.Switch,
17921
- DeviceType.Sensor,
17922
- DeviceType.Thermostat,
17923
- DeviceType.Button,
17924
- DeviceType.EventEmitter,
17925
- DeviceType.Update,
17926
- DeviceType.Generic,
17927
- DeviceType.Notifier,
17928
- DeviceType.Script,
17929
- DeviceType.Automation,
17930
- DeviceType.Lock,
17931
- DeviceType.Cover,
17932
- DeviceType.Valve,
17933
- DeviceType.Humidifier,
17934
- DeviceType.WaterHeater,
17935
- DeviceType.Fan,
17936
- DeviceType.MediaPlayer,
17937
- DeviceType.AlarmPanel,
17938
- DeviceType.Control,
17939
- DeviceType.Presence,
17940
- DeviceType.Weather,
17941
- DeviceType.Vacuum,
17942
- DeviceType.LawnMower,
17943
- DeviceType.Container,
17944
- DeviceType.Image
17945
- ],
17958
+ deviceTypes: Object.values(DeviceType),
17946
17959
  deviceConfig: { ui: {
17947
17960
  kind: "widget",
17948
17961
  widgetId: "host/consumables-panel",
@@ -19179,7 +19192,6 @@ var PipelineDefaultStepSchema = external_exports.lazy(() => external_exports.obj
19179
19192
  enabled: external_exports.boolean(),
19180
19193
  modelId: external_exports.string(),
19181
19194
  children: external_exports.array(PipelineDefaultStepSchema).readonly(),
19182
- engine: PipelineEngineChoiceSchema.optional(),
19183
19195
  group: external_exports.string().optional(),
19184
19196
  settings: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
19185
19197
  }));
@@ -19204,7 +19216,9 @@ var PipelineModelOptionSchema = external_exports.object({
19204
19216
  formats: external_exports.record(external_exports.string(), external_exports.object({
19205
19217
  downloaded: external_exports.boolean(),
19206
19218
  sizeMB: external_exports.number()
19207
- }))
19219
+ })),
19220
+ group: ModelVariantGroupSchema.optional(),
19221
+ legacy: external_exports.boolean().optional()
19208
19222
  });
19209
19223
  var ConfigFieldBridge = external_exports.custom();
19210
19224
  var PipelineAddonSchemaSchema = external_exports.object({
@@ -19234,11 +19248,6 @@ var PipelineSchemaSchema = external_exports.object({
19234
19248
  selectedEngine: PipelineEngineChoiceSchema,
19235
19249
  slots: external_exports.array(PipelineSlotSchemaSchema).readonly()
19236
19250
  });
19237
- var DetectorOutputSchema = external_exports.object({
19238
- detections: external_exports.array(SpatialDetectionSchema).readonly(),
19239
- inferenceMs: external_exports.number(),
19240
- modelId: external_exports.string()
19241
- });
19242
19251
  var EngineProvisioningSchema = external_exports.object({
19243
19252
  runtimeId: external_exports.enum([
19244
19253
  "onnx",
@@ -19255,15 +19264,42 @@ var EngineProvisioningSchema = external_exports.object({
19255
19264
  ]),
19256
19265
  progress: external_exports.number().optional(),
19257
19266
  error: external_exports.string().optional(),
19258
- nextRetryAt: external_exports.number().optional()
19267
+ nextRetryAt: external_exports.number().optional(),
19268
+ /**
19269
+ * Gate A (config-correctness gate at engine change): human-readable
19270
+ * config issues surfaced EAGERLY when the node's engine changes — model
19271
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
19272
+ * has a <format> build"). Additive/optional: informational only, never
19273
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
19274
+ * Absent/empty when the node-default tree resolves cleanly.
19275
+ */
19276
+ configIssues: external_exports.array(external_exports.string()).optional()
19259
19277
  });
19260
19278
  var PipelineStepInputSchema = external_exports.lazy(() => external_exports.object({
19261
19279
  addonId: external_exports.string(),
19262
- modelId: external_exports.string(),
19280
+ modelId: external_exports.string().optional(),
19263
19281
  enabled: external_exports.boolean().default(true),
19264
19282
  children: external_exports.array(PipelineStepInputSchema).optional(),
19265
19283
  settings: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
19266
19284
  }));
19285
+ var ModelSubstitutionSchema = external_exports.object({
19286
+ addonId: external_exports.string(),
19287
+ chosen: external_exports.string(),
19288
+ running: external_exports.string(),
19289
+ format: external_exports.string()
19290
+ });
19291
+ var PipelineValidationIssueSchema = external_exports.object({
19292
+ addonId: external_exports.string(),
19293
+ kind: external_exports.enum(["unknown-addon", "no-format-build"]),
19294
+ detail: external_exports.string()
19295
+ });
19296
+ var PipelineValidationResultSchema = external_exports.object({
19297
+ ok: external_exports.boolean(),
19298
+ issues: external_exports.array(PipelineValidationIssueSchema).readonly(),
19299
+ substitutions: external_exports.array(ModelSubstitutionSchema).readonly(),
19300
+ /** The node's `currentEngine.format` this validation ran against. */
19301
+ format: external_exports.string()
19302
+ });
19267
19303
  var ReferenceImageEntrySchema = external_exports.object({
19268
19304
  filename: external_exports.string(),
19269
19305
  stepIds: external_exports.array(external_exports.string()).readonly().optional()
@@ -19354,10 +19390,45 @@ var pipelineExecutorCapability = {
19354
19390
  kind: "mutation",
19355
19391
  auth: "admin"
19356
19392
  }),
19393
+ /**
19394
+ * Clear THIS node's executor-side PER-DEVICE settings stores (the
19395
+ * per-camera step overrides the object-detection root reads via
19396
+ * `applyDeviceOverridesToTree`). `nodeId` is the ROUTING key — the
19397
+ * generated cap-router strips it (default `nodeIdMode: 'routing'`) and
19398
+ * dispatches to that node, so the provider method runs ON the target
19399
+ * node and receives no `nodeId`.
19400
+ *
19401
+ * This is the slimmed executor leg of the orchestrator's
19402
+ * `resetNodePipelineDefaults` flow (which owns the real reset: node
19403
+ * addonDefaults pins + per-camera orchestrator overrides). The legacy
19404
+ * `resetToDefault` — which reset a persisted global step-tree seed
19405
+ * nothing in the live per-camera path read — was removed together with
19406
+ * that seed.
19407
+ */
19408
+ clearDeviceOverrides: method(external_exports.object({ nodeId: external_exports.string() }), external_exports.object({
19409
+ success: external_exports.literal(true),
19410
+ clearedDevices: external_exports.number()
19411
+ }), {
19412
+ kind: "mutation",
19413
+ auth: "admin"
19414
+ }),
19357
19415
  getSchema: method(external_exports.void(), PipelineSchemaSchema),
19358
19416
  getGlobalSteps: method(external_exports.void(), external_exports.array(PipelineDefaultStepSchema).readonly().nullable()),
19359
19417
  getGlobalPipelineConfig: method(external_exports.void(), PipelineConfigBridge),
19360
19418
  getOrchestratorConfigSchema: method(external_exports.void(), ConfigUISchemaBridge),
19419
+ /**
19420
+ * Gate B (pre-init config-correctness gate). PURE COMPUTE against this
19421
+ * node's `currentEngine.format` — resolves `steps` the same way the
19422
+ * runtime dispatch path would, and reports what WOULD happen without
19423
+ * touching any node-global state. Called by the orchestrator at attach
19424
+ * time (`attachOn`), node-pinned to the TARGET node, so config problems
19425
+ * surface BEFORE `pipelineRunner.attachCamera` rather than at the first
19426
+ * per-frame resolve. `ok` is false iff `issues` is non-empty (both
19427
+ * `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
19428
+ * is informational (a degraded-but-loadable model swap) and never
19429
+ * affects `ok`. Never throws.
19430
+ */
19431
+ validatePipeline: method(external_exports.object({ steps: external_exports.array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
19361
19432
  listTemplates: method(external_exports.void(), external_exports.array(PipelineTemplateSchema$1).readonly()),
19362
19433
  saveTemplate: method(external_exports.object({
19363
19434
  name: external_exports.string(),
@@ -19382,11 +19453,6 @@ var pipelineExecutorCapability = {
19382
19453
  modelId: external_exports.string(),
19383
19454
  format: ModelFormatSchema$1
19384
19455
  }), external_exports.object({ success: external_exports.literal(true) }), { kind: "mutation" }),
19385
- detect: method(external_exports.object({
19386
- addonId: external_exports.string(),
19387
- frame: FrameInputSchema,
19388
- config: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
19389
- }), DetectorOutputSchema),
19390
19456
  /**
19391
19457
  * Stateless single-frame execution. Callers (runner, benchmark) pass
19392
19458
  * the complete `engine` + `steps` tree; the executor holds no state
@@ -19647,6 +19713,13 @@ var RunnerFrameSourceSchema = external_exports.discriminatedUnion("kind", [exter
19647
19713
  kind: external_exports.literal("remote-restream"),
19648
19714
  /** The camera's source-owner node (slice 1: always the hub). */
19649
19715
  ownerNodeId: external_exports.string(),
19716
+ /**
19717
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
19718
+ * per-node `reachableHost` override (Cluster UI). When present the runner
19719
+ * dials THIS host for the owner's restream, in preference to the
19720
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
19721
+ */
19722
+ ownerReachableHost: external_exports.string().optional(),
19650
19723
  /** Operator override for the owner host the runner dials. */
19651
19724
  hubHostnameOverride: external_exports.string().optional()
19652
19725
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -19699,14 +19772,11 @@ var RunnerCameraConfigSchema = external_exports.object({
19699
19772
  */
19700
19773
  motionSources: MotionSourcesSchema.default(["analyzer"]),
19701
19774
  pipelineEnabled: external_exports.boolean().default(true),
19702
- /** Engine choice for video steps (runtime+backend+format). */
19703
- engine: PipelineEngineChoiceSchema.optional(),
19704
19775
  /** Ordered tree of video steps. Absent → runner skips video detection. */
19705
19776
  steps: external_exports.array(PipelineStepInputSchema).readonly().optional(),
19706
19777
  /** Audio classification branch. `enabled:false` disables, null skips. */
19707
19778
  audio: external_exports.object({
19708
- engine: PipelineEngineChoiceSchema,
19709
- modelId: external_exports.string(),
19779
+ modelId: external_exports.string().optional(),
19710
19780
  enabled: external_exports.boolean()
19711
19781
  }).nullable().optional(),
19712
19782
  /**
@@ -21849,7 +21919,9 @@ var AddonPageDeclarationSchema$1 = external_exports.object({
21849
21919
  icon: external_exports.string(),
21850
21920
  path: external_exports.string(),
21851
21921
  remoteName: external_exports.string(),
21852
- bundle: external_exports.string()
21922
+ bundle: external_exports.string(),
21923
+ section: external_exports.string().optional(),
21924
+ sectionLabel: external_exports.string().optional()
21853
21925
  });
21854
21926
  var AddonPageInfoSchema = external_exports.object({
21855
21927
  addonId: external_exports.string(),
@@ -21882,7 +21954,18 @@ var AddonPageDeclarationSchema = external_exports.object({
21882
21954
  * the static-file route can compute an mtime-based cache-buster URL
21883
21955
  * without a separate filesystem stat.
21884
21956
  */
21885
- bundle: external_exports.string()
21957
+ bundle: external_exports.string(),
21958
+ /**
21959
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
21960
+ * `'cluster'`, `'administration'` — the page renders inside that group.
21961
+ * Any OTHER string creates (or joins) a custom section rendered after
21962
+ * the built-in groups; its label comes from `sectionLabel` (first
21963
+ * declaration wins), falling back to the id. Absent → the legacy
21964
+ * "Addon Pages" group.
21965
+ */
21966
+ section: external_exports.string().optional(),
21967
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
21968
+ sectionLabel: external_exports.string().optional()
21886
21969
  });
21887
21970
  var addonPagesSourceCapability = {
21888
21971
  name: "addon-pages-source",
@@ -22067,6 +22150,17 @@ var WidgetMetadataSchema = external_exports.object({
22067
22150
  deviceContext: external_exports.boolean().default(false),
22068
22151
  integrationContext: external_exports.boolean().default(false)
22069
22152
  }),
22153
+ /**
22154
+ * Loadable BEFORE authentication. The normal widget registry listing
22155
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
22156
+ * (the login page) cannot discover a widget through it. A widget that
22157
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
22158
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
22159
+ * login-method contribution channel (see `login-method.cap.ts`) rather
22160
+ * than the authenticated registry, and its bundle is served by the
22161
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
22162
+ */
22163
+ preAuth: external_exports.boolean().optional().default(false),
22070
22164
  /** Dashboard placement HINTS (operator can override per instance). */
22071
22165
  defaultSize: WidgetSizeEnum.default("md"),
22072
22166
  allowedSizes: external_exports.array(WidgetSizeEnum).readonly().default([
@@ -22454,6 +22548,41 @@ var authProviderCapability = {
22454
22548
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
22455
22549
  mount: { kind: "skip" }
22456
22550
  };
22551
+ var LoginStageEnum = external_exports.enum(["primary", "second-factor"]);
22552
+ var RedirectLoginMethodSchema = external_exports.object({
22553
+ kind: external_exports.literal("redirect"),
22554
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
22555
+ id: external_exports.string(),
22556
+ /** Operator-facing button label. */
22557
+ label: external_exports.string(),
22558
+ /** lucide-react icon name. */
22559
+ icon: external_exports.string().optional(),
22560
+ /** Addon-owned HTTP route the button navigates to (GET). */
22561
+ startUrl: external_exports.string(),
22562
+ stage: LoginStageEnum
22563
+ });
22564
+ var WidgetLoginMethodSchema = external_exports.object({
22565
+ kind: external_exports.literal("widget"),
22566
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
22567
+ id: external_exports.string(),
22568
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
22569
+ addonId: external_exports.string(),
22570
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
22571
+ bundle: external_exports.string(),
22572
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
22573
+ remote: WidgetRemoteSchema,
22574
+ stage: LoginStageEnum
22575
+ });
22576
+ var LoginMethodContributionSchema = external_exports.discriminatedUnion("kind", [RedirectLoginMethodSchema, WidgetLoginMethodSchema]);
22577
+ var loginMethodCapability = {
22578
+ name: "login-method",
22579
+ scope: "system",
22580
+ mode: "collection",
22581
+ internal: true,
22582
+ methods: { getLoginMethods: method(external_exports.void(), external_exports.array(LoginMethodContributionSchema).readonly()) },
22583
+ /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
22584
+ mount: { kind: "skip" }
22585
+ };
22457
22586
  var BackupDestinationInfoSchema = external_exports.object({
22458
22587
  /**
22459
22588
  * Sub-id within this addon. Convention `default` for single-
@@ -25091,11 +25220,11 @@ var pipelineAnalyticsCapability = {
25091
25220
  }
25092
25221
  };
25093
25222
  var CameraPipelineConfigSchema = external_exports.object({
25094
- engine: PipelineEngineChoiceSchema,
25223
+ engine: PipelineEngineChoiceSchema.optional(),
25095
25224
  steps: external_exports.array(PipelineStepInputSchema).readonly(),
25096
25225
  audio: external_exports.object({
25097
- engine: PipelineEngineChoiceSchema,
25098
- modelId: external_exports.string(),
25226
+ engine: PipelineEngineChoiceSchema.optional(),
25227
+ modelId: external_exports.string().optional(),
25099
25228
  enabled: external_exports.boolean(),
25100
25229
  settings: external_exports.record(external_exports.string(), external_exports.unknown()).readonly().optional()
25101
25230
  }).nullable().optional()
@@ -25110,7 +25239,7 @@ var PipelineTemplateSchema = external_exports.object({
25110
25239
  });
25111
25240
  var AgentAddonConfigSchema = external_exports.object({
25112
25241
  enabled: external_exports.boolean(),
25113
- modelId: external_exports.string(),
25242
+ modelId: external_exports.string().optional(),
25114
25243
  settings: external_exports.record(external_exports.string(), external_exports.unknown()).readonly()
25115
25244
  });
25116
25245
  var AgentPipelineSettingsSchema = external_exports.object({
@@ -25120,12 +25249,25 @@ var AgentPipelineSettingsSchema = external_exports.object({
25120
25249
  detectWeight: external_exports.number().positive().optional(),
25121
25250
  /** Node is eligible to run the detection pipeline (decode + inference). */
25122
25251
  detect: external_exports.boolean().optional(),
25123
- /** Node is eligible to host decoder sessions. */
25252
+ /**
25253
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
25254
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
25255
+ * the schema ONLY so persisted stores written before the removal still
25256
+ * parse — no code reads it and no write path emits it.
25257
+ */
25124
25258
  decode: external_exports.boolean().optional(),
25125
25259
  /** Node is eligible to run audio-analyzer sessions. */
25126
25260
  audio: external_exports.boolean().optional(),
25127
25261
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
25128
- ingest: external_exports.boolean().optional()
25262
+ ingest: external_exports.boolean().optional(),
25263
+ /**
25264
+ * Operator override for the LAN host a cross-node decoder dials to reach
25265
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
25266
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
25267
+ * it already uses to reach the hub). Set this only when the auto-detected
25268
+ * address is wrong (multi-homed host, NAT, custom interface).
25269
+ */
25270
+ reachableHost: external_exports.string().optional()
25129
25271
  });
25130
25272
  var CameraPipelineForAgentSchema = external_exports.object({
25131
25273
  steps: external_exports.array(PipelineStepInputSchema).readonly(),
@@ -25162,20 +25304,6 @@ var PipelineAssignmentSchema = external_exports.object({
25162
25304
  /** Unix timestamp (ms) when the assignment was last updated. */
25163
25305
  assignedAt: external_exports.number()
25164
25306
  });
25165
- var DecoderAssignmentSchema = external_exports.object({
25166
- deviceId: external_exports.number(),
25167
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
25168
- decoderNodeId: external_exports.string(),
25169
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
25170
- pinned: external_exports.boolean(),
25171
- /** Why this assignment was made — useful for debugging the decoder balancer. */
25172
- reason: external_exports.enum([
25173
- "manual",
25174
- "co-located",
25175
- "capacity",
25176
- "hardware-affinity"
25177
- ])
25178
- });
25179
25307
  var AgentLoadSummarySchema = external_exports.object({
25180
25308
  nodeId: external_exports.string(),
25181
25309
  online: external_exports.boolean(),
@@ -25198,6 +25326,11 @@ var GlobalMetricsSchema = external_exports.object({
25198
25326
  queueDepth: external_exports.number()
25199
25327
  });
25200
25328
  var CapabilityBindingsSchema = external_exports.record(external_exports.string(), external_exports.string());
25329
+ var IngestOwnerSchema = external_exports.object({
25330
+ ownerNodeId: external_exports.string(),
25331
+ reachableHost: external_exports.string().optional(),
25332
+ configIssue: external_exports.string().optional()
25333
+ });
25201
25334
  var CameraSourceStreamSchema = external_exports.object({
25202
25335
  camStreamId: external_exports.string(),
25203
25336
  codec: external_exports.string(),
@@ -25211,6 +25344,14 @@ var CameraAssignmentStatusSchema = external_exports.object({
25211
25344
  detectionNodeId: external_exports.string().nullable(),
25212
25345
  decoderNodeId: external_exports.string().nullable(),
25213
25346
  audioNodeId: external_exports.string().nullable(),
25347
+ /**
25348
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
25349
+ * hosts the broker/restream) — the cluster ingest owner today
25350
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
25351
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
25352
+ * broker block below was read from (pinned). Nullable only pre-wiring.
25353
+ */
25354
+ sourceNodeId: external_exports.string().nullable(),
25214
25355
  pinned: external_exports.object({
25215
25356
  detection: external_exports.boolean(),
25216
25357
  decoder: external_exports.boolean(),
@@ -25384,21 +25525,14 @@ var pipelineOrchestratorCapability = {
25384
25525
  kind: "mutation",
25385
25526
  auth: "admin"
25386
25527
  }),
25387
- /** Pin a device's decoder to a specific node. */
25388
- assignDecoder: method(external_exports.object({
25389
- deviceId: external_exports.number(),
25390
- nodeId: external_exports.string()
25391
- }), external_exports.void(), {
25392
- kind: "mutation",
25393
- auth: "admin"
25394
- }),
25395
- /** Clear a device's decoder pin (revert to auto). */
25396
- unassignDecoder: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.void(), {
25397
- kind: "mutation",
25398
- auth: "admin"
25399
- }),
25400
- /** Get every camera's decoder placement. */
25401
- getDecoderAssignments: method(external_exports.void(), external_exports.array(DecoderAssignmentSchema).readonly()),
25528
+ /**
25529
+ * The cluster's single camera-source owner — resolved UNCONDITIONALLY
25530
+ * from `clusterRoles.ingestNode` (NOT the detection-decode
25531
+ * `remoteSourcingNodes` knob). Consumers (recorder/snapshot/audio) pin
25532
+ * their broker calls to `ownerNodeId` and dial `reachableHost` when
25533
+ * present. Defaults to `{ ownerNodeId: 'hub' }`.
25534
+ */
25535
+ getIngestOwner: method(external_exports.void(), IngestOwnerSchema),
25402
25536
  /** Pin a device's audio analysis to a specific cluster node. */
25403
25537
  assignAudio: method(external_exports.object({
25404
25538
  deviceId: external_exports.number(),
@@ -25430,23 +25564,6 @@ var pipelineOrchestratorCapability = {
25430
25564
  pinned: external_exports.boolean(),
25431
25565
  assignedAt: external_exports.number()
25432
25566
  }))),
25433
- /**
25434
- * Get one camera's decoder placement (computed if not yet pinned).
25435
- *
25436
- * ADVISORY today: reports the orchestrator's decoder preference only.
25437
- * Actual decode placement is broker-owned (local-node pin + frame-plane
25438
- * co-location guard). Reserved to become the binding source/decoder-owner
25439
- * control in the stream-LB epic (Phase 2).
25440
- *
25441
- * `pipelineNodeId` is the node already chosen to run inference for
25442
- * this camera. When provided, the balancer prefers co-location with
25443
- * it; omitted → falls back to the last known assignment in the
25444
- * `assignments` map and finally to 'hub'.
25445
- */
25446
- getDecoderAssignment: method(external_exports.object({
25447
- deviceId: external_exports.number(),
25448
- pipelineNodeId: external_exports.string().optional()
25449
- }), DecoderAssignmentSchema),
25450
25567
  /** Read one agent's settings. Null when not yet seeded. */
25451
25568
  getAgentSettings: method(external_exports.object({ agentNodeId: external_exports.string() }), AgentPipelineSettingsSchema.nullable()),
25452
25569
  /** Enumerate every agent's settings (hub + remote runners). */
@@ -25516,20 +25633,65 @@ var pipelineOrchestratorCapability = {
25516
25633
  * `enabledDecoderNodes`, `enabledAudioNodes`, `remoteSourcingNodes`).
25517
25634
  * Each flag is optional in the patch: omit a flag to leave it unchanged,
25518
25635
  * pass `null` to reset it to the node default (`hub` → capable, every
25519
- * other node → not). Detection/decode/audio eligibility is derived from
25520
- * these flags across the cluster; changing them re-derives the enabled
25521
- * sets and reconciles dispatch immediately.
25636
+ * other node → not). Detection/audio eligibility is derived from these
25637
+ * flags across the cluster; changing them re-derives the enabled sets
25638
+ * and reconciles dispatch immediately. There is NO separate decode flag:
25639
+ * decode is always co-located with its frame consumer, so decode
25640
+ * eligibility IS detect eligibility.
25522
25641
  */
25523
25642
  setAgentCapabilities: method(external_exports.object({
25524
25643
  agentNodeId: external_exports.string(),
25525
25644
  detect: external_exports.boolean().nullable().optional(),
25526
- decode: external_exports.boolean().nullable().optional(),
25527
25645
  audio: external_exports.boolean().nullable().optional(),
25528
25646
  ingest: external_exports.boolean().nullable().optional()
25529
25647
  }), external_exports.object({ success: external_exports.literal(true) }), {
25530
25648
  kind: "mutation",
25531
25649
  auth: "admin"
25532
25650
  }),
25651
+ /**
25652
+ * Set (or clear) the operator override for the LAN host a cross-node
25653
+ * decoder dials to reach this node's restream. Pass a non-empty string to
25654
+ * override the auto-detected address (the runner's `CAMSTACK_HUB_URL`
25655
+ * default); pass `null` or an empty string to clear it and revert to
25656
+ * auto-detect. Applied on the next dispatch cycle — takes effect for new
25657
+ * cross-node attaches; existing attaches keep their current host until
25658
+ * re-dispatched.
25659
+ */
25660
+ setAgentReachableHost: method(external_exports.object({
25661
+ agentNodeId: external_exports.string(),
25662
+ reachableHost: external_exports.string().nullable()
25663
+ }), external_exports.object({ success: external_exports.literal(true) }), {
25664
+ kind: "mutation",
25665
+ auth: "admin"
25666
+ }),
25667
+ /**
25668
+ * Reset one node's pipeline to its hardware-aware defaults — the HONEST
25669
+ * reset (replaces the executor's legacy `resetToDefault`, which cleared a
25670
+ * dead persisted step-tree seed nothing in the live path read):
25671
+ * (a) strips every `modelId` pin from that node's
25672
+ * `agentSettings.addonDefaults` (cells revert to Auto — the node
25673
+ * resolves its own hardware-aware format default at runtime);
25674
+ * (b) clears per-camera step overrides scoped to that node
25675
+ * (`stepOverridesByAgent[node]` + the wholesale
25676
+ * `pipelineByAgent[node]` escape hatch);
25677
+ * (c) clears the executor-side per-device settings stores on that node
25678
+ * (`pipelineExecutor.clearDeviceOverrides`);
25679
+ * (d) hot-reloads every camera assigned to the node.
25680
+ *
25681
+ * Returns the EFFECTIVE post-reset object-detection model for the node
25682
+ * (the executor's pure hardware-aware default) so the UI can report what
25683
+ * will actually run — not a value that never reaches the live path.
25684
+ */
25685
+ resetNodePipelineDefaults: method(external_exports.object({ agentNodeId: external_exports.string() }), external_exports.object({
25686
+ success: external_exports.literal(true),
25687
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
25688
+ effectiveModelId: external_exports.string().nullable(),
25689
+ /** Number of cameras whose node-scoped overrides were cleared. */
25690
+ clearedCameraOverrides: external_exports.number()
25691
+ }), {
25692
+ kind: "mutation",
25693
+ auth: "admin"
25694
+ }),
25533
25695
  /** Read one camera's settings. Null when never touched (inherits agent defaults fully). */
25534
25696
  getCameraSettings: method(external_exports.object({ deviceId: external_exports.number() }), CameraPipelineSettingsSchema.nullable()),
25535
25697
  /** Set or clear the 3-state toggle for one (camera, addonId). Pass `enabled: null` to clear and revert to agent default. */
@@ -25621,33 +25783,107 @@ var pipelineOrchestratorCapability = {
25621
25783
  })
25622
25784
  }
25623
25785
  };
25624
- var RegisteredStreamSchema = external_exports.object({
25625
- streamId: external_exports.string(),
25626
- label: external_exports.string().optional(),
25627
- codec: external_exports.string(),
25628
- type: external_exports.enum(["video", "audio"]),
25629
- sourceUrl: external_exports.string()
25786
+ var ServerBootModeSchema = external_exports.enum([
25787
+ "workspace",
25788
+ "baked",
25789
+ "data-root"
25790
+ ]);
25791
+ var ServerUpdateStateSchema = external_exports.enum([
25792
+ "idle",
25793
+ "checking",
25794
+ "staging",
25795
+ "pending-restart",
25796
+ "awaiting-confirmation"
25797
+ ]);
25798
+ var ServerRollbackInfoSchema = external_exports.object({
25799
+ /** The version that failed (or was manually rolled back). */
25800
+ fromVersion: external_exports.string(),
25801
+ /** The version rolled back to; null = the baked seed. */
25802
+ toVersion: external_exports.string().nullable(),
25803
+ atMs: external_exports.number(),
25804
+ reason: external_exports.string()
25630
25805
  });
25631
- var ExposedResourceSchema = external_exports.object({
25632
- streamId: external_exports.string(),
25633
- format: external_exports.string(),
25634
- value: external_exports.string()
25806
+ var ServerPackageStatusSchema = external_exports.object({
25807
+ /** Root package name (`@camstack/server` on the hub). */
25808
+ packageName: external_exports.string(),
25809
+ /** Version of the code the running process ACTUALLY loaded. */
25810
+ runningVersion: external_exports.string().nullable(),
25811
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
25812
+ nodeRuntimeVersion: external_exports.string().nullable(),
25813
+ /** Active data-dir root version; null when booted from seed/workspace. */
25814
+ activeVersion: external_exports.string().nullable(),
25815
+ /** N-1 version kept for rollback; null when no previous version exists. */
25816
+ previousVersion: external_exports.string().nullable(),
25817
+ /** Version of the immutable baked seed closure (image fallback). */
25818
+ seedVersion: external_exports.string().nullable(),
25819
+ /** Latest registry version from the most recent check (null = never checked). */
25820
+ latestVersion: external_exports.string().nullable(),
25821
+ updateAvailable: external_exports.boolean(),
25822
+ bootMode: ServerBootModeSchema,
25823
+ updateState: ServerUpdateStateSchema,
25824
+ /** Version staged + awaiting its probation boot, when one is pending. */
25825
+ pendingVersion: external_exports.string().nullable(),
25826
+ /** Set when the last freshly-activated version failed its boot health-check. */
25827
+ rolledBack: ServerRollbackInfoSchema.nullable(),
25828
+ /**
25829
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
25830
+ * hub is running from the baked seed (or workspace) while installed data-dir
25831
+ * versions are being IGNORED. Surfaced as a warning in the UI.
25832
+ */
25833
+ stateFileCorrupt: external_exports.boolean(),
25834
+ lastCheckedAtMs: external_exports.number().nullable()
25835
+ });
25836
+ var ServerUpdateCheckResultSchema = external_exports.object({
25837
+ packageName: external_exports.string(),
25838
+ runningVersion: external_exports.string().nullable(),
25839
+ latestVersion: external_exports.string().nullable(),
25840
+ updateAvailable: external_exports.boolean(),
25841
+ checkedAtMs: external_exports.number(),
25842
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
25843
+ error: external_exports.string().nullable()
25635
25844
  });
25636
- var restreamerCapability = {
25637
- name: "restreamer",
25845
+ var ServerUpdateActionResultSchema = external_exports.object({
25846
+ accepted: external_exports.boolean(),
25847
+ targetVersion: external_exports.string().nullable(),
25848
+ /** True when a graceful restart was scheduled to apply the change. */
25849
+ restarting: external_exports.boolean(),
25850
+ message: external_exports.string()
25851
+ });
25852
+ var serverManagementCapability = {
25853
+ name: "server-management",
25638
25854
  scope: "system",
25639
- mode: "collection",
25640
- internal: true,
25855
+ mode: "singleton",
25641
25856
  methods: {
25642
- registerDevice: method(external_exports.object({
25643
- deviceId: external_exports.number(),
25644
- streams: external_exports.array(RegisteredStreamSchema).readonly()
25645
- }), external_exports.void(), { kind: "mutation" }),
25646
- unregisterDevice: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.void(), { kind: "mutation" }),
25647
- getExposedResources: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.array(ExposedResourceSchema).readonly())
25857
+ getServerPackageStatus: method(external_exports.void(), ServerPackageStatusSchema, { auth: "admin" }),
25858
+ checkServerUpdate: method(external_exports.void(), ServerUpdateCheckResultSchema, {
25859
+ kind: "mutation",
25860
+ auth: "admin"
25861
+ }),
25862
+ applyServerUpdate: method(external_exports.object({
25863
+ /** Explicit target version; omitted = latest from the registry. */
25864
+ version: external_exports.string().optional()
25865
+ }), ServerUpdateActionResultSchema, {
25866
+ kind: "mutation",
25867
+ auth: "admin"
25868
+ }),
25869
+ rollbackServerUpdate: method(external_exports.void(), ServerUpdateActionResultSchema, {
25870
+ kind: "mutation",
25871
+ auth: "admin"
25872
+ }),
25873
+ /**
25874
+ * Plain process restart of the node's root process — no version change.
25875
+ * The supervisor (docker restart policy / launchd / Electron main)
25876
+ * relaunches and the starter loads the SAME active version. Refused while
25877
+ * a stage is in flight or a version is already staged awaiting restart
25878
+ * (use apply/rollback instead, so the pending version is not skipped).
25879
+ */
25880
+ restartServer: method(external_exports.void(), ServerUpdateActionResultSchema, {
25881
+ kind: "mutation",
25882
+ auth: "admin"
25883
+ })
25648
25884
  },
25649
25885
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
25650
- mount: { kind: "skip" }
25886
+ mount: { kind: "server-provided" }
25651
25887
  };
25652
25888
  var QueryFilterSchema = external_exports.object({
25653
25889
  where: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
@@ -25873,20 +26109,6 @@ var snapshotCapability = {
25873
26109
  kind: "poll"
25874
26110
  }
25875
26111
  };
25876
- var snapshotProviderCapability = {
25877
- name: "snapshot-provider",
25878
- scope: "system",
25879
- mode: "collection",
25880
- methods: {
25881
- supportsDevice: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.boolean()),
25882
- getSnapshot: method(external_exports.object({
25883
- deviceId: external_exports.number(),
25884
- streamId: external_exports.string().optional()
25885
- }), SnapshotImageSchema.nullable())
25886
- },
25887
- /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
25888
- mount: { kind: "custom" }
25889
- };
25890
26112
  var SsoBridgeClaimsSchema = external_exports.object({
25891
26113
  userId: external_exports.string(),
25892
26114
  username: external_exports.string(),
@@ -26220,6 +26442,20 @@ var userPasskeysCapability = {
26220
26442
  kind: "mutation",
26221
26443
  access: "view"
26222
26444
  }),
26445
+ beginDiscoverableAuthentication: method(external_exports.object({}), external_exports.object({ optionsJSON: external_exports.record(external_exports.string(), external_exports.unknown()) }), {
26446
+ kind: "mutation",
26447
+ access: "view"
26448
+ }),
26449
+ finishDiscoverableAuthentication: method(external_exports.object({
26450
+ /** AuthenticationResponseJSON from the browser. */
26451
+ response: external_exports.record(external_exports.string(), external_exports.unknown())
26452
+ }), external_exports.object({
26453
+ verified: external_exports.boolean(),
26454
+ userId: external_exports.string().nullable()
26455
+ }), {
26456
+ kind: "mutation",
26457
+ access: "view"
26458
+ }),
26223
26459
  listPasskeys: method(external_exports.object({ userId: external_exports.string() }), external_exports.array(PasskeySummarySchema), { auth: "admin" }),
26224
26460
  removePasskey: method(external_exports.object({
26225
26461
  userId: external_exports.string(),
@@ -26228,6 +26464,15 @@ var userPasskeysCapability = {
26228
26464
  kind: "mutation",
26229
26465
  auth: "admin",
26230
26466
  access: "delete"
26467
+ }),
26468
+ getSecondFactorPreference: method(external_exports.object({ userId: external_exports.string() }), external_exports.object({ enabled: external_exports.boolean() }), { auth: "admin" }),
26469
+ setSecondFactorPreference: method(external_exports.object({
26470
+ userId: external_exports.string(),
26471
+ enabled: external_exports.boolean()
26472
+ }), external_exports.object({ success: external_exports.literal(true) }), {
26473
+ kind: "mutation",
26474
+ auth: "admin",
26475
+ access: "create"
26231
26476
  })
26232
26477
  }
26233
26478
  };
@@ -26291,49 +26536,6 @@ var webrtcClientHintsSchema = external_exports.object({
26291
26536
  /** Hard tier override; takes precedence over scoring when registered. */
26292
26537
  prefersTier: external_exports.string().optional()
26293
26538
  }).partial();
26294
- var webrtcCapability = {
26295
- name: "webrtc",
26296
- scope: "system",
26297
- mode: "collection",
26298
- internal: true,
26299
- methods: {
26300
- handleOffer: method(external_exports.object({
26301
- streamId: external_exports.string(),
26302
- sdpOffer: external_exports.string()
26303
- }), external_exports.string(), { kind: "mutation" }),
26304
- supportsStream: method(external_exports.object({ streamId: external_exports.string() }), external_exports.boolean()),
26305
- registerStream: method(external_exports.object({
26306
- streamId: external_exports.string(),
26307
- codec: external_exports.string()
26308
- }), external_exports.void(), { kind: "mutation" }),
26309
- unregisterStream: method(external_exports.object({ streamId: external_exports.string() }), external_exports.void(), { kind: "mutation" }),
26310
- /**
26311
- * Two-step server-offer signaling. `hints` is optional — providers
26312
- * that don't care about adaptive source selection ignore it.
26313
- */
26314
- createSession: method(external_exports.object({
26315
- streamId: external_exports.string(),
26316
- hints: webrtcClientHintsSchema.optional()
26317
- }), external_exports.object({
26318
- sessionId: external_exports.string(),
26319
- sdpOffer: external_exports.string()
26320
- }), { kind: "mutation" }),
26321
- handleAnswer: method(external_exports.object({
26322
- sessionId: external_exports.string(),
26323
- sdpAnswer: external_exports.string()
26324
- }), external_exports.void(), { kind: "mutation" }),
26325
- closeSession: method(external_exports.object({ sessionId: external_exports.string() }), external_exports.void(), { kind: "mutation" }),
26326
- /**
26327
- * Whether this provider supports adaptive bitrate for the given stream.
26328
- * Currently always false — adaptive selection is one-shot at session
26329
- * start, not in-session encoder switching. Phase 5 plans to layer
26330
- * encoder-driven adaptation on top.
26331
- */
26332
- hasAdaptiveBitrate: method(external_exports.object({ streamId: external_exports.string() }), external_exports.boolean())
26333
- },
26334
- /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
26335
- mount: { kind: "skip" }
26336
- };
26337
26539
  var WebrtcStreamTargetSchema = external_exports.discriminatedUnion("kind", [
26338
26540
  external_exports.object({ kind: external_exports.literal("adaptive") }),
26339
26541
  external_exports.object({
@@ -26576,7 +26778,7 @@ var webrtcSessionCapability = {
26576
26778
  }).nullable() }))
26577
26779
  },
26578
26780
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
26579
- mount: { kind: "custom" }
26781
+ mount: { kind: "server-provided" }
26580
26782
  };
26581
26783
  var AccessoriesStatusSchema = external_exports.object({
26582
26784
  /** All accessory children of the parent. */
@@ -26882,7 +27084,15 @@ var FrameworkPackageStatusSchema = external_exports.object({
26882
27084
  latestVersion: external_exports.string().nullable(),
26883
27085
  hasUpdate: external_exports.boolean(),
26884
27086
  /** Optional manifest description for the row tooltip. */
26885
- description: external_exports.string().optional()
27087
+ description: external_exports.string().optional(),
27088
+ /**
27089
+ * Content build-id (md5 of the resolved `dist/` tree) of the code the hub
27090
+ * ACTUALLY loaded. Framework packages ship code changes without always
27091
+ * bumping `currentVersion`, so semver alone hides "same version, new code".
27092
+ * `null` when the dist can't be hashed (not installed / empty). The admin-UI
27093
+ * surfaces this so a stale-code hub is visible even at an unchanged version.
27094
+ */
27095
+ buildId: external_exports.string().nullable()
26886
27096
  });
26887
27097
  var LogStreamEntrySchema = external_exports.object({
26888
27098
  timestamp: external_exports.string(),
@@ -27168,7 +27378,7 @@ var addonsCapability = {
27168
27378
  }), LogStreamEntrySchema, { kind: "subscription" })
27169
27379
  },
27170
27380
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
27171
- mount: { kind: "service-backed" }
27381
+ mount: { kind: "server-provided" }
27172
27382
  };
27173
27383
  var buttonCapability = {
27174
27384
  name: "button",
@@ -27513,7 +27723,7 @@ var integrationsCapability = {
27513
27723
  })
27514
27724
  },
27515
27725
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
27516
- mount: { kind: "service-backed" }
27726
+ mount: { kind: "server-provided" }
27517
27727
  };
27518
27728
  var IntercomAbilitySchema = external_exports.object({
27519
27729
  /** Codecs accepted by firmware, in preference order. Driver-authored strings. */
@@ -28053,7 +28263,7 @@ var networkQualityCapability = {
28053
28263
  }), external_exports.void(), { kind: "mutation" })
28054
28264
  },
28055
28265
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
28056
- mount: { kind: "service-backed" }
28266
+ mount: { kind: "server-provided" }
28057
28267
  };
28058
28268
  var TopologyServiceSchema = external_exports.object({
28059
28269
  addonId: external_exports.string(),
@@ -28082,6 +28292,10 @@ var TopologyCategorySchema = external_exports.object({
28082
28292
  healthy: external_exports.number(),
28083
28293
  addons: external_exports.array(TopologyCategoryAddonSchema).readonly()
28084
28294
  });
28295
+ var TopologyRootPackageSchema = external_exports.object({
28296
+ name: external_exports.string(),
28297
+ version: external_exports.string()
28298
+ });
28085
28299
  var TopologyNodeSchema = external_exports.object({
28086
28300
  id: external_exports.string(),
28087
28301
  name: external_exports.string(),
@@ -28105,7 +28319,8 @@ var TopologyNodeSchema = external_exports.object({
28105
28319
  status: external_exports.string()
28106
28320
  })).readonly(),
28107
28321
  processes: external_exports.array(TopologyProcessSchema).readonly(),
28108
- categories: external_exports.array(TopologyCategorySchema).readonly()
28322
+ categories: external_exports.array(TopologyCategorySchema).readonly(),
28323
+ rootPackage: TopologyRootPackageSchema.nullable()
28109
28324
  });
28110
28325
  var CapUsageEdgeSchema = external_exports.object({
28111
28326
  callerAddonId: external_exports.string(),
@@ -28218,7 +28433,7 @@ var nodesCapability = {
28218
28433
  })
28219
28434
  },
28220
28435
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
28221
- mount: { kind: "service-backed" }
28436
+ mount: { kind: "server-provided" }
28222
28437
  };
28223
28438
  var OsdOverlayKindEnum = external_exports.enum([
28224
28439
  "text",
@@ -28841,7 +29056,7 @@ var systemCapability = {
28841
29056
  })
28842
29057
  },
28843
29058
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
28844
- mount: { kind: "service-backed" }
29059
+ mount: { kind: "server-provided" }
28845
29060
  };
28846
29061
  var ToastSchema = external_exports.object({
28847
29062
  title: external_exports.string(),
@@ -28863,7 +29078,7 @@ var toastCapability = {
28863
29078
  mode: "singleton",
28864
29079
  methods: { onToast: method(external_exports.void(), ToastSchema, { kind: "subscription" }) },
28865
29080
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
28866
- mount: { kind: "service-backed" }
29081
+ mount: { kind: "server-provided" }
28867
29082
  };
28868
29083
  var UserSummarySchema = external_exports.object({
28869
29084
  id: external_exports.string(),
@@ -31085,6 +31300,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
31085
31300
  addonId: null,
31086
31301
  access: "create"
31087
31302
  },
31303
+ "loginMethod.getLoginMethods": {
31304
+ capName: "login-method",
31305
+ capScope: "system",
31306
+ addonId: null,
31307
+ access: "view"
31308
+ },
31088
31309
  "mediaPlayer.next": {
31089
31310
  capName: "media-player",
31090
31311
  capScope: "device",
@@ -31715,23 +31936,23 @@ var METHOD_ACCESS_MAP = Object.freeze({
31715
31936
  addonId: null,
31716
31937
  access: "create"
31717
31938
  },
31718
- "pipelineExecutor.deleteModel": {
31939
+ "pipelineExecutor.clearDeviceOverrides": {
31719
31940
  capName: "pipeline-executor",
31720
31941
  capScope: "system",
31721
31942
  addonId: null,
31722
31943
  access: "delete"
31723
31944
  },
31724
- "pipelineExecutor.deleteTemplate": {
31945
+ "pipelineExecutor.deleteModel": {
31725
31946
  capName: "pipeline-executor",
31726
31947
  capScope: "system",
31727
31948
  addonId: null,
31728
31949
  access: "delete"
31729
31950
  },
31730
- "pipelineExecutor.detect": {
31951
+ "pipelineExecutor.deleteTemplate": {
31731
31952
  capName: "pipeline-executor",
31732
31953
  capScope: "system",
31733
31954
  addonId: null,
31734
- access: "view"
31955
+ access: "delete"
31735
31956
  },
31736
31957
  "pipelineExecutor.downloadModel": {
31737
31958
  capName: "pipeline-executor",
@@ -31925,13 +32146,13 @@ var METHOD_ACCESS_MAP = Object.freeze({
31925
32146
  addonId: null,
31926
32147
  access: "create"
31927
32148
  },
31928
- "pipelineOrchestrator.assignAudio": {
31929
- capName: "pipeline-orchestrator",
32149
+ "pipelineExecutor.validatePipeline": {
32150
+ capName: "pipeline-executor",
31930
32151
  capScope: "system",
31931
32152
  addonId: null,
31932
- access: "create"
32153
+ access: "view"
31933
32154
  },
31934
- "pipelineOrchestrator.assignDecoder": {
32155
+ "pipelineOrchestrator.assignAudio": {
31935
32156
  capName: "pipeline-orchestrator",
31936
32157
  capScope: "system",
31937
32158
  addonId: null,
@@ -32015,19 +32236,13 @@ var METHOD_ACCESS_MAP = Object.freeze({
32015
32236
  addonId: null,
32016
32237
  access: "view"
32017
32238
  },
32018
- "pipelineOrchestrator.getDecoderAssignment": {
32019
- capName: "pipeline-orchestrator",
32020
- capScope: "system",
32021
- addonId: null,
32022
- access: "view"
32023
- },
32024
- "pipelineOrchestrator.getDecoderAssignments": {
32239
+ "pipelineOrchestrator.getGlobalMetrics": {
32025
32240
  capName: "pipeline-orchestrator",
32026
32241
  capScope: "system",
32027
32242
  addonId: null,
32028
32243
  access: "view"
32029
32244
  },
32030
- "pipelineOrchestrator.getGlobalMetrics": {
32245
+ "pipelineOrchestrator.getIngestOwner": {
32031
32246
  capName: "pipeline-orchestrator",
32032
32247
  capScope: "system",
32033
32248
  addonId: null,
@@ -32069,6 +32284,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
32069
32284
  addonId: null,
32070
32285
  access: "delete"
32071
32286
  },
32287
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
32288
+ capName: "pipeline-orchestrator",
32289
+ capScope: "system",
32290
+ addonId: null,
32291
+ access: "delete"
32292
+ },
32072
32293
  "pipelineOrchestrator.resolvePipeline": {
32073
32294
  capName: "pipeline-orchestrator",
32074
32295
  capScope: "system",
@@ -32105,37 +32326,37 @@ var METHOD_ACCESS_MAP = Object.freeze({
32105
32326
  addonId: null,
32106
32327
  access: "create"
32107
32328
  },
32108
- "pipelineOrchestrator.setCameraPipelineForAgent": {
32329
+ "pipelineOrchestrator.setAgentReachableHost": {
32109
32330
  capName: "pipeline-orchestrator",
32110
32331
  capScope: "system",
32111
32332
  addonId: null,
32112
32333
  access: "create"
32113
32334
  },
32114
- "pipelineOrchestrator.setCameraStepOverride": {
32335
+ "pipelineOrchestrator.setCameraPipelineForAgent": {
32115
32336
  capName: "pipeline-orchestrator",
32116
32337
  capScope: "system",
32117
32338
  addonId: null,
32118
32339
  access: "create"
32119
32340
  },
32120
- "pipelineOrchestrator.setCameraStepToggle": {
32341
+ "pipelineOrchestrator.setCameraStepOverride": {
32121
32342
  capName: "pipeline-orchestrator",
32122
32343
  capScope: "system",
32123
32344
  addonId: null,
32124
32345
  access: "create"
32125
32346
  },
32126
- "pipelineOrchestrator.setCapabilityBinding": {
32347
+ "pipelineOrchestrator.setCameraStepToggle": {
32127
32348
  capName: "pipeline-orchestrator",
32128
32349
  capScope: "system",
32129
32350
  addonId: null,
32130
32351
  access: "create"
32131
32352
  },
32132
- "pipelineOrchestrator.unassignAudio": {
32353
+ "pipelineOrchestrator.setCapabilityBinding": {
32133
32354
  capName: "pipeline-orchestrator",
32134
32355
  capScope: "system",
32135
32356
  addonId: null,
32136
32357
  access: "create"
32137
32358
  },
32138
- "pipelineOrchestrator.unassignDecoder": {
32359
+ "pipelineOrchestrator.unassignAudio": {
32139
32360
  capName: "pipeline-orchestrator",
32140
32361
  capScope: "system",
32141
32362
  addonId: null,
@@ -32435,33 +32656,45 @@ var METHOD_ACCESS_MAP = Object.freeze({
32435
32656
  addonId: null,
32436
32657
  access: "create"
32437
32658
  },
32438
- "restreamer.getExposedResources": {
32439
- capName: "restreamer",
32659
+ "scriptRunner.run": {
32660
+ capName: "script-runner",
32661
+ capScope: "device",
32662
+ addonId: null,
32663
+ access: "create"
32664
+ },
32665
+ "scriptRunner.stop": {
32666
+ capName: "script-runner",
32667
+ capScope: "device",
32668
+ addonId: null,
32669
+ access: "create"
32670
+ },
32671
+ "serverManagement.applyServerUpdate": {
32672
+ capName: "server-management",
32440
32673
  capScope: "system",
32441
32674
  addonId: null,
32442
- access: "view"
32675
+ access: "create"
32443
32676
  },
32444
- "restreamer.registerDevice": {
32445
- capName: "restreamer",
32677
+ "serverManagement.checkServerUpdate": {
32678
+ capName: "server-management",
32446
32679
  capScope: "system",
32447
32680
  addonId: null,
32448
32681
  access: "create"
32449
32682
  },
32450
- "restreamer.unregisterDevice": {
32451
- capName: "restreamer",
32683
+ "serverManagement.getServerPackageStatus": {
32684
+ capName: "server-management",
32452
32685
  capScope: "system",
32453
32686
  addonId: null,
32454
- access: "delete"
32687
+ access: "view"
32455
32688
  },
32456
- "scriptRunner.run": {
32457
- capName: "script-runner",
32458
- capScope: "device",
32689
+ "serverManagement.restartServer": {
32690
+ capName: "server-management",
32691
+ capScope: "system",
32459
32692
  addonId: null,
32460
32693
  access: "create"
32461
32694
  },
32462
- "scriptRunner.stop": {
32463
- capName: "script-runner",
32464
- capScope: "device",
32695
+ "serverManagement.rollbackServerUpdate": {
32696
+ capName: "server-management",
32697
+ capScope: "system",
32465
32698
  addonId: null,
32466
32699
  access: "create"
32467
32700
  },
@@ -32555,18 +32788,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
32555
32788
  addonId: null,
32556
32789
  access: "create"
32557
32790
  },
32558
- "snapshotProvider.getSnapshot": {
32559
- capName: "snapshot-provider",
32560
- capScope: "system",
32561
- addonId: null,
32562
- access: "view"
32563
- },
32564
- "snapshotProvider.supportsDevice": {
32565
- capName: "snapshot-provider",
32566
- capScope: "system",
32567
- addonId: null,
32568
- access: "view"
32569
- },
32570
32791
  "ssoBridge.signBridgeToken": {
32571
32792
  capName: "sso-bridge",
32572
32793
  capScope: "system",
@@ -32993,30 +33214,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
32993
33214
  addonId: null,
32994
33215
  access: "view"
32995
33216
  },
32996
- "streamingEngine.getStreamUrl": {
32997
- capName: "streaming-engine",
32998
- capScope: "system",
32999
- addonId: null,
33000
- access: "view"
33001
- },
33002
- "streamingEngine.listStreams": {
33003
- capName: "streaming-engine",
33004
- capScope: "system",
33005
- addonId: null,
33006
- access: "view"
33007
- },
33008
- "streamingEngine.registerStream": {
33009
- capName: "streaming-engine",
33010
- capScope: "system",
33011
- addonId: null,
33012
- access: "create"
33013
- },
33014
- "streamingEngine.unregisterStream": {
33015
- capName: "streaming-engine",
33016
- capScope: "system",
33017
- addonId: null,
33018
- access: "delete"
33019
- },
33020
33217
  "streamParams.getConfigSchema": {
33021
33218
  capName: "stream-params",
33022
33219
  capScope: "device",
@@ -33263,6 +33460,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33263
33460
  addonId: null,
33264
33461
  access: "view"
33265
33462
  },
33463
+ "userPasskeys.beginDiscoverableAuthentication": {
33464
+ capName: "user-passkeys",
33465
+ capScope: "system",
33466
+ addonId: null,
33467
+ access: "view"
33468
+ },
33266
33469
  "userPasskeys.beginRegistration": {
33267
33470
  capName: "user-passkeys",
33268
33471
  capScope: "system",
@@ -33275,12 +33478,24 @@ var METHOD_ACCESS_MAP = Object.freeze({
33275
33478
  addonId: null,
33276
33479
  access: "view"
33277
33480
  },
33481
+ "userPasskeys.finishDiscoverableAuthentication": {
33482
+ capName: "user-passkeys",
33483
+ capScope: "system",
33484
+ addonId: null,
33485
+ access: "view"
33486
+ },
33278
33487
  "userPasskeys.finishRegistration": {
33279
33488
  capName: "user-passkeys",
33280
33489
  capScope: "system",
33281
33490
  addonId: null,
33282
33491
  access: "create"
33283
33492
  },
33493
+ "userPasskeys.getSecondFactorPreference": {
33494
+ capName: "user-passkeys",
33495
+ capScope: "system",
33496
+ addonId: null,
33497
+ access: "view"
33498
+ },
33284
33499
  "userPasskeys.listPasskeys": {
33285
33500
  capName: "user-passkeys",
33286
33501
  capScope: "system",
@@ -33293,6 +33508,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33293
33508
  addonId: null,
33294
33509
  access: "delete"
33295
33510
  },
33511
+ "userPasskeys.setSecondFactorPreference": {
33512
+ capName: "user-passkeys",
33513
+ capScope: "system",
33514
+ addonId: null,
33515
+ access: "create"
33516
+ },
33296
33517
  "vacuumControl.locate": {
33297
33518
  capName: "vacuum-control",
33298
33519
  capScope: "device",
@@ -33365,6 +33586,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
33365
33586
  addonId: null,
33366
33587
  access: "view"
33367
33588
  },
33589
+ "viewerUi.getStaticDir": {
33590
+ capName: "viewer-ui",
33591
+ capScope: "system",
33592
+ addonId: null,
33593
+ access: "view"
33594
+ },
33595
+ "viewerUi.getVersion": {
33596
+ capName: "viewer-ui",
33597
+ capScope: "system",
33598
+ addonId: null,
33599
+ access: "view"
33600
+ },
33368
33601
  "waterHeater.setAway": {
33369
33602
  capName: "water-heater",
33370
33603
  capScope: "device",
@@ -33383,54 +33616,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
33383
33616
  addonId: null,
33384
33617
  access: "create"
33385
33618
  },
33386
- "webrtc.closeSession": {
33387
- capName: "webrtc",
33388
- capScope: "system",
33389
- addonId: null,
33390
- access: "create"
33391
- },
33392
- "webrtc.createSession": {
33393
- capName: "webrtc",
33394
- capScope: "system",
33395
- addonId: null,
33396
- access: "create"
33397
- },
33398
- "webrtc.handleAnswer": {
33399
- capName: "webrtc",
33400
- capScope: "system",
33401
- addonId: null,
33402
- access: "create"
33403
- },
33404
- "webrtc.handleOffer": {
33405
- capName: "webrtc",
33406
- capScope: "system",
33407
- addonId: null,
33408
- access: "create"
33409
- },
33410
- "webrtc.hasAdaptiveBitrate": {
33411
- capName: "webrtc",
33412
- capScope: "system",
33413
- addonId: null,
33414
- access: "view"
33415
- },
33416
- "webrtc.registerStream": {
33417
- capName: "webrtc",
33418
- capScope: "system",
33419
- addonId: null,
33420
- access: "create"
33421
- },
33422
- "webrtc.supportsStream": {
33423
- capName: "webrtc",
33424
- capScope: "system",
33425
- addonId: null,
33426
- access: "view"
33427
- },
33428
- "webrtc.unregisterStream": {
33429
- capName: "webrtc",
33430
- capScope: "system",
33431
- addonId: null,
33432
- access: "delete"
33433
- },
33434
33619
  "webrtcSession.addIceCandidate": {
33435
33620
  capName: "webrtc-session",
33436
33621
  capScope: "device",