@camstack/addon-provider-hikvision 1.1.20 → 1.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -4635,7 +4635,7 @@ function _instanceof(cls, params = {}) {
4635
4635
  return inst;
4636
4636
  }
4637
4637
  //#endregion
4638
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4638
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4639
4639
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4640
4640
  EventCategory["SystemBoot"] = "system.boot";
4641
4641
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5356,10 +5356,6 @@ function hydrateField(field, values) {
5356
5356
  };
5357
5357
  }
5358
5358
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5359
- if (field.type === "password") return {
5360
- ...field,
5361
- value: ""
5362
- };
5363
5359
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5364
5360
  return {
5365
5361
  ...field,
@@ -6747,6 +6743,9 @@ function method(input, output, options) {
6747
6743
  function event(data) {
6748
6744
  return { data };
6749
6745
  }
6746
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6747
+ var VersionOutputSchema$1 = object({ version: string() });
6748
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6750
6749
  var StaticDirOutputSchema = object({ staticDir: string() });
6751
6750
  var VersionOutputSchema = object({ version: string() });
6752
6751
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -11848,7 +11847,7 @@ var BoundingBoxSchema = object({
11848
11847
  w: number(),
11849
11848
  h: number()
11850
11849
  });
11851
- var SpatialDetectionSchema = object({
11850
+ object({
11852
11851
  class: string(),
11853
11852
  originalClass: string(),
11854
11853
  score: number(),
@@ -12039,11 +12038,6 @@ var PipelineSchemaSchema = object({
12039
12038
  selectedEngine: PipelineEngineChoiceSchema,
12040
12039
  slots: array(PipelineSlotSchemaSchema).readonly()
12041
12040
  });
12042
- var DetectorOutputSchema = object({
12043
- detections: array(SpatialDetectionSchema).readonly(),
12044
- inferenceMs: number(),
12045
- modelId: string()
12046
- });
12047
12041
  var EngineProvisioningSchema = object({
12048
12042
  runtimeId: _enum([
12049
12043
  "onnx",
@@ -12168,7 +12162,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12168
12162
  auth: "admin"
12169
12163
  }), method(object({ nodeId: string() }), object({
12170
12164
  success: literal(true),
12171
- regeneratedModelId: string().nullable()
12165
+ clearedDevices: number()
12172
12166
  }), {
12173
12167
  kind: "mutation",
12174
12168
  auth: "admin"
@@ -12189,10 +12183,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12189
12183
  modelId: string(),
12190
12184
  format: ModelFormatSchema$1
12191
12185
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
12192
- addonId: string(),
12193
- frame: FrameInputSchema,
12194
- config: record(string(), unknown()).optional()
12195
- }), DetectorOutputSchema), method(object({
12196
12186
  engine: PipelineEngineChoiceSchema.optional(),
12197
12187
  steps: array(PipelineStepInputSchema).min(1),
12198
12188
  frame: FrameInputSchema.optional(),
@@ -15557,7 +15547,9 @@ var AddonPageDeclarationSchema$1 = object({
15557
15547
  icon: string(),
15558
15548
  path: string(),
15559
15549
  remoteName: string(),
15560
- bundle: string()
15550
+ bundle: string(),
15551
+ section: string().optional(),
15552
+ sectionLabel: string().optional()
15561
15553
  });
15562
15554
  var AddonPageInfoSchema = object({
15563
15555
  addonId: string(),
@@ -15597,7 +15589,18 @@ var AddonPageDeclarationSchema = object({
15597
15589
  * the static-file route can compute an mtime-based cache-buster URL
15598
15590
  * without a separate filesystem stat.
15599
15591
  */
15600
- bundle: string()
15592
+ bundle: string(),
15593
+ /**
15594
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
15595
+ * `'cluster'`, `'administration'` — the page renders inside that group.
15596
+ * Any OTHER string creates (or joins) a custom section rendered after
15597
+ * the built-in groups; its label comes from `sectionLabel` (first
15598
+ * declaration wins), falling back to the id. Absent → the legacy
15599
+ * "Addon Pages" group.
15600
+ */
15601
+ section: string().optional(),
15602
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
15603
+ sectionLabel: string().optional()
15601
15604
  });
15602
15605
  method(_void(), array(AddonPageDeclarationSchema).readonly());
15603
15606
  var AddonHttpRouteSchema = object({
@@ -15813,6 +15816,17 @@ var WidgetMetadataSchema = object({
15813
15816
  deviceContext: boolean().default(false),
15814
15817
  integrationContext: boolean().default(false)
15815
15818
  }),
15819
+ /**
15820
+ * Loadable BEFORE authentication. The normal widget registry listing
15821
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
15822
+ * (the login page) cannot discover a widget through it. A widget that
15823
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
15824
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
15825
+ * login-method contribution channel (see `login-method.cap.ts`) rather
15826
+ * than the authenticated registry, and its bundle is served by the
15827
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
15828
+ */
15829
+ preAuth: boolean().optional().default(false),
15816
15830
  /** Dashboard placement HINTS (operator can override per instance). */
15817
15831
  defaultSize: WidgetSizeEnum.default("md"),
15818
15832
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -16114,6 +16128,66 @@ method(object({
16114
16128
  password: string()
16115
16129
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
16116
16130
  /**
16131
+ * `login-method` — collection cap through which auth addons contribute
16132
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
16133
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
16134
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
16135
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
16136
+ * procedure aggregates them for the unauthenticated login page.
16137
+ *
16138
+ * A contribution is a discriminated union on `kind`:
16139
+ *
16140
+ * - `redirect` — a declarative button. The login page renders a generic
16141
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
16142
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
16143
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
16144
+ * login page needs NO change.
16145
+ *
16146
+ * - `widget` — a Module-Federation widget the login page mounts (via
16147
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
16148
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
16149
+ * addon bundle. The referenced widget also declares `preAuth: true` in
16150
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
16151
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
16152
+ *
16153
+ * Every contribution carries a `stage`:
16154
+ * - `primary` — shown on the first credentials screen (OIDC /
16155
+ * magic-link buttons; a future usernameless passkey).
16156
+ * - `second-factor` — shown AFTER the password leg, gated on the
16157
+ * returned `factors` (passkey-as-2FA today).
16158
+ *
16159
+ * `mount: skip` — the cap is read server-side by the core auth router
16160
+ * (`registry.getCollection('login-method')`), never mounted as its own
16161
+ * tRPC router.
16162
+ */
16163
+ /** When a login method renders in the two-phase login flow. */
16164
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
16165
+ /** One login-method contribution — redirect button OR pre-auth widget. */
16166
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
16167
+ kind: literal("redirect"),
16168
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
16169
+ id: string(),
16170
+ /** Operator-facing button label. */
16171
+ label: string(),
16172
+ /** lucide-react icon name. */
16173
+ icon: string().optional(),
16174
+ /** Addon-owned HTTP route the button navigates to (GET). */
16175
+ startUrl: string(),
16176
+ stage: LoginStageEnum
16177
+ }), object({
16178
+ kind: literal("widget"),
16179
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
16180
+ id: string(),
16181
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
16182
+ addonId: string(),
16183
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
16184
+ bundle: string(),
16185
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
16186
+ remote: WidgetRemoteSchema,
16187
+ stage: LoginStageEnum
16188
+ })]);
16189
+ method(_void(), array(LoginMethodContributionSchema).readonly());
16190
+ /**
16117
16191
  * Orchestrator-side destination metadata. The orchestrator computes
16118
16192
  * `id = <addonId>:<subId>` from its provider lookup so consumers
16119
16193
  * (admin UI, restore flow) see one canonical key.
@@ -18443,7 +18517,12 @@ var AgentPipelineSettingsSchema = object({
18443
18517
  detectWeight: number().positive().optional(),
18444
18518
  /** Node is eligible to run the detection pipeline (decode + inference). */
18445
18519
  detect: boolean().optional(),
18446
- /** Node is eligible to host decoder sessions. */
18520
+ /**
18521
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
18522
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
18523
+ * the schema ONLY so persisted stores written before the removal still
18524
+ * parse — no code reads it and no write path emits it.
18525
+ */
18447
18526
  decode: boolean().optional(),
18448
18527
  /** Node is eligible to run audio-analyzer sessions. */
18449
18528
  audio: boolean().optional(),
@@ -18504,25 +18583,6 @@ var PipelineAssignmentSchema = object({
18504
18583
  assignedAt: number()
18505
18584
  });
18506
18585
  /**
18507
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
18508
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
18509
- * → co-located with pipeline → capacity).
18510
- */
18511
- var DecoderAssignmentSchema = object({
18512
- deviceId: number(),
18513
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
18514
- decoderNodeId: string(),
18515
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
18516
- pinned: boolean(),
18517
- /** Why this assignment was made — useful for debugging the decoder balancer. */
18518
- reason: _enum([
18519
- "manual",
18520
- "co-located",
18521
- "capacity",
18522
- "hardware-affinity"
18523
- ])
18524
- });
18525
- /**
18526
18586
  * Per-agent load summary surfaced to the load balancer + dashboards.
18527
18587
  * Aggregated from each runner's `getLocalLoad` cap call.
18528
18588
  */
@@ -18728,15 +18788,6 @@ method(object({
18728
18788
  }), method(_void(), IngestOwnerSchema), method(object({
18729
18789
  deviceId: number(),
18730
18790
  nodeId: string()
18731
- }), _void(), {
18732
- kind: "mutation",
18733
- auth: "admin"
18734
- }), method(object({ deviceId: number() }), _void(), {
18735
- kind: "mutation",
18736
- auth: "admin"
18737
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
18738
- deviceId: number(),
18739
- nodeId: string()
18740
18791
  }), object({ success: literal(true) }), {
18741
18792
  kind: "mutation",
18742
18793
  auth: "admin"
@@ -18755,10 +18806,7 @@ method(object({
18755
18806
  nodeId: string(),
18756
18807
  pinned: boolean(),
18757
18808
  assignedAt: number()
18758
- }))), method(object({
18759
- deviceId: number(),
18760
- pipelineNodeId: string().optional()
18761
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18809
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18762
18810
  nodeId: string(),
18763
18811
  settings: AgentPipelineSettingsSchema
18764
18812
  })).readonly()), method(object({
@@ -18788,7 +18836,6 @@ method(object({
18788
18836
  }), method(object({
18789
18837
  agentNodeId: string(),
18790
18838
  detect: boolean().nullable().optional(),
18791
- decode: boolean().nullable().optional(),
18792
18839
  audio: boolean().nullable().optional(),
18793
18840
  ingest: boolean().nullable().optional()
18794
18841
  }), object({ success: literal(true) }), {
@@ -18800,6 +18847,15 @@ method(object({
18800
18847
  }), object({ success: literal(true) }), {
18801
18848
  kind: "mutation",
18802
18849
  auth: "admin"
18850
+ }), method(object({ agentNodeId: string() }), object({
18851
+ success: literal(true),
18852
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
18853
+ effectiveModelId: string().nullable(),
18854
+ /** Number of cameras whose node-scoped overrides were cleared. */
18855
+ clearedCameraOverrides: number()
18856
+ }), {
18857
+ kind: "mutation",
18858
+ auth: "admin"
18803
18859
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18804
18860
  deviceId: number(),
18805
18861
  addonId: string(),
@@ -18845,6 +18901,131 @@ method(object({
18845
18901
  auth: "admin"
18846
18902
  });
18847
18903
  /**
18904
+ * server-management — per-NODE singleton capability for a node's ROOT
18905
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
18906
+ * agents).
18907
+ *
18908
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
18909
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
18910
+ * version describes the node. Updates install into
18911
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
18912
+ * starter (probation boot + auto-rollback to N-1).
18913
+ *
18914
+ * Providers:
18915
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
18916
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
18917
+ * unpinned calls.
18918
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
18919
+ * the synthetic `agent-runtime` addonId and declared in the agent's
18920
+ * `$hub.registerNode` manifest.
18921
+ *
18922
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
18923
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
18924
+ * SDK) routes the call to that node's provider via the standard remote
18925
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
18926
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
18927
+ *
18928
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
18929
+ */
18930
+ /**
18931
+ * Where the running hub's code was loaded from:
18932
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
18933
+ * plain resolution and runtime updates are refused.
18934
+ * - `baked` — the immutable image seed closure (no data-dir root active).
18935
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
18936
+ */
18937
+ var ServerBootModeSchema = _enum([
18938
+ "workspace",
18939
+ "baked",
18940
+ "data-root"
18941
+ ]);
18942
+ /**
18943
+ * Update lifecycle state:
18944
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
18945
+ * - `pending-restart` — a version is staged and the node has NOT yet
18946
+ * restarted onto it (still running the OLD version).
18947
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
18948
+ * (it is the active probation boot) and is waiting to confirm boot-health.
18949
+ * Apply/rollback are refused in this state and the node must NOT be
18950
+ * manually restarted, or the probation boot auto-rolls-back.
18951
+ */
18952
+ var ServerUpdateStateSchema = _enum([
18953
+ "idle",
18954
+ "checking",
18955
+ "staging",
18956
+ "pending-restart",
18957
+ "awaiting-confirmation"
18958
+ ]);
18959
+ var ServerRollbackInfoSchema = object({
18960
+ /** The version that failed (or was manually rolled back). */
18961
+ fromVersion: string(),
18962
+ /** The version rolled back to; null = the baked seed. */
18963
+ toVersion: string().nullable(),
18964
+ atMs: number(),
18965
+ reason: string()
18966
+ });
18967
+ var ServerPackageStatusSchema = object({
18968
+ /** Root package name (`@camstack/server` on the hub). */
18969
+ packageName: string(),
18970
+ /** Version of the code the running process ACTUALLY loaded. */
18971
+ runningVersion: string().nullable(),
18972
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
18973
+ nodeRuntimeVersion: string().nullable(),
18974
+ /** Active data-dir root version; null when booted from seed/workspace. */
18975
+ activeVersion: string().nullable(),
18976
+ /** N-1 version kept for rollback; null when no previous version exists. */
18977
+ previousVersion: string().nullable(),
18978
+ /** Version of the immutable baked seed closure (image fallback). */
18979
+ seedVersion: string().nullable(),
18980
+ /** Latest registry version from the most recent check (null = never checked). */
18981
+ latestVersion: string().nullable(),
18982
+ updateAvailable: boolean(),
18983
+ bootMode: ServerBootModeSchema,
18984
+ updateState: ServerUpdateStateSchema,
18985
+ /** Version staged + awaiting its probation boot, when one is pending. */
18986
+ pendingVersion: string().nullable(),
18987
+ /** Set when the last freshly-activated version failed its boot health-check. */
18988
+ rolledBack: ServerRollbackInfoSchema.nullable(),
18989
+ /**
18990
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
18991
+ * hub is running from the baked seed (or workspace) while installed data-dir
18992
+ * versions are being IGNORED. Surfaced as a warning in the UI.
18993
+ */
18994
+ stateFileCorrupt: boolean(),
18995
+ lastCheckedAtMs: number().nullable()
18996
+ });
18997
+ var ServerUpdateCheckResultSchema = object({
18998
+ packageName: string(),
18999
+ runningVersion: string().nullable(),
19000
+ latestVersion: string().nullable(),
19001
+ updateAvailable: boolean(),
19002
+ checkedAtMs: number(),
19003
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
19004
+ error: string().nullable()
19005
+ });
19006
+ var ServerUpdateActionResultSchema = object({
19007
+ accepted: boolean(),
19008
+ targetVersion: string().nullable(),
19009
+ /** True when a graceful restart was scheduled to apply the change. */
19010
+ restarting: boolean(),
19011
+ message: string()
19012
+ });
19013
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
19014
+ kind: "mutation",
19015
+ auth: "admin"
19016
+ }), method(object({
19017
+ /** Explicit target version; omitted = latest from the registry. */
19018
+ version: string().optional() }), ServerUpdateActionResultSchema, {
19019
+ kind: "mutation",
19020
+ auth: "admin"
19021
+ }), method(_void(), ServerUpdateActionResultSchema, {
19022
+ kind: "mutation",
19023
+ auth: "admin"
19024
+ }), method(_void(), ServerUpdateActionResultSchema, {
19025
+ kind: "mutation",
19026
+ auth: "admin"
19027
+ });
19028
+ /**
18848
19029
  * Query filter for settings-store collections.
18849
19030
  */
18850
19031
  var QueryFilterSchema = object({
@@ -20925,6 +21106,16 @@ var TopologyCategorySchema = object({
20925
21106
  healthy: number(),
20926
21107
  addons: array(TopologyCategoryAddonSchema).readonly()
20927
21108
  });
21109
+ /**
21110
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
21111
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
21112
+ * version visibility for the Server management surface. Nullable: offline
21113
+ * rows and pre-phase-2 nodes report none.
21114
+ */
21115
+ var TopologyRootPackageSchema = object({
21116
+ name: string(),
21117
+ version: string()
21118
+ });
20928
21119
  var TopologyNodeSchema = object({
20929
21120
  id: string(),
20930
21121
  name: string(),
@@ -20948,7 +21139,8 @@ var TopologyNodeSchema = object({
20948
21139
  status: string()
20949
21140
  })).readonly(),
20950
21141
  processes: array(TopologyProcessSchema).readonly(),
20951
- categories: array(TopologyCategorySchema).readonly()
21142
+ categories: array(TopologyCategorySchema).readonly(),
21143
+ rootPackage: TopologyRootPackageSchema.nullable()
20952
21144
  });
20953
21145
  var CapUsageEdgeSchema = object({
20954
21146
  callerAddonId: string(),
@@ -24072,6 +24264,12 @@ Object.freeze({
24072
24264
  addonId: null,
24073
24265
  access: "create"
24074
24266
  },
24267
+ "loginMethod.getLoginMethods": {
24268
+ capName: "login-method",
24269
+ capScope: "system",
24270
+ addonId: null,
24271
+ access: "view"
24272
+ },
24075
24273
  "mediaPlayer.next": {
24076
24274
  capName: "media-player",
24077
24275
  capScope: "device",
@@ -24702,23 +24900,23 @@ Object.freeze({
24702
24900
  addonId: null,
24703
24901
  access: "create"
24704
24902
  },
24705
- "pipelineExecutor.deleteModel": {
24903
+ "pipelineExecutor.clearDeviceOverrides": {
24706
24904
  capName: "pipeline-executor",
24707
24905
  capScope: "system",
24708
24906
  addonId: null,
24709
24907
  access: "delete"
24710
24908
  },
24711
- "pipelineExecutor.deleteTemplate": {
24909
+ "pipelineExecutor.deleteModel": {
24712
24910
  capName: "pipeline-executor",
24713
24911
  capScope: "system",
24714
24912
  addonId: null,
24715
24913
  access: "delete"
24716
24914
  },
24717
- "pipelineExecutor.detect": {
24915
+ "pipelineExecutor.deleteTemplate": {
24718
24916
  capName: "pipeline-executor",
24719
24917
  capScope: "system",
24720
24918
  addonId: null,
24721
- access: "view"
24919
+ access: "delete"
24722
24920
  },
24723
24921
  "pipelineExecutor.downloadModel": {
24724
24922
  capName: "pipeline-executor",
@@ -24864,12 +25062,6 @@ Object.freeze({
24864
25062
  addonId: null,
24865
25063
  access: "create"
24866
25064
  },
24867
- "pipelineExecutor.resetToDefault": {
24868
- capName: "pipeline-executor",
24869
- capScope: "system",
24870
- addonId: null,
24871
- access: "delete"
24872
- },
24873
25065
  "pipelineExecutor.runAudioTest": {
24874
25066
  capName: "pipeline-executor",
24875
25067
  capScope: "system",
@@ -24930,12 +25122,6 @@ Object.freeze({
24930
25122
  addonId: null,
24931
25123
  access: "create"
24932
25124
  },
24933
- "pipelineOrchestrator.assignDecoder": {
24934
- capName: "pipeline-orchestrator",
24935
- capScope: "system",
24936
- addonId: null,
24937
- access: "create"
24938
- },
24939
25125
  "pipelineOrchestrator.assignPipeline": {
24940
25126
  capName: "pipeline-orchestrator",
24941
25127
  capScope: "system",
@@ -25014,18 +25200,6 @@ Object.freeze({
25014
25200
  addonId: null,
25015
25201
  access: "view"
25016
25202
  },
25017
- "pipelineOrchestrator.getDecoderAssignment": {
25018
- capName: "pipeline-orchestrator",
25019
- capScope: "system",
25020
- addonId: null,
25021
- access: "view"
25022
- },
25023
- "pipelineOrchestrator.getDecoderAssignments": {
25024
- capName: "pipeline-orchestrator",
25025
- capScope: "system",
25026
- addonId: null,
25027
- access: "view"
25028
- },
25029
25203
  "pipelineOrchestrator.getGlobalMetrics": {
25030
25204
  capName: "pipeline-orchestrator",
25031
25205
  capScope: "system",
@@ -25074,6 +25248,12 @@ Object.freeze({
25074
25248
  addonId: null,
25075
25249
  access: "delete"
25076
25250
  },
25251
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
25252
+ capName: "pipeline-orchestrator",
25253
+ capScope: "system",
25254
+ addonId: null,
25255
+ access: "delete"
25256
+ },
25077
25257
  "pipelineOrchestrator.resolvePipeline": {
25078
25258
  capName: "pipeline-orchestrator",
25079
25259
  capScope: "system",
@@ -25146,12 +25326,6 @@ Object.freeze({
25146
25326
  addonId: null,
25147
25327
  access: "create"
25148
25328
  },
25149
- "pipelineOrchestrator.unassignDecoder": {
25150
- capName: "pipeline-orchestrator",
25151
- capScope: "system",
25152
- addonId: null,
25153
- access: "create"
25154
- },
25155
25329
  "pipelineOrchestrator.unassignPipeline": {
25156
25330
  capName: "pipeline-orchestrator",
25157
25331
  capScope: "system",
@@ -25458,6 +25632,36 @@ Object.freeze({
25458
25632
  addonId: null,
25459
25633
  access: "create"
25460
25634
  },
25635
+ "serverManagement.applyServerUpdate": {
25636
+ capName: "server-management",
25637
+ capScope: "system",
25638
+ addonId: null,
25639
+ access: "create"
25640
+ },
25641
+ "serverManagement.checkServerUpdate": {
25642
+ capName: "server-management",
25643
+ capScope: "system",
25644
+ addonId: null,
25645
+ access: "create"
25646
+ },
25647
+ "serverManagement.getServerPackageStatus": {
25648
+ capName: "server-management",
25649
+ capScope: "system",
25650
+ addonId: null,
25651
+ access: "view"
25652
+ },
25653
+ "serverManagement.restartServer": {
25654
+ capName: "server-management",
25655
+ capScope: "system",
25656
+ addonId: null,
25657
+ access: "create"
25658
+ },
25659
+ "serverManagement.rollbackServerUpdate": {
25660
+ capName: "server-management",
25661
+ capScope: "system",
25662
+ addonId: null,
25663
+ access: "create"
25664
+ },
25461
25665
  "settingsStore.count": {
25462
25666
  capName: "settings-store",
25463
25667
  capScope: "system",
@@ -26322,6 +26526,18 @@ Object.freeze({
26322
26526
  addonId: null,
26323
26527
  access: "view"
26324
26528
  },
26529
+ "viewerUi.getStaticDir": {
26530
+ capName: "viewer-ui",
26531
+ capScope: "system",
26532
+ addonId: null,
26533
+ access: "view"
26534
+ },
26535
+ "viewerUi.getVersion": {
26536
+ capName: "viewer-ui",
26537
+ capScope: "system",
26538
+ addonId: null,
26539
+ access: "view"
26540
+ },
26325
26541
  "waterHeater.setAway": {
26326
26542
  capName: "water-heater",
26327
26543
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4636,7 +4636,7 @@ function _instanceof(cls, params = {}) {
4636
4636
  return inst;
4637
4637
  }
4638
4638
  //#endregion
4639
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4639
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4640
4640
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4641
4641
  EventCategory["SystemBoot"] = "system.boot";
4642
4642
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5357,10 +5357,6 @@ function hydrateField(field, values) {
5357
5357
  };
5358
5358
  }
5359
5359
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5360
- if (field.type === "password") return {
5361
- ...field,
5362
- value: ""
5363
- };
5364
5360
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5365
5361
  return {
5366
5362
  ...field,
@@ -6748,6 +6744,9 @@ function method(input, output, options) {
6748
6744
  function event(data) {
6749
6745
  return { data };
6750
6746
  }
6747
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6748
+ var VersionOutputSchema$1 = object({ version: string() });
6749
+ method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
6751
6750
  var StaticDirOutputSchema = object({ staticDir: string() });
6752
6751
  var VersionOutputSchema = object({ version: string() });
6753
6752
  method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
@@ -11849,7 +11848,7 @@ var BoundingBoxSchema = object({
11849
11848
  w: number(),
11850
11849
  h: number()
11851
11850
  });
11852
- var SpatialDetectionSchema = object({
11851
+ object({
11853
11852
  class: string(),
11854
11853
  originalClass: string(),
11855
11854
  score: number(),
@@ -12040,11 +12039,6 @@ var PipelineSchemaSchema = object({
12040
12039
  selectedEngine: PipelineEngineChoiceSchema,
12041
12040
  slots: array(PipelineSlotSchemaSchema).readonly()
12042
12041
  });
12043
- var DetectorOutputSchema = object({
12044
- detections: array(SpatialDetectionSchema).readonly(),
12045
- inferenceMs: number(),
12046
- modelId: string()
12047
- });
12048
12042
  var EngineProvisioningSchema = object({
12049
12043
  runtimeId: _enum([
12050
12044
  "onnx",
@@ -12169,7 +12163,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12169
12163
  auth: "admin"
12170
12164
  }), method(object({ nodeId: string() }), object({
12171
12165
  success: literal(true),
12172
- regeneratedModelId: string().nullable()
12166
+ clearedDevices: number()
12173
12167
  }), {
12174
12168
  kind: "mutation",
12175
12169
  auth: "admin"
@@ -12190,10 +12184,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12190
12184
  modelId: string(),
12191
12185
  format: ModelFormatSchema$1
12192
12186
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
12193
- addonId: string(),
12194
- frame: FrameInputSchema,
12195
- config: record(string(), unknown()).optional()
12196
- }), DetectorOutputSchema), method(object({
12197
12187
  engine: PipelineEngineChoiceSchema.optional(),
12198
12188
  steps: array(PipelineStepInputSchema).min(1),
12199
12189
  frame: FrameInputSchema.optional(),
@@ -15558,7 +15548,9 @@ var AddonPageDeclarationSchema$1 = object({
15558
15548
  icon: string(),
15559
15549
  path: string(),
15560
15550
  remoteName: string(),
15561
- bundle: string()
15551
+ bundle: string(),
15552
+ section: string().optional(),
15553
+ sectionLabel: string().optional()
15562
15554
  });
15563
15555
  var AddonPageInfoSchema = object({
15564
15556
  addonId: string(),
@@ -15598,7 +15590,18 @@ var AddonPageDeclarationSchema = object({
15598
15590
  * the static-file route can compute an mtime-based cache-buster URL
15599
15591
  * without a separate filesystem stat.
15600
15592
  */
15601
- bundle: string()
15593
+ bundle: string(),
15594
+ /**
15595
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
15596
+ * `'cluster'`, `'administration'` — the page renders inside that group.
15597
+ * Any OTHER string creates (or joins) a custom section rendered after
15598
+ * the built-in groups; its label comes from `sectionLabel` (first
15599
+ * declaration wins), falling back to the id. Absent → the legacy
15600
+ * "Addon Pages" group.
15601
+ */
15602
+ section: string().optional(),
15603
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
15604
+ sectionLabel: string().optional()
15602
15605
  });
15603
15606
  method(_void(), array(AddonPageDeclarationSchema).readonly());
15604
15607
  var AddonHttpRouteSchema = object({
@@ -15814,6 +15817,17 @@ var WidgetMetadataSchema = object({
15814
15817
  deviceContext: boolean().default(false),
15815
15818
  integrationContext: boolean().default(false)
15816
15819
  }),
15820
+ /**
15821
+ * Loadable BEFORE authentication. The normal widget registry listing
15822
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
15823
+ * (the login page) cannot discover a widget through it. A widget that
15824
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
15825
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
15826
+ * login-method contribution channel (see `login-method.cap.ts`) rather
15827
+ * than the authenticated registry, and its bundle is served by the
15828
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
15829
+ */
15830
+ preAuth: boolean().optional().default(false),
15817
15831
  /** Dashboard placement HINTS (operator can override per instance). */
15818
15832
  defaultSize: WidgetSizeEnum.default("md"),
15819
15833
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -16115,6 +16129,66 @@ method(object({
16115
16129
  password: string()
16116
16130
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
16117
16131
  /**
16132
+ * `login-method` — collection cap through which auth addons contribute
16133
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
16134
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
16135
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
16136
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
16137
+ * procedure aggregates them for the unauthenticated login page.
16138
+ *
16139
+ * A contribution is a discriminated union on `kind`:
16140
+ *
16141
+ * - `redirect` — a declarative button. The login page renders a generic
16142
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
16143
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
16144
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
16145
+ * login page needs NO change.
16146
+ *
16147
+ * - `widget` — a Module-Federation widget the login page mounts (via
16148
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
16149
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
16150
+ * addon bundle. The referenced widget also declares `preAuth: true` in
16151
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
16152
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
16153
+ *
16154
+ * Every contribution carries a `stage`:
16155
+ * - `primary` — shown on the first credentials screen (OIDC /
16156
+ * magic-link buttons; a future usernameless passkey).
16157
+ * - `second-factor` — shown AFTER the password leg, gated on the
16158
+ * returned `factors` (passkey-as-2FA today).
16159
+ *
16160
+ * `mount: skip` — the cap is read server-side by the core auth router
16161
+ * (`registry.getCollection('login-method')`), never mounted as its own
16162
+ * tRPC router.
16163
+ */
16164
+ /** When a login method renders in the two-phase login flow. */
16165
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
16166
+ /** One login-method contribution — redirect button OR pre-auth widget. */
16167
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
16168
+ kind: literal("redirect"),
16169
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
16170
+ id: string(),
16171
+ /** Operator-facing button label. */
16172
+ label: string(),
16173
+ /** lucide-react icon name. */
16174
+ icon: string().optional(),
16175
+ /** Addon-owned HTTP route the button navigates to (GET). */
16176
+ startUrl: string(),
16177
+ stage: LoginStageEnum
16178
+ }), object({
16179
+ kind: literal("widget"),
16180
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
16181
+ id: string(),
16182
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
16183
+ addonId: string(),
16184
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
16185
+ bundle: string(),
16186
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
16187
+ remote: WidgetRemoteSchema,
16188
+ stage: LoginStageEnum
16189
+ })]);
16190
+ method(_void(), array(LoginMethodContributionSchema).readonly());
16191
+ /**
16118
16192
  * Orchestrator-side destination metadata. The orchestrator computes
16119
16193
  * `id = <addonId>:<subId>` from its provider lookup so consumers
16120
16194
  * (admin UI, restore flow) see one canonical key.
@@ -18444,7 +18518,12 @@ var AgentPipelineSettingsSchema = object({
18444
18518
  detectWeight: number().positive().optional(),
18445
18519
  /** Node is eligible to run the detection pipeline (decode + inference). */
18446
18520
  detect: boolean().optional(),
18447
- /** Node is eligible to host decoder sessions. */
18521
+ /**
18522
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
18523
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
18524
+ * the schema ONLY so persisted stores written before the removal still
18525
+ * parse — no code reads it and no write path emits it.
18526
+ */
18448
18527
  decode: boolean().optional(),
18449
18528
  /** Node is eligible to run audio-analyzer sessions. */
18450
18529
  audio: boolean().optional(),
@@ -18505,25 +18584,6 @@ var PipelineAssignmentSchema = object({
18505
18584
  assignedAt: number()
18506
18585
  });
18507
18586
  /**
18508
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
18509
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
18510
- * → co-located with pipeline → capacity).
18511
- */
18512
- var DecoderAssignmentSchema = object({
18513
- deviceId: number(),
18514
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
18515
- decoderNodeId: string(),
18516
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
18517
- pinned: boolean(),
18518
- /** Why this assignment was made — useful for debugging the decoder balancer. */
18519
- reason: _enum([
18520
- "manual",
18521
- "co-located",
18522
- "capacity",
18523
- "hardware-affinity"
18524
- ])
18525
- });
18526
- /**
18527
18587
  * Per-agent load summary surfaced to the load balancer + dashboards.
18528
18588
  * Aggregated from each runner's `getLocalLoad` cap call.
18529
18589
  */
@@ -18729,15 +18789,6 @@ method(object({
18729
18789
  }), method(_void(), IngestOwnerSchema), method(object({
18730
18790
  deviceId: number(),
18731
18791
  nodeId: string()
18732
- }), _void(), {
18733
- kind: "mutation",
18734
- auth: "admin"
18735
- }), method(object({ deviceId: number() }), _void(), {
18736
- kind: "mutation",
18737
- auth: "admin"
18738
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
18739
- deviceId: number(),
18740
- nodeId: string()
18741
18792
  }), object({ success: literal(true) }), {
18742
18793
  kind: "mutation",
18743
18794
  auth: "admin"
@@ -18756,10 +18807,7 @@ method(object({
18756
18807
  nodeId: string(),
18757
18808
  pinned: boolean(),
18758
18809
  assignedAt: number()
18759
- }))), method(object({
18760
- deviceId: number(),
18761
- pipelineNodeId: string().optional()
18762
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18810
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
18763
18811
  nodeId: string(),
18764
18812
  settings: AgentPipelineSettingsSchema
18765
18813
  })).readonly()), method(object({
@@ -18789,7 +18837,6 @@ method(object({
18789
18837
  }), method(object({
18790
18838
  agentNodeId: string(),
18791
18839
  detect: boolean().nullable().optional(),
18792
- decode: boolean().nullable().optional(),
18793
18840
  audio: boolean().nullable().optional(),
18794
18841
  ingest: boolean().nullable().optional()
18795
18842
  }), object({ success: literal(true) }), {
@@ -18801,6 +18848,15 @@ method(object({
18801
18848
  }), object({ success: literal(true) }), {
18802
18849
  kind: "mutation",
18803
18850
  auth: "admin"
18851
+ }), method(object({ agentNodeId: string() }), object({
18852
+ success: literal(true),
18853
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
18854
+ effectiveModelId: string().nullable(),
18855
+ /** Number of cameras whose node-scoped overrides were cleared. */
18856
+ clearedCameraOverrides: number()
18857
+ }), {
18858
+ kind: "mutation",
18859
+ auth: "admin"
18804
18860
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18805
18861
  deviceId: number(),
18806
18862
  addonId: string(),
@@ -18846,6 +18902,131 @@ method(object({
18846
18902
  auth: "admin"
18847
18903
  });
18848
18904
  /**
18905
+ * server-management — per-NODE singleton capability for a node's ROOT
18906
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
18907
+ * agents).
18908
+ *
18909
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
18910
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
18911
+ * version describes the node. Updates install into
18912
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
18913
+ * starter (probation boot + auto-rollback to N-1).
18914
+ *
18915
+ * Providers:
18916
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
18917
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
18918
+ * unpinned calls.
18919
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
18920
+ * the synthetic `agent-runtime` addonId and declared in the agent's
18921
+ * `$hub.registerNode` manifest.
18922
+ *
18923
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
18924
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
18925
+ * SDK) routes the call to that node's provider via the standard remote
18926
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
18927
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
18928
+ *
18929
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
18930
+ */
18931
+ /**
18932
+ * Where the running hub's code was loaded from:
18933
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
18934
+ * plain resolution and runtime updates are refused.
18935
+ * - `baked` — the immutable image seed closure (no data-dir root active).
18936
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
18937
+ */
18938
+ var ServerBootModeSchema = _enum([
18939
+ "workspace",
18940
+ "baked",
18941
+ "data-root"
18942
+ ]);
18943
+ /**
18944
+ * Update lifecycle state:
18945
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
18946
+ * - `pending-restart` — a version is staged and the node has NOT yet
18947
+ * restarted onto it (still running the OLD version).
18948
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
18949
+ * (it is the active probation boot) and is waiting to confirm boot-health.
18950
+ * Apply/rollback are refused in this state and the node must NOT be
18951
+ * manually restarted, or the probation boot auto-rolls-back.
18952
+ */
18953
+ var ServerUpdateStateSchema = _enum([
18954
+ "idle",
18955
+ "checking",
18956
+ "staging",
18957
+ "pending-restart",
18958
+ "awaiting-confirmation"
18959
+ ]);
18960
+ var ServerRollbackInfoSchema = object({
18961
+ /** The version that failed (or was manually rolled back). */
18962
+ fromVersion: string(),
18963
+ /** The version rolled back to; null = the baked seed. */
18964
+ toVersion: string().nullable(),
18965
+ atMs: number(),
18966
+ reason: string()
18967
+ });
18968
+ var ServerPackageStatusSchema = object({
18969
+ /** Root package name (`@camstack/server` on the hub). */
18970
+ packageName: string(),
18971
+ /** Version of the code the running process ACTUALLY loaded. */
18972
+ runningVersion: string().nullable(),
18973
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
18974
+ nodeRuntimeVersion: string().nullable(),
18975
+ /** Active data-dir root version; null when booted from seed/workspace. */
18976
+ activeVersion: string().nullable(),
18977
+ /** N-1 version kept for rollback; null when no previous version exists. */
18978
+ previousVersion: string().nullable(),
18979
+ /** Version of the immutable baked seed closure (image fallback). */
18980
+ seedVersion: string().nullable(),
18981
+ /** Latest registry version from the most recent check (null = never checked). */
18982
+ latestVersion: string().nullable(),
18983
+ updateAvailable: boolean(),
18984
+ bootMode: ServerBootModeSchema,
18985
+ updateState: ServerUpdateStateSchema,
18986
+ /** Version staged + awaiting its probation boot, when one is pending. */
18987
+ pendingVersion: string().nullable(),
18988
+ /** Set when the last freshly-activated version failed its boot health-check. */
18989
+ rolledBack: ServerRollbackInfoSchema.nullable(),
18990
+ /**
18991
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
18992
+ * hub is running from the baked seed (or workspace) while installed data-dir
18993
+ * versions are being IGNORED. Surfaced as a warning in the UI.
18994
+ */
18995
+ stateFileCorrupt: boolean(),
18996
+ lastCheckedAtMs: number().nullable()
18997
+ });
18998
+ var ServerUpdateCheckResultSchema = object({
18999
+ packageName: string(),
19000
+ runningVersion: string().nullable(),
19001
+ latestVersion: string().nullable(),
19002
+ updateAvailable: boolean(),
19003
+ checkedAtMs: number(),
19004
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
19005
+ error: string().nullable()
19006
+ });
19007
+ var ServerUpdateActionResultSchema = object({
19008
+ accepted: boolean(),
19009
+ targetVersion: string().nullable(),
19010
+ /** True when a graceful restart was scheduled to apply the change. */
19011
+ restarting: boolean(),
19012
+ message: string()
19013
+ });
19014
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
19015
+ kind: "mutation",
19016
+ auth: "admin"
19017
+ }), method(object({
19018
+ /** Explicit target version; omitted = latest from the registry. */
19019
+ version: string().optional() }), ServerUpdateActionResultSchema, {
19020
+ kind: "mutation",
19021
+ auth: "admin"
19022
+ }), method(_void(), ServerUpdateActionResultSchema, {
19023
+ kind: "mutation",
19024
+ auth: "admin"
19025
+ }), method(_void(), ServerUpdateActionResultSchema, {
19026
+ kind: "mutation",
19027
+ auth: "admin"
19028
+ });
19029
+ /**
18849
19030
  * Query filter for settings-store collections.
18850
19031
  */
18851
19032
  var QueryFilterSchema = object({
@@ -20926,6 +21107,16 @@ var TopologyCategorySchema = object({
20926
21107
  healthy: number(),
20927
21108
  addons: array(TopologyCategoryAddonSchema).readonly()
20928
21109
  });
21110
+ /**
21111
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
21112
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
21113
+ * version visibility for the Server management surface. Nullable: offline
21114
+ * rows and pre-phase-2 nodes report none.
21115
+ */
21116
+ var TopologyRootPackageSchema = object({
21117
+ name: string(),
21118
+ version: string()
21119
+ });
20929
21120
  var TopologyNodeSchema = object({
20930
21121
  id: string(),
20931
21122
  name: string(),
@@ -20949,7 +21140,8 @@ var TopologyNodeSchema = object({
20949
21140
  status: string()
20950
21141
  })).readonly(),
20951
21142
  processes: array(TopologyProcessSchema).readonly(),
20952
- categories: array(TopologyCategorySchema).readonly()
21143
+ categories: array(TopologyCategorySchema).readonly(),
21144
+ rootPackage: TopologyRootPackageSchema.nullable()
20953
21145
  });
20954
21146
  var CapUsageEdgeSchema = object({
20955
21147
  callerAddonId: string(),
@@ -24073,6 +24265,12 @@ Object.freeze({
24073
24265
  addonId: null,
24074
24266
  access: "create"
24075
24267
  },
24268
+ "loginMethod.getLoginMethods": {
24269
+ capName: "login-method",
24270
+ capScope: "system",
24271
+ addonId: null,
24272
+ access: "view"
24273
+ },
24076
24274
  "mediaPlayer.next": {
24077
24275
  capName: "media-player",
24078
24276
  capScope: "device",
@@ -24703,23 +24901,23 @@ Object.freeze({
24703
24901
  addonId: null,
24704
24902
  access: "create"
24705
24903
  },
24706
- "pipelineExecutor.deleteModel": {
24904
+ "pipelineExecutor.clearDeviceOverrides": {
24707
24905
  capName: "pipeline-executor",
24708
24906
  capScope: "system",
24709
24907
  addonId: null,
24710
24908
  access: "delete"
24711
24909
  },
24712
- "pipelineExecutor.deleteTemplate": {
24910
+ "pipelineExecutor.deleteModel": {
24713
24911
  capName: "pipeline-executor",
24714
24912
  capScope: "system",
24715
24913
  addonId: null,
24716
24914
  access: "delete"
24717
24915
  },
24718
- "pipelineExecutor.detect": {
24916
+ "pipelineExecutor.deleteTemplate": {
24719
24917
  capName: "pipeline-executor",
24720
24918
  capScope: "system",
24721
24919
  addonId: null,
24722
- access: "view"
24920
+ access: "delete"
24723
24921
  },
24724
24922
  "pipelineExecutor.downloadModel": {
24725
24923
  capName: "pipeline-executor",
@@ -24865,12 +25063,6 @@ Object.freeze({
24865
25063
  addonId: null,
24866
25064
  access: "create"
24867
25065
  },
24868
- "pipelineExecutor.resetToDefault": {
24869
- capName: "pipeline-executor",
24870
- capScope: "system",
24871
- addonId: null,
24872
- access: "delete"
24873
- },
24874
25066
  "pipelineExecutor.runAudioTest": {
24875
25067
  capName: "pipeline-executor",
24876
25068
  capScope: "system",
@@ -24931,12 +25123,6 @@ Object.freeze({
24931
25123
  addonId: null,
24932
25124
  access: "create"
24933
25125
  },
24934
- "pipelineOrchestrator.assignDecoder": {
24935
- capName: "pipeline-orchestrator",
24936
- capScope: "system",
24937
- addonId: null,
24938
- access: "create"
24939
- },
24940
25126
  "pipelineOrchestrator.assignPipeline": {
24941
25127
  capName: "pipeline-orchestrator",
24942
25128
  capScope: "system",
@@ -25015,18 +25201,6 @@ Object.freeze({
25015
25201
  addonId: null,
25016
25202
  access: "view"
25017
25203
  },
25018
- "pipelineOrchestrator.getDecoderAssignment": {
25019
- capName: "pipeline-orchestrator",
25020
- capScope: "system",
25021
- addonId: null,
25022
- access: "view"
25023
- },
25024
- "pipelineOrchestrator.getDecoderAssignments": {
25025
- capName: "pipeline-orchestrator",
25026
- capScope: "system",
25027
- addonId: null,
25028
- access: "view"
25029
- },
25030
25204
  "pipelineOrchestrator.getGlobalMetrics": {
25031
25205
  capName: "pipeline-orchestrator",
25032
25206
  capScope: "system",
@@ -25075,6 +25249,12 @@ Object.freeze({
25075
25249
  addonId: null,
25076
25250
  access: "delete"
25077
25251
  },
25252
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
25253
+ capName: "pipeline-orchestrator",
25254
+ capScope: "system",
25255
+ addonId: null,
25256
+ access: "delete"
25257
+ },
25078
25258
  "pipelineOrchestrator.resolvePipeline": {
25079
25259
  capName: "pipeline-orchestrator",
25080
25260
  capScope: "system",
@@ -25147,12 +25327,6 @@ Object.freeze({
25147
25327
  addonId: null,
25148
25328
  access: "create"
25149
25329
  },
25150
- "pipelineOrchestrator.unassignDecoder": {
25151
- capName: "pipeline-orchestrator",
25152
- capScope: "system",
25153
- addonId: null,
25154
- access: "create"
25155
- },
25156
25330
  "pipelineOrchestrator.unassignPipeline": {
25157
25331
  capName: "pipeline-orchestrator",
25158
25332
  capScope: "system",
@@ -25459,6 +25633,36 @@ Object.freeze({
25459
25633
  addonId: null,
25460
25634
  access: "create"
25461
25635
  },
25636
+ "serverManagement.applyServerUpdate": {
25637
+ capName: "server-management",
25638
+ capScope: "system",
25639
+ addonId: null,
25640
+ access: "create"
25641
+ },
25642
+ "serverManagement.checkServerUpdate": {
25643
+ capName: "server-management",
25644
+ capScope: "system",
25645
+ addonId: null,
25646
+ access: "create"
25647
+ },
25648
+ "serverManagement.getServerPackageStatus": {
25649
+ capName: "server-management",
25650
+ capScope: "system",
25651
+ addonId: null,
25652
+ access: "view"
25653
+ },
25654
+ "serverManagement.restartServer": {
25655
+ capName: "server-management",
25656
+ capScope: "system",
25657
+ addonId: null,
25658
+ access: "create"
25659
+ },
25660
+ "serverManagement.rollbackServerUpdate": {
25661
+ capName: "server-management",
25662
+ capScope: "system",
25663
+ addonId: null,
25664
+ access: "create"
25665
+ },
25462
25666
  "settingsStore.count": {
25463
25667
  capName: "settings-store",
25464
25668
  capScope: "system",
@@ -26323,6 +26527,18 @@ Object.freeze({
26323
26527
  addonId: null,
26324
26528
  access: "view"
26325
26529
  },
26530
+ "viewerUi.getStaticDir": {
26531
+ capName: "viewer-ui",
26532
+ capScope: "system",
26533
+ addonId: null,
26534
+ access: "view"
26535
+ },
26536
+ "viewerUi.getVersion": {
26537
+ capName: "viewer-ui",
26538
+ capScope: "system",
26539
+ addonId: null,
26540
+ access: "view"
26541
+ },
26326
26542
  "waterHeater.setAway": {
26327
26543
  capName: "water-heater",
26328
26544
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-hikvision",
3
- "version": "1.1.20",
3
+ "version": "1.1.21",
4
4
  "description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
5
5
  "keywords": [
6
6
  "camstack",
@@ -66,6 +66,9 @@
66
66
  }
67
67
  ]
68
68
  }
69
+ ],
70
+ "runtimeDependencies": [
71
+ "onvif"
69
72
  ]
70
73
  },
71
74
  "files": [