@camstack/addon-provider-onvif 1.1.21 → 1.1.22

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.
Files changed (3) hide show
  1. package/dist/addon.js +303 -87
  2. package/dist/addon.mjs +303 -87
  3. package/package.json +4 -1
package/dist/addon.js CHANGED
@@ -4631,7 +4631,7 @@ function _instanceof(cls, params = {}) {
4631
4631
  return inst;
4632
4632
  }
4633
4633
  //#endregion
4634
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4634
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4635
4635
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4636
4636
  EventCategory["SystemBoot"] = "system.boot";
4637
4637
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5352,10 +5352,6 @@ function hydrateField(field, values) {
5352
5352
  };
5353
5353
  }
5354
5354
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5355
- if (field.type === "password") return {
5356
- ...field,
5357
- value: ""
5358
- };
5359
5355
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5360
5356
  return {
5361
5357
  ...field,
@@ -6739,6 +6735,9 @@ function method(input, output, options) {
6739
6735
  timeoutMs: options?.timeoutMs
6740
6736
  };
6741
6737
  }
6738
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6739
+ var VersionOutputSchema$1 = object({ version: string() });
6740
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6742
6741
  var StaticDirOutputSchema = object({ staticDir: string() });
6743
6742
  var VersionOutputSchema = object({ version: string() });
6744
6743
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -10481,7 +10480,7 @@ var BoundingBoxSchema = object({
10481
10480
  w: number(),
10482
10481
  h: number()
10483
10482
  });
10484
- var SpatialDetectionSchema = object({
10483
+ object({
10485
10484
  class: string(),
10486
10485
  originalClass: string(),
10487
10486
  score: number(),
@@ -10672,11 +10671,6 @@ var PipelineSchemaSchema = object({
10672
10671
  selectedEngine: PipelineEngineChoiceSchema,
10673
10672
  slots: array(PipelineSlotSchemaSchema).readonly()
10674
10673
  });
10675
- var DetectorOutputSchema = object({
10676
- detections: array(SpatialDetectionSchema).readonly(),
10677
- inferenceMs: number(),
10678
- modelId: string()
10679
- });
10680
10674
  var EngineProvisioningSchema = object({
10681
10675
  runtimeId: _enum([
10682
10676
  "onnx",
@@ -10801,7 +10795,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10801
10795
  auth: "admin"
10802
10796
  }), method(object({ nodeId: string() }), object({
10803
10797
  success: literal(true),
10804
- regeneratedModelId: string().nullable()
10798
+ clearedDevices: number()
10805
10799
  }), {
10806
10800
  kind: "mutation",
10807
10801
  auth: "admin"
@@ -10822,10 +10816,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10822
10816
  modelId: string(),
10823
10817
  format: ModelFormatSchema$1
10824
10818
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10825
- addonId: string(),
10826
- frame: FrameInputSchema,
10827
- config: record(string(), unknown()).optional()
10828
- }), DetectorOutputSchema), method(object({
10829
10819
  engine: PipelineEngineChoiceSchema.optional(),
10830
10820
  steps: array(PipelineStepInputSchema).min(1),
10831
10821
  frame: FrameInputSchema.optional(),
@@ -12814,7 +12804,9 @@ var AddonPageDeclarationSchema$1 = object({
12814
12804
  icon: string(),
12815
12805
  path: string(),
12816
12806
  remoteName: string(),
12817
- bundle: string()
12807
+ bundle: string(),
12808
+ section: string().optional(),
12809
+ sectionLabel: string().optional()
12818
12810
  });
12819
12811
  var AddonPageInfoSchema = object({
12820
12812
  addonId: string(),
@@ -12854,7 +12846,18 @@ var AddonPageDeclarationSchema = object({
12854
12846
  * the static-file route can compute an mtime-based cache-buster URL
12855
12847
  * without a separate filesystem stat.
12856
12848
  */
12857
- bundle: string()
12849
+ bundle: string(),
12850
+ /**
12851
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12852
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12853
+ * Any OTHER string creates (or joins) a custom section rendered after
12854
+ * the built-in groups; its label comes from `sectionLabel` (first
12855
+ * declaration wins), falling back to the id. Absent → the legacy
12856
+ * "Addon Pages" group.
12857
+ */
12858
+ section: string().optional(),
12859
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12860
+ sectionLabel: string().optional()
12858
12861
  });
12859
12862
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12860
12863
  var AddonHttpRouteSchema = object({
@@ -13070,6 +13073,17 @@ var WidgetMetadataSchema = object({
13070
13073
  deviceContext: boolean().default(false),
13071
13074
  integrationContext: boolean().default(false)
13072
13075
  }),
13076
+ /**
13077
+ * Loadable BEFORE authentication. The normal widget registry listing
13078
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
13079
+ * (the login page) cannot discover a widget through it. A widget that
13080
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
13081
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
13082
+ * login-method contribution channel (see `login-method.cap.ts`) rather
13083
+ * than the authenticated registry, and its bundle is served by the
13084
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
13085
+ */
13086
+ preAuth: boolean().optional().default(false),
13073
13087
  /** Dashboard placement HINTS (operator can override per instance). */
13074
13088
  defaultSize: WidgetSizeEnum.default("md"),
13075
13089
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -13371,6 +13385,66 @@ method(object({
13371
13385
  password: string()
13372
13386
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
13373
13387
  /**
13388
+ * `login-method` — collection cap through which auth addons contribute
13389
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
13390
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
13391
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
13392
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
13393
+ * procedure aggregates them for the unauthenticated login page.
13394
+ *
13395
+ * A contribution is a discriminated union on `kind`:
13396
+ *
13397
+ * - `redirect` — a declarative button. The login page renders a generic
13398
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
13399
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
13400
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
13401
+ * login page needs NO change.
13402
+ *
13403
+ * - `widget` — a Module-Federation widget the login page mounts (via
13404
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
13405
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
13406
+ * addon bundle. The referenced widget also declares `preAuth: true` in
13407
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
13408
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
13409
+ *
13410
+ * Every contribution carries a `stage`:
13411
+ * - `primary` — shown on the first credentials screen (OIDC /
13412
+ * magic-link buttons; a future usernameless passkey).
13413
+ * - `second-factor` — shown AFTER the password leg, gated on the
13414
+ * returned `factors` (passkey-as-2FA today).
13415
+ *
13416
+ * `mount: skip` — the cap is read server-side by the core auth router
13417
+ * (`registry.getCollection('login-method')`), never mounted as its own
13418
+ * tRPC router.
13419
+ */
13420
+ /** When a login method renders in the two-phase login flow. */
13421
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
13422
+ /** One login-method contribution — redirect button OR pre-auth widget. */
13423
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
13424
+ kind: literal("redirect"),
13425
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
13426
+ id: string(),
13427
+ /** Operator-facing button label. */
13428
+ label: string(),
13429
+ /** lucide-react icon name. */
13430
+ icon: string().optional(),
13431
+ /** Addon-owned HTTP route the button navigates to (GET). */
13432
+ startUrl: string(),
13433
+ stage: LoginStageEnum
13434
+ }), object({
13435
+ kind: literal("widget"),
13436
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
13437
+ id: string(),
13438
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
13439
+ addonId: string(),
13440
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
13441
+ bundle: string(),
13442
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
13443
+ remote: WidgetRemoteSchema,
13444
+ stage: LoginStageEnum
13445
+ })]);
13446
+ method(_void(), array(LoginMethodContributionSchema).readonly());
13447
+ /**
13374
13448
  * Orchestrator-side destination metadata. The orchestrator computes
13375
13449
  * `id = <addonId>:<subId>` from its provider lookup so consumers
13376
13450
  * (admin UI, restore flow) see one canonical key.
@@ -15688,7 +15762,12 @@ var AgentPipelineSettingsSchema = object({
15688
15762
  detectWeight: number().positive().optional(),
15689
15763
  /** Node is eligible to run the detection pipeline (decode + inference). */
15690
15764
  detect: boolean().optional(),
15691
- /** Node is eligible to host decoder sessions. */
15765
+ /**
15766
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15767
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15768
+ * the schema ONLY so persisted stores written before the removal still
15769
+ * parse — no code reads it and no write path emits it.
15770
+ */
15692
15771
  decode: boolean().optional(),
15693
15772
  /** Node is eligible to run audio-analyzer sessions. */
15694
15773
  audio: boolean().optional(),
@@ -15749,25 +15828,6 @@ var PipelineAssignmentSchema = object({
15749
15828
  assignedAt: number()
15750
15829
  });
15751
15830
  /**
15752
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15753
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15754
- * → co-located with pipeline → capacity).
15755
- */
15756
- var DecoderAssignmentSchema = object({
15757
- deviceId: number(),
15758
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15759
- decoderNodeId: string(),
15760
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15761
- pinned: boolean(),
15762
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15763
- reason: _enum([
15764
- "manual",
15765
- "co-located",
15766
- "capacity",
15767
- "hardware-affinity"
15768
- ])
15769
- });
15770
- /**
15771
15831
  * Per-agent load summary surfaced to the load balancer + dashboards.
15772
15832
  * Aggregated from each runner's `getLocalLoad` cap call.
15773
15833
  */
@@ -15973,15 +16033,6 @@ method(object({
15973
16033
  }), method(_void(), IngestOwnerSchema), method(object({
15974
16034
  deviceId: number(),
15975
16035
  nodeId: string()
15976
- }), _void(), {
15977
- kind: "mutation",
15978
- auth: "admin"
15979
- }), method(object({ deviceId: number() }), _void(), {
15980
- kind: "mutation",
15981
- auth: "admin"
15982
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15983
- deviceId: number(),
15984
- nodeId: string()
15985
16036
  }), object({ success: literal(true) }), {
15986
16037
  kind: "mutation",
15987
16038
  auth: "admin"
@@ -16000,10 +16051,7 @@ method(object({
16000
16051
  nodeId: string(),
16001
16052
  pinned: boolean(),
16002
16053
  assignedAt: number()
16003
- }))), method(object({
16004
- deviceId: number(),
16005
- pipelineNodeId: string().optional()
16006
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
16054
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
16007
16055
  nodeId: string(),
16008
16056
  settings: AgentPipelineSettingsSchema
16009
16057
  })).readonly()), method(object({
@@ -16033,7 +16081,6 @@ method(object({
16033
16081
  }), method(object({
16034
16082
  agentNodeId: string(),
16035
16083
  detect: boolean().nullable().optional(),
16036
- decode: boolean().nullable().optional(),
16037
16084
  audio: boolean().nullable().optional(),
16038
16085
  ingest: boolean().nullable().optional()
16039
16086
  }), object({ success: literal(true) }), {
@@ -16045,6 +16092,15 @@ method(object({
16045
16092
  }), object({ success: literal(true) }), {
16046
16093
  kind: "mutation",
16047
16094
  auth: "admin"
16095
+ }), method(object({ agentNodeId: string() }), object({
16096
+ success: literal(true),
16097
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
16098
+ effectiveModelId: string().nullable(),
16099
+ /** Number of cameras whose node-scoped overrides were cleared. */
16100
+ clearedCameraOverrides: number()
16101
+ }), {
16102
+ kind: "mutation",
16103
+ auth: "admin"
16048
16104
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
16049
16105
  deviceId: number(),
16050
16106
  addonId: string(),
@@ -16090,6 +16146,131 @@ method(object({
16090
16146
  auth: "admin"
16091
16147
  });
16092
16148
  /**
16149
+ * server-management — per-NODE singleton capability for a node's ROOT
16150
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
16151
+ * agents).
16152
+ *
16153
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
16154
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
16155
+ * version describes the node. Updates install into
16156
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
16157
+ * starter (probation boot + auto-rollback to N-1).
16158
+ *
16159
+ * Providers:
16160
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
16161
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
16162
+ * unpinned calls.
16163
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
16164
+ * the synthetic `agent-runtime` addonId and declared in the agent's
16165
+ * `$hub.registerNode` manifest.
16166
+ *
16167
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
16168
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
16169
+ * SDK) routes the call to that node's provider via the standard remote
16170
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
16171
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
16172
+ *
16173
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
16174
+ */
16175
+ /**
16176
+ * Where the running hub's code was loaded from:
16177
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
16178
+ * plain resolution and runtime updates are refused.
16179
+ * - `baked` — the immutable image seed closure (no data-dir root active).
16180
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
16181
+ */
16182
+ var ServerBootModeSchema = _enum([
16183
+ "workspace",
16184
+ "baked",
16185
+ "data-root"
16186
+ ]);
16187
+ /**
16188
+ * Update lifecycle state:
16189
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
16190
+ * - `pending-restart` — a version is staged and the node has NOT yet
16191
+ * restarted onto it (still running the OLD version).
16192
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
16193
+ * (it is the active probation boot) and is waiting to confirm boot-health.
16194
+ * Apply/rollback are refused in this state and the node must NOT be
16195
+ * manually restarted, or the probation boot auto-rolls-back.
16196
+ */
16197
+ var ServerUpdateStateSchema = _enum([
16198
+ "idle",
16199
+ "checking",
16200
+ "staging",
16201
+ "pending-restart",
16202
+ "awaiting-confirmation"
16203
+ ]);
16204
+ var ServerRollbackInfoSchema = object({
16205
+ /** The version that failed (or was manually rolled back). */
16206
+ fromVersion: string(),
16207
+ /** The version rolled back to; null = the baked seed. */
16208
+ toVersion: string().nullable(),
16209
+ atMs: number(),
16210
+ reason: string()
16211
+ });
16212
+ var ServerPackageStatusSchema = object({
16213
+ /** Root package name (`@camstack/server` on the hub). */
16214
+ packageName: string(),
16215
+ /** Version of the code the running process ACTUALLY loaded. */
16216
+ runningVersion: string().nullable(),
16217
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
16218
+ nodeRuntimeVersion: string().nullable(),
16219
+ /** Active data-dir root version; null when booted from seed/workspace. */
16220
+ activeVersion: string().nullable(),
16221
+ /** N-1 version kept for rollback; null when no previous version exists. */
16222
+ previousVersion: string().nullable(),
16223
+ /** Version of the immutable baked seed closure (image fallback). */
16224
+ seedVersion: string().nullable(),
16225
+ /** Latest registry version from the most recent check (null = never checked). */
16226
+ latestVersion: string().nullable(),
16227
+ updateAvailable: boolean(),
16228
+ bootMode: ServerBootModeSchema,
16229
+ updateState: ServerUpdateStateSchema,
16230
+ /** Version staged + awaiting its probation boot, when one is pending. */
16231
+ pendingVersion: string().nullable(),
16232
+ /** Set when the last freshly-activated version failed its boot health-check. */
16233
+ rolledBack: ServerRollbackInfoSchema.nullable(),
16234
+ /**
16235
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
16236
+ * hub is running from the baked seed (or workspace) while installed data-dir
16237
+ * versions are being IGNORED. Surfaced as a warning in the UI.
16238
+ */
16239
+ stateFileCorrupt: boolean(),
16240
+ lastCheckedAtMs: number().nullable()
16241
+ });
16242
+ var ServerUpdateCheckResultSchema = object({
16243
+ packageName: string(),
16244
+ runningVersion: string().nullable(),
16245
+ latestVersion: string().nullable(),
16246
+ updateAvailable: boolean(),
16247
+ checkedAtMs: number(),
16248
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
16249
+ error: string().nullable()
16250
+ });
16251
+ var ServerUpdateActionResultSchema = object({
16252
+ accepted: boolean(),
16253
+ targetVersion: string().nullable(),
16254
+ /** True when a graceful restart was scheduled to apply the change. */
16255
+ restarting: boolean(),
16256
+ message: string()
16257
+ });
16258
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
16259
+ kind: "mutation",
16260
+ auth: "admin"
16261
+ }), method(object({
16262
+ /** Explicit target version; omitted = latest from the registry. */
16263
+ version: string().optional() }), ServerUpdateActionResultSchema, {
16264
+ kind: "mutation",
16265
+ auth: "admin"
16266
+ }), method(_void(), ServerUpdateActionResultSchema, {
16267
+ kind: "mutation",
16268
+ auth: "admin"
16269
+ }), method(_void(), ServerUpdateActionResultSchema, {
16270
+ kind: "mutation",
16271
+ auth: "admin"
16272
+ });
16273
+ /**
16093
16274
  * Query filter for settings-store collections.
16094
16275
  */
16095
16276
  var QueryFilterSchema = object({
@@ -18119,6 +18300,16 @@ var TopologyCategorySchema = object({
18119
18300
  healthy: number(),
18120
18301
  addons: array(TopologyCategoryAddonSchema).readonly()
18121
18302
  });
18303
+ /**
18304
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
18305
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
18306
+ * version visibility for the Server management surface. Nullable: offline
18307
+ * rows and pre-phase-2 nodes report none.
18308
+ */
18309
+ var TopologyRootPackageSchema = object({
18310
+ name: string(),
18311
+ version: string()
18312
+ });
18122
18313
  var TopologyNodeSchema = object({
18123
18314
  id: string(),
18124
18315
  name: string(),
@@ -18142,7 +18333,8 @@ var TopologyNodeSchema = object({
18142
18333
  status: string()
18143
18334
  })).readonly(),
18144
18335
  processes: array(TopologyProcessSchema).readonly(),
18145
- categories: array(TopologyCategorySchema).readonly()
18336
+ categories: array(TopologyCategorySchema).readonly(),
18337
+ rootPackage: TopologyRootPackageSchema.nullable()
18146
18338
  });
18147
18339
  var CapUsageEdgeSchema = object({
18148
18340
  callerAddonId: string(),
@@ -20984,6 +21176,12 @@ Object.freeze({
20984
21176
  addonId: null,
20985
21177
  access: "create"
20986
21178
  },
21179
+ "loginMethod.getLoginMethods": {
21180
+ capName: "login-method",
21181
+ capScope: "system",
21182
+ addonId: null,
21183
+ access: "view"
21184
+ },
20987
21185
  "mediaPlayer.next": {
20988
21186
  capName: "media-player",
20989
21187
  capScope: "device",
@@ -21614,23 +21812,23 @@ Object.freeze({
21614
21812
  addonId: null,
21615
21813
  access: "create"
21616
21814
  },
21617
- "pipelineExecutor.deleteModel": {
21815
+ "pipelineExecutor.clearDeviceOverrides": {
21618
21816
  capName: "pipeline-executor",
21619
21817
  capScope: "system",
21620
21818
  addonId: null,
21621
21819
  access: "delete"
21622
21820
  },
21623
- "pipelineExecutor.deleteTemplate": {
21821
+ "pipelineExecutor.deleteModel": {
21624
21822
  capName: "pipeline-executor",
21625
21823
  capScope: "system",
21626
21824
  addonId: null,
21627
21825
  access: "delete"
21628
21826
  },
21629
- "pipelineExecutor.detect": {
21827
+ "pipelineExecutor.deleteTemplate": {
21630
21828
  capName: "pipeline-executor",
21631
21829
  capScope: "system",
21632
21830
  addonId: null,
21633
- access: "view"
21831
+ access: "delete"
21634
21832
  },
21635
21833
  "pipelineExecutor.downloadModel": {
21636
21834
  capName: "pipeline-executor",
@@ -21776,12 +21974,6 @@ Object.freeze({
21776
21974
  addonId: null,
21777
21975
  access: "create"
21778
21976
  },
21779
- "pipelineExecutor.resetToDefault": {
21780
- capName: "pipeline-executor",
21781
- capScope: "system",
21782
- addonId: null,
21783
- access: "delete"
21784
- },
21785
21977
  "pipelineExecutor.runAudioTest": {
21786
21978
  capName: "pipeline-executor",
21787
21979
  capScope: "system",
@@ -21842,12 +22034,6 @@ Object.freeze({
21842
22034
  addonId: null,
21843
22035
  access: "create"
21844
22036
  },
21845
- "pipelineOrchestrator.assignDecoder": {
21846
- capName: "pipeline-orchestrator",
21847
- capScope: "system",
21848
- addonId: null,
21849
- access: "create"
21850
- },
21851
22037
  "pipelineOrchestrator.assignPipeline": {
21852
22038
  capName: "pipeline-orchestrator",
21853
22039
  capScope: "system",
@@ -21926,18 +22112,6 @@ Object.freeze({
21926
22112
  addonId: null,
21927
22113
  access: "view"
21928
22114
  },
21929
- "pipelineOrchestrator.getDecoderAssignment": {
21930
- capName: "pipeline-orchestrator",
21931
- capScope: "system",
21932
- addonId: null,
21933
- access: "view"
21934
- },
21935
- "pipelineOrchestrator.getDecoderAssignments": {
21936
- capName: "pipeline-orchestrator",
21937
- capScope: "system",
21938
- addonId: null,
21939
- access: "view"
21940
- },
21941
22115
  "pipelineOrchestrator.getGlobalMetrics": {
21942
22116
  capName: "pipeline-orchestrator",
21943
22117
  capScope: "system",
@@ -21986,6 +22160,12 @@ Object.freeze({
21986
22160
  addonId: null,
21987
22161
  access: "delete"
21988
22162
  },
22163
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
22164
+ capName: "pipeline-orchestrator",
22165
+ capScope: "system",
22166
+ addonId: null,
22167
+ access: "delete"
22168
+ },
21989
22169
  "pipelineOrchestrator.resolvePipeline": {
21990
22170
  capName: "pipeline-orchestrator",
21991
22171
  capScope: "system",
@@ -22058,12 +22238,6 @@ Object.freeze({
22058
22238
  addonId: null,
22059
22239
  access: "create"
22060
22240
  },
22061
- "pipelineOrchestrator.unassignDecoder": {
22062
- capName: "pipeline-orchestrator",
22063
- capScope: "system",
22064
- addonId: null,
22065
- access: "create"
22066
- },
22067
22241
  "pipelineOrchestrator.unassignPipeline": {
22068
22242
  capName: "pipeline-orchestrator",
22069
22243
  capScope: "system",
@@ -22370,6 +22544,36 @@ Object.freeze({
22370
22544
  addonId: null,
22371
22545
  access: "create"
22372
22546
  },
22547
+ "serverManagement.applyServerUpdate": {
22548
+ capName: "server-management",
22549
+ capScope: "system",
22550
+ addonId: null,
22551
+ access: "create"
22552
+ },
22553
+ "serverManagement.checkServerUpdate": {
22554
+ capName: "server-management",
22555
+ capScope: "system",
22556
+ addonId: null,
22557
+ access: "create"
22558
+ },
22559
+ "serverManagement.getServerPackageStatus": {
22560
+ capName: "server-management",
22561
+ capScope: "system",
22562
+ addonId: null,
22563
+ access: "view"
22564
+ },
22565
+ "serverManagement.restartServer": {
22566
+ capName: "server-management",
22567
+ capScope: "system",
22568
+ addonId: null,
22569
+ access: "create"
22570
+ },
22571
+ "serverManagement.rollbackServerUpdate": {
22572
+ capName: "server-management",
22573
+ capScope: "system",
22574
+ addonId: null,
22575
+ access: "create"
22576
+ },
22373
22577
  "settingsStore.count": {
22374
22578
  capName: "settings-store",
22375
22579
  capScope: "system",
@@ -23234,6 +23438,18 @@ Object.freeze({
23234
23438
  addonId: null,
23235
23439
  access: "view"
23236
23440
  },
23441
+ "viewerUi.getStaticDir": {
23442
+ capName: "viewer-ui",
23443
+ capScope: "system",
23444
+ addonId: null,
23445
+ access: "view"
23446
+ },
23447
+ "viewerUi.getVersion": {
23448
+ capName: "viewer-ui",
23449
+ capScope: "system",
23450
+ addonId: null,
23451
+ access: "view"
23452
+ },
23237
23453
  "waterHeater.setAway": {
23238
23454
  capName: "water-heater",
23239
23455
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4632,7 +4632,7 @@ function _instanceof(cls, params = {}) {
4632
4632
  return inst;
4633
4633
  }
4634
4634
  //#endregion
4635
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4635
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4636
4636
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4637
4637
  EventCategory["SystemBoot"] = "system.boot";
4638
4638
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5353,10 +5353,6 @@ function hydrateField(field, values) {
5353
5353
  };
5354
5354
  }
5355
5355
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5356
- if (field.type === "password") return {
5357
- ...field,
5358
- value: ""
5359
- };
5360
5356
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5361
5357
  return {
5362
5358
  ...field,
@@ -6740,6 +6736,9 @@ function method(input, output, options) {
6740
6736
  timeoutMs: options?.timeoutMs
6741
6737
  };
6742
6738
  }
6739
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6740
+ var VersionOutputSchema$1 = object({ version: string() });
6741
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6743
6742
  var StaticDirOutputSchema = object({ staticDir: string() });
6744
6743
  var VersionOutputSchema = object({ version: string() });
6745
6744
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -10482,7 +10481,7 @@ var BoundingBoxSchema = object({
10482
10481
  w: number(),
10483
10482
  h: number()
10484
10483
  });
10485
- var SpatialDetectionSchema = object({
10484
+ object({
10486
10485
  class: string(),
10487
10486
  originalClass: string(),
10488
10487
  score: number(),
@@ -10673,11 +10672,6 @@ var PipelineSchemaSchema = object({
10673
10672
  selectedEngine: PipelineEngineChoiceSchema,
10674
10673
  slots: array(PipelineSlotSchemaSchema).readonly()
10675
10674
  });
10676
- var DetectorOutputSchema = object({
10677
- detections: array(SpatialDetectionSchema).readonly(),
10678
- inferenceMs: number(),
10679
- modelId: string()
10680
- });
10681
10675
  var EngineProvisioningSchema = object({
10682
10676
  runtimeId: _enum([
10683
10677
  "onnx",
@@ -10802,7 +10796,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10802
10796
  auth: "admin"
10803
10797
  }), method(object({ nodeId: string() }), object({
10804
10798
  success: literal(true),
10805
- regeneratedModelId: string().nullable()
10799
+ clearedDevices: number()
10806
10800
  }), {
10807
10801
  kind: "mutation",
10808
10802
  auth: "admin"
@@ -10823,10 +10817,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10823
10817
  modelId: string(),
10824
10818
  format: ModelFormatSchema$1
10825
10819
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10826
- addonId: string(),
10827
- frame: FrameInputSchema,
10828
- config: record(string(), unknown()).optional()
10829
- }), DetectorOutputSchema), method(object({
10830
10820
  engine: PipelineEngineChoiceSchema.optional(),
10831
10821
  steps: array(PipelineStepInputSchema).min(1),
10832
10822
  frame: FrameInputSchema.optional(),
@@ -12815,7 +12805,9 @@ var AddonPageDeclarationSchema$1 = object({
12815
12805
  icon: string(),
12816
12806
  path: string(),
12817
12807
  remoteName: string(),
12818
- bundle: string()
12808
+ bundle: string(),
12809
+ section: string().optional(),
12810
+ sectionLabel: string().optional()
12819
12811
  });
12820
12812
  var AddonPageInfoSchema = object({
12821
12813
  addonId: string(),
@@ -12855,7 +12847,18 @@ var AddonPageDeclarationSchema = object({
12855
12847
  * the static-file route can compute an mtime-based cache-buster URL
12856
12848
  * without a separate filesystem stat.
12857
12849
  */
12858
- bundle: string()
12850
+ bundle: string(),
12851
+ /**
12852
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12853
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12854
+ * Any OTHER string creates (or joins) a custom section rendered after
12855
+ * the built-in groups; its label comes from `sectionLabel` (first
12856
+ * declaration wins), falling back to the id. Absent → the legacy
12857
+ * "Addon Pages" group.
12858
+ */
12859
+ section: string().optional(),
12860
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12861
+ sectionLabel: string().optional()
12859
12862
  });
12860
12863
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12861
12864
  var AddonHttpRouteSchema = object({
@@ -13071,6 +13074,17 @@ var WidgetMetadataSchema = object({
13071
13074
  deviceContext: boolean().default(false),
13072
13075
  integrationContext: boolean().default(false)
13073
13076
  }),
13077
+ /**
13078
+ * Loadable BEFORE authentication. The normal widget registry listing
13079
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
13080
+ * (the login page) cannot discover a widget through it. A widget that
13081
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
13082
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
13083
+ * login-method contribution channel (see `login-method.cap.ts`) rather
13084
+ * than the authenticated registry, and its bundle is served by the
13085
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
13086
+ */
13087
+ preAuth: boolean().optional().default(false),
13074
13088
  /** Dashboard placement HINTS (operator can override per instance). */
13075
13089
  defaultSize: WidgetSizeEnum.default("md"),
13076
13090
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -13372,6 +13386,66 @@ method(object({
13372
13386
  password: string()
13373
13387
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
13374
13388
  /**
13389
+ * `login-method` — collection cap through which auth addons contribute
13390
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
13391
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
13392
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
13393
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
13394
+ * procedure aggregates them for the unauthenticated login page.
13395
+ *
13396
+ * A contribution is a discriminated union on `kind`:
13397
+ *
13398
+ * - `redirect` — a declarative button. The login page renders a generic
13399
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
13400
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
13401
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
13402
+ * login page needs NO change.
13403
+ *
13404
+ * - `widget` — a Module-Federation widget the login page mounts (via
13405
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
13406
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
13407
+ * addon bundle. The referenced widget also declares `preAuth: true` in
13408
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
13409
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
13410
+ *
13411
+ * Every contribution carries a `stage`:
13412
+ * - `primary` — shown on the first credentials screen (OIDC /
13413
+ * magic-link buttons; a future usernameless passkey).
13414
+ * - `second-factor` — shown AFTER the password leg, gated on the
13415
+ * returned `factors` (passkey-as-2FA today).
13416
+ *
13417
+ * `mount: skip` — the cap is read server-side by the core auth router
13418
+ * (`registry.getCollection('login-method')`), never mounted as its own
13419
+ * tRPC router.
13420
+ */
13421
+ /** When a login method renders in the two-phase login flow. */
13422
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
13423
+ /** One login-method contribution — redirect button OR pre-auth widget. */
13424
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
13425
+ kind: literal("redirect"),
13426
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
13427
+ id: string(),
13428
+ /** Operator-facing button label. */
13429
+ label: string(),
13430
+ /** lucide-react icon name. */
13431
+ icon: string().optional(),
13432
+ /** Addon-owned HTTP route the button navigates to (GET). */
13433
+ startUrl: string(),
13434
+ stage: LoginStageEnum
13435
+ }), object({
13436
+ kind: literal("widget"),
13437
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
13438
+ id: string(),
13439
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
13440
+ addonId: string(),
13441
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
13442
+ bundle: string(),
13443
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
13444
+ remote: WidgetRemoteSchema,
13445
+ stage: LoginStageEnum
13446
+ })]);
13447
+ method(_void(), array(LoginMethodContributionSchema).readonly());
13448
+ /**
13375
13449
  * Orchestrator-side destination metadata. The orchestrator computes
13376
13450
  * `id = <addonId>:<subId>` from its provider lookup so consumers
13377
13451
  * (admin UI, restore flow) see one canonical key.
@@ -15689,7 +15763,12 @@ var AgentPipelineSettingsSchema = object({
15689
15763
  detectWeight: number().positive().optional(),
15690
15764
  /** Node is eligible to run the detection pipeline (decode + inference). */
15691
15765
  detect: boolean().optional(),
15692
- /** Node is eligible to host decoder sessions. */
15766
+ /**
15767
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15768
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15769
+ * the schema ONLY so persisted stores written before the removal still
15770
+ * parse — no code reads it and no write path emits it.
15771
+ */
15693
15772
  decode: boolean().optional(),
15694
15773
  /** Node is eligible to run audio-analyzer sessions. */
15695
15774
  audio: boolean().optional(),
@@ -15750,25 +15829,6 @@ var PipelineAssignmentSchema = object({
15750
15829
  assignedAt: number()
15751
15830
  });
15752
15831
  /**
15753
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15754
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15755
- * → co-located with pipeline → capacity).
15756
- */
15757
- var DecoderAssignmentSchema = object({
15758
- deviceId: number(),
15759
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15760
- decoderNodeId: string(),
15761
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15762
- pinned: boolean(),
15763
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15764
- reason: _enum([
15765
- "manual",
15766
- "co-located",
15767
- "capacity",
15768
- "hardware-affinity"
15769
- ])
15770
- });
15771
- /**
15772
15832
  * Per-agent load summary surfaced to the load balancer + dashboards.
15773
15833
  * Aggregated from each runner's `getLocalLoad` cap call.
15774
15834
  */
@@ -15974,15 +16034,6 @@ method(object({
15974
16034
  }), method(_void(), IngestOwnerSchema), method(object({
15975
16035
  deviceId: number(),
15976
16036
  nodeId: string()
15977
- }), _void(), {
15978
- kind: "mutation",
15979
- auth: "admin"
15980
- }), method(object({ deviceId: number() }), _void(), {
15981
- kind: "mutation",
15982
- auth: "admin"
15983
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15984
- deviceId: number(),
15985
- nodeId: string()
15986
16037
  }), object({ success: literal(true) }), {
15987
16038
  kind: "mutation",
15988
16039
  auth: "admin"
@@ -16001,10 +16052,7 @@ method(object({
16001
16052
  nodeId: string(),
16002
16053
  pinned: boolean(),
16003
16054
  assignedAt: number()
16004
- }))), method(object({
16005
- deviceId: number(),
16006
- pipelineNodeId: string().optional()
16007
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
16055
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
16008
16056
  nodeId: string(),
16009
16057
  settings: AgentPipelineSettingsSchema
16010
16058
  })).readonly()), method(object({
@@ -16034,7 +16082,6 @@ method(object({
16034
16082
  }), method(object({
16035
16083
  agentNodeId: string(),
16036
16084
  detect: boolean().nullable().optional(),
16037
- decode: boolean().nullable().optional(),
16038
16085
  audio: boolean().nullable().optional(),
16039
16086
  ingest: boolean().nullable().optional()
16040
16087
  }), object({ success: literal(true) }), {
@@ -16046,6 +16093,15 @@ method(object({
16046
16093
  }), object({ success: literal(true) }), {
16047
16094
  kind: "mutation",
16048
16095
  auth: "admin"
16096
+ }), method(object({ agentNodeId: string() }), object({
16097
+ success: literal(true),
16098
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
16099
+ effectiveModelId: string().nullable(),
16100
+ /** Number of cameras whose node-scoped overrides were cleared. */
16101
+ clearedCameraOverrides: number()
16102
+ }), {
16103
+ kind: "mutation",
16104
+ auth: "admin"
16049
16105
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
16050
16106
  deviceId: number(),
16051
16107
  addonId: string(),
@@ -16091,6 +16147,131 @@ method(object({
16091
16147
  auth: "admin"
16092
16148
  });
16093
16149
  /**
16150
+ * server-management — per-NODE singleton capability for a node's ROOT
16151
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
16152
+ * agents).
16153
+ *
16154
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
16155
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
16156
+ * version describes the node. Updates install into
16157
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
16158
+ * starter (probation boot + auto-rollback to N-1).
16159
+ *
16160
+ * Providers:
16161
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
16162
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
16163
+ * unpinned calls.
16164
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
16165
+ * the synthetic `agent-runtime` addonId and declared in the agent's
16166
+ * `$hub.registerNode` manifest.
16167
+ *
16168
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
16169
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
16170
+ * SDK) routes the call to that node's provider via the standard remote
16171
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
16172
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
16173
+ *
16174
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
16175
+ */
16176
+ /**
16177
+ * Where the running hub's code was loaded from:
16178
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
16179
+ * plain resolution and runtime updates are refused.
16180
+ * - `baked` — the immutable image seed closure (no data-dir root active).
16181
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
16182
+ */
16183
+ var ServerBootModeSchema = _enum([
16184
+ "workspace",
16185
+ "baked",
16186
+ "data-root"
16187
+ ]);
16188
+ /**
16189
+ * Update lifecycle state:
16190
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
16191
+ * - `pending-restart` — a version is staged and the node has NOT yet
16192
+ * restarted onto it (still running the OLD version).
16193
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
16194
+ * (it is the active probation boot) and is waiting to confirm boot-health.
16195
+ * Apply/rollback are refused in this state and the node must NOT be
16196
+ * manually restarted, or the probation boot auto-rolls-back.
16197
+ */
16198
+ var ServerUpdateStateSchema = _enum([
16199
+ "idle",
16200
+ "checking",
16201
+ "staging",
16202
+ "pending-restart",
16203
+ "awaiting-confirmation"
16204
+ ]);
16205
+ var ServerRollbackInfoSchema = object({
16206
+ /** The version that failed (or was manually rolled back). */
16207
+ fromVersion: string(),
16208
+ /** The version rolled back to; null = the baked seed. */
16209
+ toVersion: string().nullable(),
16210
+ atMs: number(),
16211
+ reason: string()
16212
+ });
16213
+ var ServerPackageStatusSchema = object({
16214
+ /** Root package name (`@camstack/server` on the hub). */
16215
+ packageName: string(),
16216
+ /** Version of the code the running process ACTUALLY loaded. */
16217
+ runningVersion: string().nullable(),
16218
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
16219
+ nodeRuntimeVersion: string().nullable(),
16220
+ /** Active data-dir root version; null when booted from seed/workspace. */
16221
+ activeVersion: string().nullable(),
16222
+ /** N-1 version kept for rollback; null when no previous version exists. */
16223
+ previousVersion: string().nullable(),
16224
+ /** Version of the immutable baked seed closure (image fallback). */
16225
+ seedVersion: string().nullable(),
16226
+ /** Latest registry version from the most recent check (null = never checked). */
16227
+ latestVersion: string().nullable(),
16228
+ updateAvailable: boolean(),
16229
+ bootMode: ServerBootModeSchema,
16230
+ updateState: ServerUpdateStateSchema,
16231
+ /** Version staged + awaiting its probation boot, when one is pending. */
16232
+ pendingVersion: string().nullable(),
16233
+ /** Set when the last freshly-activated version failed its boot health-check. */
16234
+ rolledBack: ServerRollbackInfoSchema.nullable(),
16235
+ /**
16236
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
16237
+ * hub is running from the baked seed (or workspace) while installed data-dir
16238
+ * versions are being IGNORED. Surfaced as a warning in the UI.
16239
+ */
16240
+ stateFileCorrupt: boolean(),
16241
+ lastCheckedAtMs: number().nullable()
16242
+ });
16243
+ var ServerUpdateCheckResultSchema = object({
16244
+ packageName: string(),
16245
+ runningVersion: string().nullable(),
16246
+ latestVersion: string().nullable(),
16247
+ updateAvailable: boolean(),
16248
+ checkedAtMs: number(),
16249
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
16250
+ error: string().nullable()
16251
+ });
16252
+ var ServerUpdateActionResultSchema = object({
16253
+ accepted: boolean(),
16254
+ targetVersion: string().nullable(),
16255
+ /** True when a graceful restart was scheduled to apply the change. */
16256
+ restarting: boolean(),
16257
+ message: string()
16258
+ });
16259
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
16260
+ kind: "mutation",
16261
+ auth: "admin"
16262
+ }), method(object({
16263
+ /** Explicit target version; omitted = latest from the registry. */
16264
+ version: string().optional() }), ServerUpdateActionResultSchema, {
16265
+ kind: "mutation",
16266
+ auth: "admin"
16267
+ }), method(_void(), ServerUpdateActionResultSchema, {
16268
+ kind: "mutation",
16269
+ auth: "admin"
16270
+ }), method(_void(), ServerUpdateActionResultSchema, {
16271
+ kind: "mutation",
16272
+ auth: "admin"
16273
+ });
16274
+ /**
16094
16275
  * Query filter for settings-store collections.
16095
16276
  */
16096
16277
  var QueryFilterSchema = object({
@@ -18120,6 +18301,16 @@ var TopologyCategorySchema = object({
18120
18301
  healthy: number(),
18121
18302
  addons: array(TopologyCategoryAddonSchema).readonly()
18122
18303
  });
18304
+ /**
18305
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
18306
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
18307
+ * version visibility for the Server management surface. Nullable: offline
18308
+ * rows and pre-phase-2 nodes report none.
18309
+ */
18310
+ var TopologyRootPackageSchema = object({
18311
+ name: string(),
18312
+ version: string()
18313
+ });
18123
18314
  var TopologyNodeSchema = object({
18124
18315
  id: string(),
18125
18316
  name: string(),
@@ -18143,7 +18334,8 @@ var TopologyNodeSchema = object({
18143
18334
  status: string()
18144
18335
  })).readonly(),
18145
18336
  processes: array(TopologyProcessSchema).readonly(),
18146
- categories: array(TopologyCategorySchema).readonly()
18337
+ categories: array(TopologyCategorySchema).readonly(),
18338
+ rootPackage: TopologyRootPackageSchema.nullable()
18147
18339
  });
18148
18340
  var CapUsageEdgeSchema = object({
18149
18341
  callerAddonId: string(),
@@ -20985,6 +21177,12 @@ Object.freeze({
20985
21177
  addonId: null,
20986
21178
  access: "create"
20987
21179
  },
21180
+ "loginMethod.getLoginMethods": {
21181
+ capName: "login-method",
21182
+ capScope: "system",
21183
+ addonId: null,
21184
+ access: "view"
21185
+ },
20988
21186
  "mediaPlayer.next": {
20989
21187
  capName: "media-player",
20990
21188
  capScope: "device",
@@ -21615,23 +21813,23 @@ Object.freeze({
21615
21813
  addonId: null,
21616
21814
  access: "create"
21617
21815
  },
21618
- "pipelineExecutor.deleteModel": {
21816
+ "pipelineExecutor.clearDeviceOverrides": {
21619
21817
  capName: "pipeline-executor",
21620
21818
  capScope: "system",
21621
21819
  addonId: null,
21622
21820
  access: "delete"
21623
21821
  },
21624
- "pipelineExecutor.deleteTemplate": {
21822
+ "pipelineExecutor.deleteModel": {
21625
21823
  capName: "pipeline-executor",
21626
21824
  capScope: "system",
21627
21825
  addonId: null,
21628
21826
  access: "delete"
21629
21827
  },
21630
- "pipelineExecutor.detect": {
21828
+ "pipelineExecutor.deleteTemplate": {
21631
21829
  capName: "pipeline-executor",
21632
21830
  capScope: "system",
21633
21831
  addonId: null,
21634
- access: "view"
21832
+ access: "delete"
21635
21833
  },
21636
21834
  "pipelineExecutor.downloadModel": {
21637
21835
  capName: "pipeline-executor",
@@ -21777,12 +21975,6 @@ Object.freeze({
21777
21975
  addonId: null,
21778
21976
  access: "create"
21779
21977
  },
21780
- "pipelineExecutor.resetToDefault": {
21781
- capName: "pipeline-executor",
21782
- capScope: "system",
21783
- addonId: null,
21784
- access: "delete"
21785
- },
21786
21978
  "pipelineExecutor.runAudioTest": {
21787
21979
  capName: "pipeline-executor",
21788
21980
  capScope: "system",
@@ -21843,12 +22035,6 @@ Object.freeze({
21843
22035
  addonId: null,
21844
22036
  access: "create"
21845
22037
  },
21846
- "pipelineOrchestrator.assignDecoder": {
21847
- capName: "pipeline-orchestrator",
21848
- capScope: "system",
21849
- addonId: null,
21850
- access: "create"
21851
- },
21852
22038
  "pipelineOrchestrator.assignPipeline": {
21853
22039
  capName: "pipeline-orchestrator",
21854
22040
  capScope: "system",
@@ -21927,18 +22113,6 @@ Object.freeze({
21927
22113
  addonId: null,
21928
22114
  access: "view"
21929
22115
  },
21930
- "pipelineOrchestrator.getDecoderAssignment": {
21931
- capName: "pipeline-orchestrator",
21932
- capScope: "system",
21933
- addonId: null,
21934
- access: "view"
21935
- },
21936
- "pipelineOrchestrator.getDecoderAssignments": {
21937
- capName: "pipeline-orchestrator",
21938
- capScope: "system",
21939
- addonId: null,
21940
- access: "view"
21941
- },
21942
22116
  "pipelineOrchestrator.getGlobalMetrics": {
21943
22117
  capName: "pipeline-orchestrator",
21944
22118
  capScope: "system",
@@ -21987,6 +22161,12 @@ Object.freeze({
21987
22161
  addonId: null,
21988
22162
  access: "delete"
21989
22163
  },
22164
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
22165
+ capName: "pipeline-orchestrator",
22166
+ capScope: "system",
22167
+ addonId: null,
22168
+ access: "delete"
22169
+ },
21990
22170
  "pipelineOrchestrator.resolvePipeline": {
21991
22171
  capName: "pipeline-orchestrator",
21992
22172
  capScope: "system",
@@ -22059,12 +22239,6 @@ Object.freeze({
22059
22239
  addonId: null,
22060
22240
  access: "create"
22061
22241
  },
22062
- "pipelineOrchestrator.unassignDecoder": {
22063
- capName: "pipeline-orchestrator",
22064
- capScope: "system",
22065
- addonId: null,
22066
- access: "create"
22067
- },
22068
22242
  "pipelineOrchestrator.unassignPipeline": {
22069
22243
  capName: "pipeline-orchestrator",
22070
22244
  capScope: "system",
@@ -22371,6 +22545,36 @@ Object.freeze({
22371
22545
  addonId: null,
22372
22546
  access: "create"
22373
22547
  },
22548
+ "serverManagement.applyServerUpdate": {
22549
+ capName: "server-management",
22550
+ capScope: "system",
22551
+ addonId: null,
22552
+ access: "create"
22553
+ },
22554
+ "serverManagement.checkServerUpdate": {
22555
+ capName: "server-management",
22556
+ capScope: "system",
22557
+ addonId: null,
22558
+ access: "create"
22559
+ },
22560
+ "serverManagement.getServerPackageStatus": {
22561
+ capName: "server-management",
22562
+ capScope: "system",
22563
+ addonId: null,
22564
+ access: "view"
22565
+ },
22566
+ "serverManagement.restartServer": {
22567
+ capName: "server-management",
22568
+ capScope: "system",
22569
+ addonId: null,
22570
+ access: "create"
22571
+ },
22572
+ "serverManagement.rollbackServerUpdate": {
22573
+ capName: "server-management",
22574
+ capScope: "system",
22575
+ addonId: null,
22576
+ access: "create"
22577
+ },
22374
22578
  "settingsStore.count": {
22375
22579
  capName: "settings-store",
22376
22580
  capScope: "system",
@@ -23235,6 +23439,18 @@ Object.freeze({
23235
23439
  addonId: null,
23236
23440
  access: "view"
23237
23441
  },
23442
+ "viewerUi.getStaticDir": {
23443
+ capName: "viewer-ui",
23444
+ capScope: "system",
23445
+ addonId: null,
23446
+ access: "view"
23447
+ },
23448
+ "viewerUi.getVersion": {
23449
+ capName: "viewer-ui",
23450
+ capScope: "system",
23451
+ addonId: null,
23452
+ access: "view"
23453
+ },
23238
23454
  "waterHeater.setAway": {
23239
23455
  capName: "water-heater",
23240
23456
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-onvif",
3
- "version": "1.1.21",
3
+ "version": "1.1.22",
4
4
  "description": "ONVIF camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",
@@ -47,6 +47,9 @@
47
47
  }
48
48
  ]
49
49
  }
50
+ ],
51
+ "runtimeDependencies": [
52
+ "onvif"
50
53
  ]
51
54
  },
52
55
  "files": [