@camstack/addon-admin-ui 1.1.38 → 1.1.40

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 (93) hide show
  1. package/dist/assets/{AddLocationWizard-6UQCTSu4.js → AddLocationWizard-DH1zgXau.js} +1 -1
  2. package/dist/assets/AddonCollectionPage-C8P99b0n.js +1 -0
  3. package/dist/assets/Addons-ql4qAeON.js +1 -0
  4. package/dist/assets/{AdminTabs-Bn5jDw8C.js → AdminTabs-BFmViSgF.js} +1 -1
  5. package/dist/assets/{BrokerForm-E7__Uhl9.js → BrokerForm-ClAXJAT9.js} +1 -1
  6. package/dist/assets/{Capabilities-DWu3W2I3.js → Capabilities-BUUnmipR.js} +1 -1
  7. package/dist/assets/{CapabilityBadges-D4uPGt_S.js → CapabilityBadges-DJ4Ez0Qj.js} +1 -1
  8. package/dist/assets/Cluster-_sIDv3Dx.js +1 -0
  9. package/dist/assets/{Dashboard-DRARX0g8.js → Dashboard-DkWFR-RK.js} +1 -1
  10. package/dist/assets/Data-B9S8aoV6.js +1 -0
  11. package/dist/assets/DetectionIntelligence-Db0D7-gq.js +1 -0
  12. package/dist/assets/DeviceDetail-MyRno8pF.js +2 -0
  13. package/dist/assets/{Devices-BFoz2HIh.js → Devices-CYdjYNMa.js} +1 -1
  14. package/dist/assets/{EmbedPlayerPage-BY9eFyyg.js → EmbedPlayerPage-BxhfuZxm.js} +1 -1
  15. package/dist/assets/{FormBuilder-CJrUV3p4.js → FormBuilder-CzGQp2IN.js} +1 -1
  16. package/dist/assets/Identity-VBuwkiW_.js +1 -0
  17. package/dist/assets/IntegrationDetail-Bv6r0j-e.js +1 -0
  18. package/dist/assets/{Integrations-Bj35Jpxj.js → Integrations-34-SopSE.js} +1 -1
  19. package/dist/assets/Integrations-VR6uvQtU.js +1 -0
  20. package/dist/assets/{Logs-B2WAadmI.js → Logs-Bd6dsQiy.js} +1 -1
  21. package/dist/assets/{MotionZonesSettings-3tt6mBQ0.js → MotionZonesSettings-CblR7zDg.js} +1 -1
  22. package/dist/assets/MyAccess-D9wXYE6f.js +2 -0
  23. package/dist/assets/Network-B4UJnXGJ.js +1 -0
  24. package/dist/assets/{NodeAddonsSettingsPanel-DTzycFzS.js → NodeAddonsSettingsPanel-DTo_3cuU.js} +1 -1
  25. package/dist/assets/{NotificationTargets-C3VSwqNL.js → NotificationTargets-BgoTGaHZ.js} +1 -1
  26. package/dist/assets/Pipeline-0vYb0c3Q.js +1 -0
  27. package/dist/assets/{PrivacyMaskSettings-temQSWYL.js → PrivacyMaskSettings-BvyW7gZf.js} +1 -1
  28. package/dist/assets/ProviderIcon-CS5qVLX5.js +1 -0
  29. package/dist/assets/{ScanNetworkModal-C6OLnfky.js → ScanNetworkModal-D8l7vvfO.js} +1 -1
  30. package/dist/assets/ServerManagement-CU7yGbqi.js +1 -0
  31. package/dist/assets/{Settings-BmZ2YcWY.js → Settings-afXspnHv.js} +1 -1
  32. package/dist/assets/{Showroom-CHFvHOSL.js → Showroom-ByFNrd3B.js} +1 -1
  33. package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-xXz7MEuT.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DmurZU5p.js} +1 -1
  34. package/dist/assets/addon-display-names-DvSEQty-.js +1 -0
  35. package/dist/assets/{build-cluster-graph-DIgt00ch.js → build-cluster-graph-BPT-sggI.js} +2 -2
  36. package/dist/assets/circle-check-big-CTwHEGsR.js +1 -0
  37. package/dist/assets/{copy-CpT57v81.js → copy-Dyvl96ei.js} +1 -1
  38. package/dist/assets/dist-ClgrIx6c.js +7 -0
  39. package/dist/assets/{dist-B8dNOlY9.js → dist-Udv3GGFK.js} +1 -1
  40. package/dist/assets/{download-fsWmKUMh.js → download-BFNY5_CW.js} +1 -1
  41. package/dist/assets/{hostInit-sp7Rf71V.js → hostInit-CagYACyE.js} +1 -1
  42. package/dist/assets/index-3DCschCe.js +4 -0
  43. package/dist/assets/index-BNTiPmxL.css +2 -0
  44. package/dist/assets/{key-round-0X280kmV.js → key-round-Bi4e5-k8.js} +1 -1
  45. package/dist/assets/{mf-entry-bootstrap-0-2b967ba8.js → mf-entry-bootstrap-0-b7b22ad0.js} +2 -2
  46. package/dist/assets/{pencil-BlQGw-pI.js → pencil-DedPunTk.js} +1 -1
  47. package/dist/assets/{player-overlays-CpsGl45o.js → player-overlays-BrMuuVRR.js} +1 -1
  48. package/dist/assets/plus-r3Kz9Nsb.js +1 -0
  49. package/dist/assets/{radio-DO0Dq2MF.js → radio-BM7T2fMm.js} +1 -1
  50. package/dist/assets/{refresh-cw-CMRlnF-M.js → refresh-cw-CC8OysCP.js} +1 -1
  51. package/dist/assets/remoteEntry-D9u56wxx.js +1 -0
  52. package/dist/assets/{rotate-ccw-CaH5zDeG.js → rotate-ccw-hTTLi20Q.js} +1 -1
  53. package/dist/assets/rotate-cw-BHsfPq8X.js +1 -0
  54. package/dist/assets/search-GJrj432A.js +1 -0
  55. package/dist/assets/{sparkles-D1oHkgOm.js → sparkles-DURbj_l0.js} +1 -1
  56. package/dist/assets/square-DXUXUdD9.js +1 -0
  57. package/dist/assets/{square-check-big-D7lGfpqc.js → square-check-big-B5WFnMH6.js} +1 -1
  58. package/dist/assets/src-D5vrhmeM.js +7 -0
  59. package/dist/assets/src-ojhqTnBF.js +67 -0
  60. package/dist/assets/{upload-7zSY3rlx.js → upload-DM5RHvd4.js} +1 -1
  61. package/dist/assets/{useDevice-BwzYPnLK.js → useDevice-BQkNwlm7.js} +1 -1
  62. package/dist/assets/{useEventInvalidation-CETyyXeZ.js → useEventInvalidation-BBDMvWpm.js} +1 -1
  63. package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-DkH43QoX.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-BbV1VRd0.js} +2 -2
  64. package/dist/assets/{wifi-BeF9XXWL.js → wifi-Cr9H7WCZ.js} +1 -1
  65. package/dist/assets/{zap-abOrEOMQ.js → zap-BWxQNiSd.js} +1 -1
  66. package/dist/index.html +6 -6
  67. package/dist/server/addon.js +308 -92
  68. package/package.json +1 -1
  69. package/dist/assets/AddonCollectionPage-C7y1Xqv4.js +0 -1
  70. package/dist/assets/Addons-BMHA1UvX.js +0 -1
  71. package/dist/assets/Cluster-dHKbt5S3.js +0 -1
  72. package/dist/assets/Data-Cgi4uVIl.js +0 -1
  73. package/dist/assets/DetectionIntelligence-B-VvnmfI.js +0 -1
  74. package/dist/assets/DeviceDetail-DiuVtjgW.js +0 -2
  75. package/dist/assets/Identity-B0ygozcS.js +0 -1
  76. package/dist/assets/IntegrationDetail-Brj01VUG.js +0 -1
  77. package/dist/assets/Integrations-DpfC2qld.js +0 -1
  78. package/dist/assets/MyAccess-DXmHi-4Y.js +0 -2
  79. package/dist/assets/Network-CaKLSIvm.js +0 -1
  80. package/dist/assets/Pipeline-Cp7B8YFG.js +0 -1
  81. package/dist/assets/ProviderIcon-DwFpv01K.js +0 -1
  82. package/dist/assets/circle-check-big-wzEehng2.js +0 -1
  83. package/dist/assets/dist-DRenWL4F.js +0 -7
  84. package/dist/assets/index-CY52lvbZ.js +0 -4
  85. package/dist/assets/index-_8k1nh07.css +0 -2
  86. package/dist/assets/plus-DSiRMRVx.js +0 -1
  87. package/dist/assets/remoteEntry-BTav0B7H.js +0 -1
  88. package/dist/assets/rotate-cw-CCcZjC0U.js +0 -1
  89. package/dist/assets/search-CN_ccU_h.js +0 -1
  90. package/dist/assets/server-CaW_paWO.js +0 -1
  91. package/dist/assets/square-DWukmPnU.js +0 -1
  92. package/dist/assets/src-BXL7z3gT.js +0 -7
  93. package/dist/assets/src-BZ1dd5LI.js +0 -67
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-Cc14_yxc.mjs
4632
+ //#region ../types/dist/sleep-DJaTV2D7.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5350,10 +5350,6 @@ function hydrateField(field, values) {
5350
5350
  };
5351
5351
  }
5352
5352
  const rawValue = storedValue !== void 0 ? storedValue : defaultValue !== void 0 ? defaultValue : null;
5353
- if (field.type === "password") return {
5354
- ...field,
5355
- value: ""
5356
- };
5357
5353
  const value = field.type === "textarea" && field.isJson && rawValue !== null && typeof rawValue === "object" ? JSON.stringify(rawValue, null, 2) : rawValue;
5358
5354
  return {
5359
5355
  ...field,
@@ -6737,18 +6733,21 @@ function method(input, output, options) {
6737
6733
  timeoutMs: options?.timeoutMs
6738
6734
  };
6739
6735
  }
6740
- var StaticDirOutputSchema = object({ staticDir: string() });
6741
- var VersionOutputSchema = object({ version: string() });
6736
+ var StaticDirOutputSchema$1 = object({ staticDir: string() });
6737
+ var VersionOutputSchema$1 = object({ version: string() });
6742
6738
  var adminUiCapability = {
6743
6739
  name: "admin-ui",
6744
6740
  scope: "system",
6745
6741
  mode: "singleton",
6746
6742
  internal: true,
6747
6743
  methods: {
6748
- getStaticDir: method(_void(), StaticDirOutputSchema),
6749
- getVersion: method(_void(), VersionOutputSchema)
6744
+ getStaticDir: method(_void(), StaticDirOutputSchema$1),
6745
+ getVersion: method(_void(), VersionOutputSchema$1)
6750
6746
  }
6751
6747
  };
6748
+ var StaticDirOutputSchema = object({ staticDir: string() });
6749
+ var VersionOutputSchema = object({ version: string() });
6750
+ method(_void(), StaticDirOutputSchema), method(_void(), VersionOutputSchema);
6752
6751
  /**
6753
6752
  * device-ops — device-scoped cap that unifies the per-IDevice operations
6754
6753
  * previously routed through the `.device-ops` Moleculer bridge service.
@@ -10306,7 +10305,7 @@ var BoundingBoxSchema = object({
10306
10305
  w: number(),
10307
10306
  h: number()
10308
10307
  });
10309
- var SpatialDetectionSchema = object({
10308
+ object({
10310
10309
  class: string(),
10311
10310
  originalClass: string(),
10312
10311
  score: number(),
@@ -10497,11 +10496,6 @@ var PipelineSchemaSchema = object({
10497
10496
  selectedEngine: PipelineEngineChoiceSchema,
10498
10497
  slots: array(PipelineSlotSchemaSchema).readonly()
10499
10498
  });
10500
- var DetectorOutputSchema = object({
10501
- detections: array(SpatialDetectionSchema).readonly(),
10502
- inferenceMs: number(),
10503
- modelId: string()
10504
- });
10505
10499
  var EngineProvisioningSchema = object({
10506
10500
  runtimeId: _enum([
10507
10501
  "onnx",
@@ -10626,7 +10620,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10626
10620
  auth: "admin"
10627
10621
  }), method(object({ nodeId: string() }), object({
10628
10622
  success: literal(true),
10629
- regeneratedModelId: string().nullable()
10623
+ clearedDevices: number()
10630
10624
  }), {
10631
10625
  kind: "mutation",
10632
10626
  auth: "admin"
@@ -10647,10 +10641,6 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10647
10641
  modelId: string(),
10648
10642
  format: ModelFormatSchema$1
10649
10643
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
10650
- addonId: string(),
10651
- frame: FrameInputSchema,
10652
- config: record(string(), unknown()).optional()
10653
- }), DetectorOutputSchema), method(object({
10654
10644
  engine: PipelineEngineChoiceSchema.optional(),
10655
10645
  steps: array(PipelineStepInputSchema).min(1),
10656
10646
  frame: FrameInputSchema.optional(),
@@ -12345,7 +12335,9 @@ var AddonPageDeclarationSchema$1 = object({
12345
12335
  icon: string(),
12346
12336
  path: string(),
12347
12337
  remoteName: string(),
12348
- bundle: string()
12338
+ bundle: string(),
12339
+ section: string().optional(),
12340
+ sectionLabel: string().optional()
12349
12341
  });
12350
12342
  var AddonPageInfoSchema = object({
12351
12343
  addonId: string(),
@@ -12385,7 +12377,18 @@ var AddonPageDeclarationSchema = object({
12385
12377
  * the static-file route can compute an mtime-based cache-buster URL
12386
12378
  * without a separate filesystem stat.
12387
12379
  */
12388
- bundle: string()
12380
+ bundle: string(),
12381
+ /**
12382
+ * Sidebar section this page docks into. Well-known ids: `'detection'`,
12383
+ * `'cluster'`, `'administration'` — the page renders inside that group.
12384
+ * Any OTHER string creates (or joins) a custom section rendered after
12385
+ * the built-in groups; its label comes from `sectionLabel` (first
12386
+ * declaration wins), falling back to the id. Absent → the legacy
12387
+ * "Addon Pages" group.
12388
+ */
12389
+ section: string().optional(),
12390
+ /** Display label for a CUSTOM `section` id (ignored for well-known ids). */
12391
+ sectionLabel: string().optional()
12389
12392
  });
12390
12393
  method(_void(), array(AddonPageDeclarationSchema).readonly());
12391
12394
  var AddonHttpRouteSchema = object({
@@ -12601,6 +12604,17 @@ var WidgetMetadataSchema = object({
12601
12604
  deviceContext: boolean().default(false),
12602
12605
  integrationContext: boolean().default(false)
12603
12606
  }),
12607
+ /**
12608
+ * Loadable BEFORE authentication. The normal widget registry listing
12609
+ * (`addon-widgets.listWidgets`) is auth-gated, so a pre-auth surface
12610
+ * (the login page) cannot discover a widget through it. A widget that
12611
+ * declares `preAuth: true` marks itself as safe to mount on a pre-auth
12612
+ * screen — it is surfaced through the PUBLIC `auth.listLoginMethods`
12613
+ * login-method contribution channel (see `login-method.cap.ts`) rather
12614
+ * than the authenticated registry, and its bundle is served by the
12615
+ * public `/api/addon-widgets/:addonId/*` static route. Defaults false.
12616
+ */
12617
+ preAuth: boolean().optional().default(false),
12604
12618
  /** Dashboard placement HINTS (operator can override per instance). */
12605
12619
  defaultSize: WidgetSizeEnum.default("md"),
12606
12620
  allowedSizes: array(WidgetSizeEnum).readonly().default([
@@ -12902,6 +12916,66 @@ method(object({
12902
12916
  password: string()
12903
12917
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
12904
12918
  /**
12919
+ * `login-method` — collection cap through which auth addons contribute
12920
+ * their pre-auth login surfaces to the login page. This is the SINGLE,
12921
+ * generic mechanism that supersedes the dead `auth.listProviders` reader:
12922
+ * every auth addon (OIDC, magic-link, WebAuthn/passkey) registers a
12923
+ * `login-method` provider and the PUBLIC `auth.listLoginMethods`
12924
+ * procedure aggregates them for the unauthenticated login page.
12925
+ *
12926
+ * A contribution is a discriminated union on `kind`:
12927
+ *
12928
+ * - `redirect` — a declarative button. The login page renders a generic
12929
+ * button that navigates to `startUrl` (an addon-owned HTTP route).
12930
+ * Covers OIDC (`/addon/auth-oidc/<id>/start`) and magic-link with
12931
+ * ZERO shell-side JS. A future SSO addon plugs in the same way — the
12932
+ * login page needs NO change.
12933
+ *
12934
+ * - `widget` — a Module-Federation widget the login page mounts (via
12935
+ * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
12936
+ * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
12937
+ * addon bundle. The referenced widget also declares `preAuth: true` in
12938
+ * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
12939
+ * stamps a public `bundleUrl` from `addonId` + `bundle`.
12940
+ *
12941
+ * Every contribution carries a `stage`:
12942
+ * - `primary` — shown on the first credentials screen (OIDC /
12943
+ * magic-link buttons; a future usernameless passkey).
12944
+ * - `second-factor` — shown AFTER the password leg, gated on the
12945
+ * returned `factors` (passkey-as-2FA today).
12946
+ *
12947
+ * `mount: skip` — the cap is read server-side by the core auth router
12948
+ * (`registry.getCollection('login-method')`), never mounted as its own
12949
+ * tRPC router.
12950
+ */
12951
+ /** When a login method renders in the two-phase login flow. */
12952
+ var LoginStageEnum = _enum(["primary", "second-factor"]);
12953
+ /** One login-method contribution — redirect button OR pre-auth widget. */
12954
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
12955
+ kind: literal("redirect"),
12956
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
12957
+ id: string(),
12958
+ /** Operator-facing button label. */
12959
+ label: string(),
12960
+ /** lucide-react icon name. */
12961
+ icon: string().optional(),
12962
+ /** Addon-owned HTTP route the button navigates to (GET). */
12963
+ startUrl: string(),
12964
+ stage: LoginStageEnum
12965
+ }), object({
12966
+ kind: literal("widget"),
12967
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
12968
+ id: string(),
12969
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
12970
+ addonId: string(),
12971
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
12972
+ bundle: string(),
12973
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
12974
+ remote: WidgetRemoteSchema,
12975
+ stage: LoginStageEnum
12976
+ })]);
12977
+ method(_void(), array(LoginMethodContributionSchema).readonly());
12978
+ /**
12905
12979
  * Orchestrator-side destination metadata. The orchestrator computes
12906
12980
  * `id = <addonId>:<subId>` from its provider lookup so consumers
12907
12981
  * (admin UI, restore flow) see one canonical key.
@@ -15219,7 +15293,12 @@ var AgentPipelineSettingsSchema = object({
15219
15293
  detectWeight: number().positive().optional(),
15220
15294
  /** Node is eligible to run the detection pipeline (decode + inference). */
15221
15295
  detect: boolean().optional(),
15222
- /** Node is eligible to host decoder sessions. */
15296
+ /**
15297
+ * DEPRECATED AND IGNORED. Decode is always co-located with its frame
15298
+ * consumer, so decode eligibility IS detect eligibility. Kept optional in
15299
+ * the schema ONLY so persisted stores written before the removal still
15300
+ * parse — no code reads it and no write path emits it.
15301
+ */
15223
15302
  decode: boolean().optional(),
15224
15303
  /** Node is eligible to run audio-analyzer sessions. */
15225
15304
  audio: boolean().optional(),
@@ -15280,25 +15359,6 @@ var PipelineAssignmentSchema = object({
15280
15359
  assignedAt: number()
15281
15360
  });
15282
15361
  /**
15283
- * Decoder placement record. Symmetric to `PipelineAssignmentSchema` but for
15284
- * the decoder-node placement domain (`balanceDecoder` decision: manual pin
15285
- * → co-located with pipeline → capacity).
15286
- */
15287
- var DecoderAssignmentSchema = object({
15288
- deviceId: number(),
15289
- /** Moleculer node id of the decoder provider currently responsible for this camera. */
15290
- decoderNodeId: string(),
15291
- /** True when the assignment was set manually via `assignDecoder`, false when chosen by the balancer. */
15292
- pinned: boolean(),
15293
- /** Why this assignment was made — useful for debugging the decoder balancer. */
15294
- reason: _enum([
15295
- "manual",
15296
- "co-located",
15297
- "capacity",
15298
- "hardware-affinity"
15299
- ])
15300
- });
15301
- /**
15302
15362
  * Per-agent load summary surfaced to the load balancer + dashboards.
15303
15363
  * Aggregated from each runner's `getLocalLoad` cap call.
15304
15364
  */
@@ -15504,15 +15564,6 @@ method(object({
15504
15564
  }), method(_void(), IngestOwnerSchema), method(object({
15505
15565
  deviceId: number(),
15506
15566
  nodeId: string()
15507
- }), _void(), {
15508
- kind: "mutation",
15509
- auth: "admin"
15510
- }), method(object({ deviceId: number() }), _void(), {
15511
- kind: "mutation",
15512
- auth: "admin"
15513
- }), method(_void(), array(DecoderAssignmentSchema).readonly()), method(object({
15514
- deviceId: number(),
15515
- nodeId: string()
15516
15567
  }), object({ success: literal(true) }), {
15517
15568
  kind: "mutation",
15518
15569
  auth: "admin"
@@ -15531,10 +15582,7 @@ method(object({
15531
15582
  nodeId: string(),
15532
15583
  pinned: boolean(),
15533
15584
  assignedAt: number()
15534
- }))), method(object({
15535
- deviceId: number(),
15536
- pipelineNodeId: string().optional()
15537
- }), DecoderAssignmentSchema), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15585
+ }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
15538
15586
  nodeId: string(),
15539
15587
  settings: AgentPipelineSettingsSchema
15540
15588
  })).readonly()), method(object({
@@ -15564,7 +15612,6 @@ method(object({
15564
15612
  }), method(object({
15565
15613
  agentNodeId: string(),
15566
15614
  detect: boolean().nullable().optional(),
15567
- decode: boolean().nullable().optional(),
15568
15615
  audio: boolean().nullable().optional(),
15569
15616
  ingest: boolean().nullable().optional()
15570
15617
  }), object({ success: literal(true) }), {
@@ -15576,6 +15623,15 @@ method(object({
15576
15623
  }), object({ success: literal(true) }), {
15577
15624
  kind: "mutation",
15578
15625
  auth: "admin"
15626
+ }), method(object({ agentNodeId: string() }), object({
15627
+ success: literal(true),
15628
+ /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
15629
+ effectiveModelId: string().nullable(),
15630
+ /** Number of cameras whose node-scoped overrides were cleared. */
15631
+ clearedCameraOverrides: number()
15632
+ }), {
15633
+ kind: "mutation",
15634
+ auth: "admin"
15579
15635
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15580
15636
  deviceId: number(),
15581
15637
  addonId: string(),
@@ -15621,6 +15677,131 @@ method(object({
15621
15677
  auth: "admin"
15622
15678
  });
15623
15679
  /**
15680
+ * server-management — per-NODE singleton capability for a node's ROOT
15681
+ * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
15682
+ * agents).
15683
+ *
15684
+ * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
15685
+ * on agents) carries the whole software stack in its npm dep tree, so ONE
15686
+ * version describes the node. Updates install into
15687
+ * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
15688
+ * starter (probation boot + auto-rollback to N-1).
15689
+ *
15690
+ * Providers:
15691
+ * - HUB: `ServerUpdateService` behind the `server-provided` mount
15692
+ * (`buildServerProviders` in trpc.router.ts) — the default target for
15693
+ * unpinned calls.
15694
+ * - AGENT: `AgentUpdateService` registered by the agent bootstrap under
15695
+ * the synthetic `agent-runtime` addonId and declared in the agent's
15696
+ * `$hub.registerNode` manifest.
15697
+ *
15698
+ * Node routing: singleton caps get the codegen/runtime-builder `nodeId`
15699
+ * injection on every method — `input.nodeId` (or `nodePin(nodeId)` from the
15700
+ * SDK) routes the call to that node's provider via the standard remote
15701
+ * proxy (`createCapabilityProxy` → `$agent-cap-fwd` → the agent's
15702
+ * in-process provider lookup). No `nodeId` → the hub's own provider.
15703
+ *
15704
+ * Spec: docs/superpowers/specs/2026-07-12-runtime-updatable-node-packages-design.md
15705
+ */
15706
+ /**
15707
+ * Where the running hub's code was loaded from:
15708
+ * - `workspace` — dev checkout (tsx / workspace dist); the starter defers to
15709
+ * plain resolution and runtime updates are refused.
15710
+ * - `baked` — the immutable image seed closure (no data-dir root active).
15711
+ * - `data-root` — the runtime-updatable `<dataDir>/server-root` closure.
15712
+ */
15713
+ var ServerBootModeSchema = _enum([
15714
+ "workspace",
15715
+ "baked",
15716
+ "data-root"
15717
+ ]);
15718
+ /**
15719
+ * Update lifecycle state:
15720
+ * - `idle` / `checking` / `staging` — steady / in-flight registry work.
15721
+ * - `pending-restart` — a version is staged and the node has NOT yet
15722
+ * restarted onto it (still running the OLD version).
15723
+ * - `awaiting-confirmation` — the node HAS restarted onto the staged version
15724
+ * (it is the active probation boot) and is waiting to confirm boot-health.
15725
+ * Apply/rollback are refused in this state and the node must NOT be
15726
+ * manually restarted, or the probation boot auto-rolls-back.
15727
+ */
15728
+ var ServerUpdateStateSchema = _enum([
15729
+ "idle",
15730
+ "checking",
15731
+ "staging",
15732
+ "pending-restart",
15733
+ "awaiting-confirmation"
15734
+ ]);
15735
+ var ServerRollbackInfoSchema = object({
15736
+ /** The version that failed (or was manually rolled back). */
15737
+ fromVersion: string(),
15738
+ /** The version rolled back to; null = the baked seed. */
15739
+ toVersion: string().nullable(),
15740
+ atMs: number(),
15741
+ reason: string()
15742
+ });
15743
+ var ServerPackageStatusSchema = object({
15744
+ /** Root package name (`@camstack/server` on the hub). */
15745
+ packageName: string(),
15746
+ /** Version of the code the running process ACTUALLY loaded. */
15747
+ runningVersion: string().nullable(),
15748
+ /** Node.js runtime version the node's process runs on (`process.versions.node`). */
15749
+ nodeRuntimeVersion: string().nullable(),
15750
+ /** Active data-dir root version; null when booted from seed/workspace. */
15751
+ activeVersion: string().nullable(),
15752
+ /** N-1 version kept for rollback; null when no previous version exists. */
15753
+ previousVersion: string().nullable(),
15754
+ /** Version of the immutable baked seed closure (image fallback). */
15755
+ seedVersion: string().nullable(),
15756
+ /** Latest registry version from the most recent check (null = never checked). */
15757
+ latestVersion: string().nullable(),
15758
+ updateAvailable: boolean(),
15759
+ bootMode: ServerBootModeSchema,
15760
+ updateState: ServerUpdateStateSchema,
15761
+ /** Version staged + awaiting its probation boot, when one is pending. */
15762
+ pendingVersion: string().nullable(),
15763
+ /** Set when the last freshly-activated version failed its boot health-check. */
15764
+ rolledBack: ServerRollbackInfoSchema.nullable(),
15765
+ /**
15766
+ * True when `server-root/state.json` EXISTS but is unreadable/corrupt — the
15767
+ * hub is running from the baked seed (or workspace) while installed data-dir
15768
+ * versions are being IGNORED. Surfaced as a warning in the UI.
15769
+ */
15770
+ stateFileCorrupt: boolean(),
15771
+ lastCheckedAtMs: number().nullable()
15772
+ });
15773
+ var ServerUpdateCheckResultSchema = object({
15774
+ packageName: string(),
15775
+ runningVersion: string().nullable(),
15776
+ latestVersion: string().nullable(),
15777
+ updateAvailable: boolean(),
15778
+ checkedAtMs: number(),
15779
+ /** Non-null when the registry lookup failed (offline, bad registry, …). */
15780
+ error: string().nullable()
15781
+ });
15782
+ var ServerUpdateActionResultSchema = object({
15783
+ accepted: boolean(),
15784
+ targetVersion: string().nullable(),
15785
+ /** True when a graceful restart was scheduled to apply the change. */
15786
+ restarting: boolean(),
15787
+ message: string()
15788
+ });
15789
+ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), ServerUpdateCheckResultSchema, {
15790
+ kind: "mutation",
15791
+ auth: "admin"
15792
+ }), method(object({
15793
+ /** Explicit target version; omitted = latest from the registry. */
15794
+ version: string().optional() }), ServerUpdateActionResultSchema, {
15795
+ kind: "mutation",
15796
+ auth: "admin"
15797
+ }), method(_void(), ServerUpdateActionResultSchema, {
15798
+ kind: "mutation",
15799
+ auth: "admin"
15800
+ }), method(_void(), ServerUpdateActionResultSchema, {
15801
+ kind: "mutation",
15802
+ auth: "admin"
15803
+ });
15804
+ /**
15624
15805
  * Query filter for settings-store collections.
15625
15806
  */
15626
15807
  var QueryFilterSchema = object({
@@ -17607,6 +17788,16 @@ var TopologyCategorySchema = object({
17607
17788
  healthy: number(),
17608
17789
  addons: array(TopologyCategoryAddonSchema).readonly()
17609
17790
  });
17791
+ /**
17792
+ * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
17793
+ * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
17794
+ * version visibility for the Server management surface. Nullable: offline
17795
+ * rows and pre-phase-2 nodes report none.
17796
+ */
17797
+ var TopologyRootPackageSchema = object({
17798
+ name: string(),
17799
+ version: string()
17800
+ });
17610
17801
  var TopologyNodeSchema = object({
17611
17802
  id: string(),
17612
17803
  name: string(),
@@ -17630,7 +17821,8 @@ var TopologyNodeSchema = object({
17630
17821
  status: string()
17631
17822
  })).readonly(),
17632
17823
  processes: array(TopologyProcessSchema).readonly(),
17633
- categories: array(TopologyCategorySchema).readonly()
17824
+ categories: array(TopologyCategorySchema).readonly(),
17825
+ rootPackage: TopologyRootPackageSchema.nullable()
17634
17826
  });
17635
17827
  var CapUsageEdgeSchema = object({
17636
17828
  callerAddonId: string(),
@@ -20430,6 +20622,12 @@ Object.freeze({
20430
20622
  addonId: null,
20431
20623
  access: "create"
20432
20624
  },
20625
+ "loginMethod.getLoginMethods": {
20626
+ capName: "login-method",
20627
+ capScope: "system",
20628
+ addonId: null,
20629
+ access: "view"
20630
+ },
20433
20631
  "mediaPlayer.next": {
20434
20632
  capName: "media-player",
20435
20633
  capScope: "device",
@@ -21060,23 +21258,23 @@ Object.freeze({
21060
21258
  addonId: null,
21061
21259
  access: "create"
21062
21260
  },
21063
- "pipelineExecutor.deleteModel": {
21261
+ "pipelineExecutor.clearDeviceOverrides": {
21064
21262
  capName: "pipeline-executor",
21065
21263
  capScope: "system",
21066
21264
  addonId: null,
21067
21265
  access: "delete"
21068
21266
  },
21069
- "pipelineExecutor.deleteTemplate": {
21267
+ "pipelineExecutor.deleteModel": {
21070
21268
  capName: "pipeline-executor",
21071
21269
  capScope: "system",
21072
21270
  addonId: null,
21073
21271
  access: "delete"
21074
21272
  },
21075
- "pipelineExecutor.detect": {
21273
+ "pipelineExecutor.deleteTemplate": {
21076
21274
  capName: "pipeline-executor",
21077
21275
  capScope: "system",
21078
21276
  addonId: null,
21079
- access: "view"
21277
+ access: "delete"
21080
21278
  },
21081
21279
  "pipelineExecutor.downloadModel": {
21082
21280
  capName: "pipeline-executor",
@@ -21222,12 +21420,6 @@ Object.freeze({
21222
21420
  addonId: null,
21223
21421
  access: "create"
21224
21422
  },
21225
- "pipelineExecutor.resetToDefault": {
21226
- capName: "pipeline-executor",
21227
- capScope: "system",
21228
- addonId: null,
21229
- access: "delete"
21230
- },
21231
21423
  "pipelineExecutor.runAudioTest": {
21232
21424
  capName: "pipeline-executor",
21233
21425
  capScope: "system",
@@ -21288,12 +21480,6 @@ Object.freeze({
21288
21480
  addonId: null,
21289
21481
  access: "create"
21290
21482
  },
21291
- "pipelineOrchestrator.assignDecoder": {
21292
- capName: "pipeline-orchestrator",
21293
- capScope: "system",
21294
- addonId: null,
21295
- access: "create"
21296
- },
21297
21483
  "pipelineOrchestrator.assignPipeline": {
21298
21484
  capName: "pipeline-orchestrator",
21299
21485
  capScope: "system",
@@ -21372,18 +21558,6 @@ Object.freeze({
21372
21558
  addonId: null,
21373
21559
  access: "view"
21374
21560
  },
21375
- "pipelineOrchestrator.getDecoderAssignment": {
21376
- capName: "pipeline-orchestrator",
21377
- capScope: "system",
21378
- addonId: null,
21379
- access: "view"
21380
- },
21381
- "pipelineOrchestrator.getDecoderAssignments": {
21382
- capName: "pipeline-orchestrator",
21383
- capScope: "system",
21384
- addonId: null,
21385
- access: "view"
21386
- },
21387
21561
  "pipelineOrchestrator.getGlobalMetrics": {
21388
21562
  capName: "pipeline-orchestrator",
21389
21563
  capScope: "system",
@@ -21432,6 +21606,12 @@ Object.freeze({
21432
21606
  addonId: null,
21433
21607
  access: "delete"
21434
21608
  },
21609
+ "pipelineOrchestrator.resetNodePipelineDefaults": {
21610
+ capName: "pipeline-orchestrator",
21611
+ capScope: "system",
21612
+ addonId: null,
21613
+ access: "delete"
21614
+ },
21435
21615
  "pipelineOrchestrator.resolvePipeline": {
21436
21616
  capName: "pipeline-orchestrator",
21437
21617
  capScope: "system",
@@ -21504,12 +21684,6 @@ Object.freeze({
21504
21684
  addonId: null,
21505
21685
  access: "create"
21506
21686
  },
21507
- "pipelineOrchestrator.unassignDecoder": {
21508
- capName: "pipeline-orchestrator",
21509
- capScope: "system",
21510
- addonId: null,
21511
- access: "create"
21512
- },
21513
21687
  "pipelineOrchestrator.unassignPipeline": {
21514
21688
  capName: "pipeline-orchestrator",
21515
21689
  capScope: "system",
@@ -21816,6 +21990,36 @@ Object.freeze({
21816
21990
  addonId: null,
21817
21991
  access: "create"
21818
21992
  },
21993
+ "serverManagement.applyServerUpdate": {
21994
+ capName: "server-management",
21995
+ capScope: "system",
21996
+ addonId: null,
21997
+ access: "create"
21998
+ },
21999
+ "serverManagement.checkServerUpdate": {
22000
+ capName: "server-management",
22001
+ capScope: "system",
22002
+ addonId: null,
22003
+ access: "create"
22004
+ },
22005
+ "serverManagement.getServerPackageStatus": {
22006
+ capName: "server-management",
22007
+ capScope: "system",
22008
+ addonId: null,
22009
+ access: "view"
22010
+ },
22011
+ "serverManagement.restartServer": {
22012
+ capName: "server-management",
22013
+ capScope: "system",
22014
+ addonId: null,
22015
+ access: "create"
22016
+ },
22017
+ "serverManagement.rollbackServerUpdate": {
22018
+ capName: "server-management",
22019
+ capScope: "system",
22020
+ addonId: null,
22021
+ access: "create"
22022
+ },
21819
22023
  "settingsStore.count": {
21820
22024
  capName: "settings-store",
21821
22025
  capScope: "system",
@@ -22680,6 +22884,18 @@ Object.freeze({
22680
22884
  addonId: null,
22681
22885
  access: "view"
22682
22886
  },
22887
+ "viewerUi.getStaticDir": {
22888
+ capName: "viewer-ui",
22889
+ capScope: "system",
22890
+ addonId: null,
22891
+ access: "view"
22892
+ },
22893
+ "viewerUi.getVersion": {
22894
+ capName: "viewer-ui",
22895
+ capScope: "system",
22896
+ addonId: null,
22897
+ access: "view"
22898
+ },
22683
22899
  "waterHeater.setAway": {
22684
22900
  capName: "water-heater",
22685
22901
  capScope: "device",
@@ -22866,7 +23082,7 @@ var AdminUIAddon = class extends BaseAddon {
22866
23082
  capability: adminUiCapability,
22867
23083
  provider: {
22868
23084
  getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
22869
- getVersion: async () => ({ version: "1.1.38" })
23085
+ getVersion: async () => ({ version: "1.1.40" })
22870
23086
  }
22871
23087
  }];
22872
23088
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-admin-ui",
3
- "version": "1.1.38",
3
+ "version": "1.1.40",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "CamStack Admin UI — Vite frontend build and server-side addon",
@@ -1 +0,0 @@
1
- import{$i as e,Tt as t,bt as n,d as r,ea as i,g as a,ja as o,ka as s,m as c}from"./src-BZ1dd5LI.js";import{Q as l,S as u,o as d,q as f,x as p,z as m}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DTufy7Ue.js";import{t as h}from"./plus-DSiRMRVx.js";import{t as g}from"./refresh-cw-CMRlnF-M.js";import{t as _}from"./square-DWukmPnU.js";import{H as v,P as y,R as b,V as x,p as S,x as C}from"./index-CY52lvbZ.js";import{t as w}from"./AdminPage-BwmGKnRf.js";import{t as T}from"./NodeAddonsSettingsPanel-DTzycFzS.js";var E=x(`play`,[[`polygon`,{points:`6 3 20 12 6 21 6 3`,key:`1oa8hb`}]]);l();function D({addonId:e,fallback:t,tileClassName:n,iconPath:r=`assets/icon.svg`}){let[i,a]=f(!1),o=`/api/addon-assets/${e}/${r}`;return p(`div`,{className:`h-10 w-10 rounded-lg flex items-center justify-center shrink-0 ${n}`,children:i?p(t,{className:`h-5 w-5`}):p(`img`,{src:o,alt:e,className:`h-7 w-7 rounded-md bg-white p-1 ring-1 ring-black/5`,onError:()=>a(!0)})})}l();function O({addonId:e,defaultActivity:t,showActivity:n=!0,maxHeight:r=`max-h-64`,defaultTab:i,capability:o}){let[s,l]=f(t??(i===`events`?`events`:`logs`));return u(`div`,{className:`flex flex-col gap-4`,children:[p(T,{nodeId:`hub`,addonIds:[e],level:`global`,capability:o}),n&&u(`div`,{className:`rounded-lg border border-border bg-surface overflow-hidden`,children:[u(`div`,{className:`flex items-center justify-between px-3 py-2 border-b border-border bg-surface-hover/20`,children:[p(`span`,{className:`text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide`,children:`Activity`}),u(`div`,{className:`flex items-center gap-1`,children:[p(k,{kind:`logs`,active:s===`logs`,onClick:()=>l(`logs`)}),p(k,{kind:`events`,active:s===`events`,onClick:()=>l(`events`)})]})]}),s===`logs`?p(a,{addonId:e,maxHeight:r,showFilters:!1}):p(c,{addonId:e,category:`addon.*`,maxHeight:r})]})]})}function k({kind:e,active:t,onClick:n}){return u(`button`,{onClick:n,className:`inline-flex items-center gap-1 rounded px-2 py-0.5 text-[11px] font-medium transition-colors ${t?`bg-primary/10 text-primary`:`text-foreground-subtle hover:text-foreground hover:bg-surface-hover`}`,children:[p(e===`logs`?S:b,{className:`h-3 w-3`}),e===`logs`?`Logs`:`Events`]})}l();function A(t){let{title:n,subtitle:r,pageIcon:a,itemIcon:c,capability:l,installButtonLabel:d=`Add addon`,items:g,isLoading:_,emptyTitle:b=`No addons installed for this capability`,emptyDescription:x,itemIconColor:S,renderStatusBadges:C,renderPrimaryAction:T,itemError:E,renderExpandedPanel:k,workspaceMaxHeight:A=`max-h-72`,trailing:P,showChrome:F=!1}=t,I=g.length>1,[L,R]=f(()=>g[0]?.addonId??null);m(()=>{L&&(g.some(e=>e.addonId===L)||R(g[0]?.addonId??null))},[g,L]);let z=e=>R(t=>t===e?null:e),B=`/system/addons?capability=${encodeURIComponent(l)}`;return p(w,{icon:F?a:void 0,title:F?n:void 0,subtitle:F?r:void 0,actions:F?p(v,{to:B,children:u(o,{variant:`primary`,size:`sm`,children:[p(h,{className:`h-3.5 w-3.5 mr-1`}),d]})}):void 0,children:_?p(s,{children:p(`div`,{className:`p-6 text-sm text-foreground-subtle`,children:`Loading…`})}):g.length===0?p(s,{children:p(i,{title:b,description:x??`Install an addon that declares the "${l}" capability to get started.`,action:F?p(v,{to:B,children:u(o,{variant:`primary`,size:`sm`,children:[p(h,{className:`h-3.5 w-3.5 mr-1`}),d]})}):void 0})}):u(`div`,{className:`flex flex-col gap-4`,children:[g.map(t=>{let n=!I||L===t.addonId,r=S?.(t)??(t.isActive?`bg-emerald-500/15 text-emerald-700 dark:text-emerald-300`:`bg-foreground-subtle/15 text-foreground-subtle`),i=E?.(t)??null;return u(s,{children:[u(`div`,{className:`flex flex-col gap-3 p-4 sm:flex-row sm:items-center ${n?`border-b border-border`:``}`,children:[u(`div`,{className:`flex items-center gap-3 flex-1 min-w-0`,children:[I&&p(`button`,{type:`button`,onClick:()=>z(t.addonId),"aria-label":n?`Collapse`:`Expand`,className:`shrink-0 p-1 rounded hover:bg-foreground-subtle/10 transition-colors`,children:p(y,{className:`h-4 w-4 text-foreground-subtle transition-transform ${n?`rotate-180`:``}`})}),u(`button`,{type:`button`,onClick:()=>I&&z(t.addonId),className:`flex items-center gap-4 flex-1 min-w-0 text-left ${I?`hover:opacity-80 transition-opacity`:``}`,disabled:!I,children:[p(D,{addonId:t.addonId,fallback:c,tileClassName:r}),u(`div`,{className:`flex-1 min-w-0`,children:[u(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[p(`span`,{className:`font-semibold text-foreground`,children:t.displayName}),p(j,{isActive:t.isActive}),C?.(t)]}),u(`div`,{className:`text-xs text-foreground-subtle mt-1 font-mono break-all`,children:[`@camstack/addon-`,t.addonId]})]})]})]}),u(`div`,{className:`flex items-center gap-1 shrink-0 flex-wrap justify-end`,children:[T?.(t),p(M,{capName:l,addonId:t.addonId,isActive:t.isActive}),p(N,{addonId:t.addonId,displayName:t.displayName})]})]}),n&&u(`div`,{className:`p-4 flex flex-col gap-3`,children:[i!==null&&p(e,{message:i}),k?.(t),p(O,{addonId:t.addonId,maxHeight:A,capability:l})]})]},t.addonId)}),P]})})}function j({isActive:e}){return p(`span`,{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${e?`bg-emerald-500/15 text-emerald-700 dark:text-emerald-300`:`bg-foreground-subtle/15 text-foreground-subtle`}`,children:e?`Enabled`:`Disabled`})}function M({capName:e,addonId:n,isActive:r}){let i=d(),a=t({onSuccess:()=>{i.invalidateQueries({queryKey:[[`addons`,`listCapabilityProviders`]]})}}),s=a.isPending;return u(o,{size:`sm`,variant:r?`secondary`:`primary`,disabled:s,onClick:()=>a.mutate({capName:e,addonId:n,enabled:!r}),children:[s?p(C,{className:`h-3 w-3 animate-spin`}):p(r?_:E,{className:`h-3 w-3`}),r?`Disable`:`Enable`]})}function N({addonId:e,displayName:t}){let i=d(),a=n({onSuccess:()=>{i.invalidateQueries({queryKey:[[`addons`,`listCapabilityProviders`]]})}});return p(r,{label:`Restart`,icon:g,size:`sm`,title:`Restart "${t}"?`,description:`Restarting the addon bounces its subprocess — the provider will briefly drop and reconnect automatically.`,confirmLabel:`Restart`,triggerVariant:`ghost`,confirmVariant:`danger`,disabled:a.isPending,action:()=>a.mutateAsync({addonId:e})})}export{E as n,A as t};