@camstack/addon-provider-rtsp 1.0.3 → 1.0.5

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 +315 -30
  2. package/dist/addon.mjs +315 -30
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -4996,6 +4996,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4996
4996
  */
4997
4997
  EventCategory["PipelineEngineMetricsSnapshot"] = "pipeline.engine-metrics-snapshot";
4998
4998
  /**
4999
+ * Per-node detection-engine runtime-provisioning transition. Emitted by
5000
+ * the detection-pipeline provider on every state change of its lazy
5001
+ * engine-provisioning machine (idle → installing → verifying → ready,
5002
+ * or → failed with a `nextRetryAt`). Payload is the
5003
+ * `EngineProvisioningState` snapshot; `event.source.nodeId` carries the
5004
+ * node. The Pipeline page subscribes to drive a live "installing
5005
+ * OpenVINO… / ready" indicator per node without polling
5006
+ * `pipelineExecutor.getEngineProvisioning`. Telemetry-grade (D8): the UI
5007
+ * also reads the cap snapshot on mount / reconnect. Phase 2.
5008
+ */
5009
+ EventCategory["PipelineEngineProvisioning"] = "pipeline.engine-provisioning";
5010
+ /**
4999
5011
  * Cluster topology snapshot. Carries the same payload returned by
5000
5012
  * `nodes.topology` (every reachable node + addons + processes).
5001
5013
  * Emitted by the hub on any agent / addon lifecycle change
@@ -5145,14 +5157,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5145
5157
  EventCategory["DeviceSleeping"] = "device.sleeping";
5146
5158
  EventCategory["RetentionCleanup"] = "retention.cleanup";
5147
5159
  /**
5148
- * Progress snapshot emitted by `BulkUpdateCoordinator` on every state
5149
- * transition (item status change, phase change, completion, cancel).
5150
- * Payload is `BulkUpdateState`. Admin UI subscribes via `useLiveEvent`
5151
- * to drive the sticky `BulkUpdateBanner` and per-row `AddonRowBadge`.
5152
- *
5153
- * Spec: docs/superpowers/specs/2026-05-21-addons-bulk-update-progress-design.md
5160
+ * Legacy bulk-update progress snapshot (payload `BulkUpdateState`). No longer
5161
+ * emitted F3 removed the coordinator that produced it; "Update all" now runs
5162
+ * as one lifecycle engine job (`AddonsJobProgress`/`AddonsJobLog`). Retained
5163
+ * (with `BulkUpdateState`) only to avoid regenerating the event maps; removed
5164
+ * in F4 once live bulk progress is re-implemented over the engine events.
5154
5165
  */
5155
5166
  EventCategory["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
5167
+ EventCategory["AddonsJobProgress"] = "addons.job-progress";
5168
+ EventCategory["AddonsJobLog"] = "addons.job-log";
5156
5169
  /**
5157
5170
  * A container's child visibility toggled (hidden/shown). Emitted by the
5158
5171
  * `accessories` cap when a child device is hidden or revealed.
@@ -10390,6 +10403,24 @@ var DetectorOutputSchema = object({
10390
10403
  inferenceMs: number(),
10391
10404
  modelId: string()
10392
10405
  });
10406
+ var EngineProvisioningSchema = object({
10407
+ runtimeId: _enum([
10408
+ "onnx",
10409
+ "openvino",
10410
+ "coreml"
10411
+ ]).nullable(),
10412
+ device: string().nullable(),
10413
+ state: _enum([
10414
+ "idle",
10415
+ "installing",
10416
+ "verifying",
10417
+ "ready",
10418
+ "failed"
10419
+ ]),
10420
+ progress: number().optional(),
10421
+ error: string().optional(),
10422
+ nextRetryAt: number().optional()
10423
+ });
10393
10424
  var PipelineStepInputSchema = lazy(() => object({
10394
10425
  addonId: string(),
10395
10426
  modelId: string(),
@@ -10458,7 +10489,7 @@ var PipelineRunResultBridge = custom();
10458
10489
  method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
10459
10490
  kind: "mutation",
10460
10491
  auth: "admin"
10461
- }), method(_void(), record(string(), object({
10492
+ }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
10462
10493
  modelId: string(),
10463
10494
  settings: record(string(), unknown()).readonly()
10464
10495
  }))), method(object({ steps: record(string(), object({
@@ -15614,7 +15645,10 @@ var AgentAddonConfigSchema = object({
15614
15645
  modelId: string(),
15615
15646
  settings: record(string(), unknown()).readonly()
15616
15647
  });
15617
- var AgentPipelineSettingsSchema = object({ addonDefaults: record(string(), AgentAddonConfigSchema).readonly() });
15648
+ var AgentPipelineSettingsSchema = object({
15649
+ addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
15650
+ maxCameras: number().int().nonnegative().nullable().default(null)
15651
+ });
15618
15652
  var CameraPipelineForAgentSchema = object({
15619
15653
  steps: array(PipelineStepInputSchema).readonly(),
15620
15654
  audio: object({
@@ -15716,6 +15750,133 @@ var GlobalMetricsSchema = object({
15716
15750
  * capability providers.
15717
15751
  */
15718
15752
  var CapabilityBindingsSchema = record(string(), string());
15753
+ /** Source block — always present; derives from the stream catalog. */
15754
+ var CameraSourceStatusSchema = object({ streams: array(object({
15755
+ camStreamId: string(),
15756
+ codec: string(),
15757
+ width: number(),
15758
+ height: number(),
15759
+ fps: number(),
15760
+ kind: string()
15761
+ })).readonly() });
15762
+ /** Assignment block — always present (orchestrator-local, no remote call). */
15763
+ var CameraAssignmentStatusSchema = object({
15764
+ detectionNodeId: string().nullable(),
15765
+ decoderNodeId: string().nullable(),
15766
+ audioNodeId: string().nullable(),
15767
+ pinned: object({
15768
+ detection: boolean(),
15769
+ decoder: boolean(),
15770
+ audio: boolean()
15771
+ }),
15772
+ reasons: object({
15773
+ detection: string().optional(),
15774
+ decoder: string().optional(),
15775
+ audio: string().optional()
15776
+ })
15777
+ });
15778
+ /** Broker block — null when the broker stage is unreachable or inactive. */
15779
+ var CameraBrokerStatusSchema = object({
15780
+ profiles: array(object({
15781
+ profile: string(),
15782
+ status: string(),
15783
+ codec: string(),
15784
+ width: number(),
15785
+ height: number(),
15786
+ subscribers: number(),
15787
+ inFps: number(),
15788
+ outFps: number()
15789
+ })).readonly(),
15790
+ webrtcSessions: number(),
15791
+ rtspRestream: boolean()
15792
+ });
15793
+ /** Shared-memory ring statistics within the decoder block. */
15794
+ var CameraDecoderShmSchema = object({
15795
+ framesWritten: number(),
15796
+ getFrameHits: number(),
15797
+ getFrameMisses: number(),
15798
+ budgetMb: number()
15799
+ });
15800
+ /** Decoder block — null when the decoder stage is unreachable or inactive. */
15801
+ var CameraDecoderStatusSchema = object({
15802
+ nodeId: string(),
15803
+ formats: array(string()).readonly(),
15804
+ sessionCount: number(),
15805
+ shm: CameraDecoderShmSchema
15806
+ });
15807
+ /** Motion block — null when motion detection is not active for this device. */
15808
+ var CameraMotionStatusSchema = object({
15809
+ enabled: boolean(),
15810
+ fps: number()
15811
+ });
15812
+ /** Detection provisioning sub-block. */
15813
+ var CameraDetectionProvisioningSchema = object({
15814
+ state: _enum([
15815
+ "idle",
15816
+ "installing",
15817
+ "verifying",
15818
+ "ready",
15819
+ "failed"
15820
+ ]),
15821
+ error: string().optional()
15822
+ });
15823
+ /** Detection phase — derived from the runner's engine phase. */
15824
+ var CameraDetectionPhaseSchema = _enum([
15825
+ "idle",
15826
+ "watching",
15827
+ "active"
15828
+ ]);
15829
+ /** Detection block — null when no detection node is assigned or reachable. */
15830
+ var CameraDetectionStatusSchema = object({
15831
+ nodeId: string(),
15832
+ engine: object({
15833
+ backend: string(),
15834
+ device: string()
15835
+ }),
15836
+ phase: CameraDetectionPhaseSchema,
15837
+ configuredFps: number(),
15838
+ actualFps: number(),
15839
+ queueDepth: number(),
15840
+ avgInferenceMs: number(),
15841
+ provisioning: CameraDetectionProvisioningSchema
15842
+ });
15843
+ /** Audio block — null when no audio node is assigned or reachable. */
15844
+ var CameraAudioStatusSchema = object({
15845
+ nodeId: string(),
15846
+ enabled: boolean()
15847
+ });
15848
+ /** Recording block — null when no recording cap is active for this device. */
15849
+ var CameraRecordingStatusSchema = object({
15850
+ mode: _enum([
15851
+ "off",
15852
+ "continuous",
15853
+ "events"
15854
+ ]),
15855
+ active: boolean(),
15856
+ storageBytes: number()
15857
+ });
15858
+ /**
15859
+ * Aggregated per-camera pipeline status — server-composed, single call.
15860
+ *
15861
+ * The `assignment` and `source` blocks are always present.
15862
+ * Every other block is `null` when the stage is inactive or unreachable
15863
+ * during the bounded parallel fan-out in the orchestrator implementation.
15864
+ *
15865
+ * See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
15866
+ */
15867
+ var CameraStatusSchema = object({
15868
+ deviceId: number(),
15869
+ assignment: CameraAssignmentStatusSchema,
15870
+ source: CameraSourceStatusSchema,
15871
+ broker: CameraBrokerStatusSchema.nullable(),
15872
+ decoder: CameraDecoderStatusSchema.nullable(),
15873
+ motion: CameraMotionStatusSchema.nullable(),
15874
+ detection: CameraDetectionStatusSchema.nullable(),
15875
+ audio: CameraAudioStatusSchema.nullable(),
15876
+ recording: CameraRecordingStatusSchema.nullable(),
15877
+ /** Unix timestamp (ms) when this snapshot was composed server-side. */
15878
+ fetchedAt: number()
15879
+ });
15719
15880
  method(object({
15720
15881
  deviceId: number(),
15721
15882
  agentNodeId: string()
@@ -15783,6 +15944,12 @@ method(object({
15783
15944
  }), {
15784
15945
  kind: "mutation",
15785
15946
  auth: "admin"
15947
+ }), method(object({
15948
+ agentNodeId: string(),
15949
+ maxCameras: number().int().nonnegative().nullable()
15950
+ }), object({ success: literal(true) }), {
15951
+ kind: "mutation",
15952
+ auth: "admin"
15786
15953
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15787
15954
  deviceId: number(),
15788
15955
  addonId: string(),
@@ -15808,7 +15975,7 @@ method(object({
15808
15975
  }), method(object({
15809
15976
  deviceId: number(),
15810
15977
  agentNodeId: string().optional()
15811
- }), CameraPipelineConfigSchema), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
15978
+ }), CameraPipelineConfigSchema), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
15812
15979
  name: string(),
15813
15980
  description: string().optional(),
15814
15981
  config: CameraPipelineConfigSchema
@@ -18828,6 +18995,69 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
18828
18995
  kind: "mutation",
18829
18996
  auth: "admin"
18830
18997
  });
18998
+ var jobKindSchema = _enum([
18999
+ "install",
19000
+ "update",
19001
+ "uninstall",
19002
+ "restart"
19003
+ ]);
19004
+ var taskPhaseSchema = _enum([
19005
+ "queued",
19006
+ "fetching",
19007
+ "staged",
19008
+ "validating",
19009
+ "applying",
19010
+ "restarting",
19011
+ "applied",
19012
+ "done",
19013
+ "failed",
19014
+ "skipped"
19015
+ ]);
19016
+ var taskTargetSchema = _enum(["framework", "addon"]);
19017
+ var taskLogEntrySchema = object({
19018
+ tsMs: number(),
19019
+ nodeId: string(),
19020
+ packageName: string(),
19021
+ phase: taskPhaseSchema,
19022
+ message: string()
19023
+ });
19024
+ var lifecycleTaskSchema = object({
19025
+ taskId: string(),
19026
+ nodeId: string(),
19027
+ packageName: string(),
19028
+ fromVersion: string().nullable(),
19029
+ toVersion: string(),
19030
+ target: taskTargetSchema,
19031
+ phase: taskPhaseSchema,
19032
+ stagedPath: string().nullable(),
19033
+ attempts: number(),
19034
+ steps: array(taskLogEntrySchema),
19035
+ error: string().nullable(),
19036
+ startedAtMs: number().nullable(),
19037
+ finishedAtMs: number().nullable()
19038
+ });
19039
+ var lifecycleJobStateSchema = _enum([
19040
+ "running",
19041
+ "completed",
19042
+ "failed",
19043
+ "partially-failed",
19044
+ "cancelled"
19045
+ ]);
19046
+ var lifecycleJobScopeSchema = _enum([
19047
+ "single",
19048
+ "bulk",
19049
+ "cluster"
19050
+ ]);
19051
+ var lifecycleJobSchema = object({
19052
+ jobId: string(),
19053
+ kind: jobKindSchema,
19054
+ createdAtMs: number(),
19055
+ createdBy: string(),
19056
+ scope: lifecycleJobScopeSchema,
19057
+ tasks: array(lifecycleTaskSchema),
19058
+ state: lifecycleJobStateSchema,
19059
+ schemaVersion: literal(1)
19060
+ });
18831
19061
  /**
18832
19062
  * addons — system-scoped singleton capability for addon package
18833
19063
  * management (install, update, configure, restart) and per-addon log
@@ -19010,7 +19240,7 @@ var BulkUpdatePhaseSchema = _enum([
19010
19240
  "restarting",
19011
19241
  "finalizing"
19012
19242
  ]);
19013
- var BulkUpdateStateSchema = object({
19243
+ object({
19014
19244
  id: string(),
19015
19245
  nodeId: string(),
19016
19246
  startedAtMs: number(),
@@ -19113,20 +19343,7 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
19113
19343
  }), UpdateFrameworkPackageResultSchema, {
19114
19344
  kind: "mutation",
19115
19345
  auth: "admin"
19116
- }), method(object({
19117
- nodeId: string(),
19118
- items: array(object({
19119
- name: string(),
19120
- version: string(),
19121
- isSystem: boolean()
19122
- })).readonly()
19123
- }), object({ id: string() }), {
19124
- kind: "mutation",
19125
- auth: "admin"
19126
- }), method(object({ id: string() }), BulkUpdateStateSchema.nullable(), { auth: "admin" }), method(object({ id: string() }), object({ cancelled: boolean() }), {
19127
- kind: "mutation",
19128
- auth: "admin"
19129
- }), method(object({ nodeId: string().optional() }), array(BulkUpdateStateSchema).readonly(), { auth: "admin" }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
19346
+ }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
19130
19347
  kind: "mutation",
19131
19348
  auth: "admin"
19132
19349
  }), method(object({ packageName: string() }), object({ success: literal(true) }), {
@@ -19148,6 +19365,24 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
19148
19365
  kind: "mutation",
19149
19366
  auth: "admin"
19150
19367
  }), method(CustomActionInputSchema, unknown(), { kind: "mutation" }), method(object({
19368
+ kind: _enum([
19369
+ "install",
19370
+ "update",
19371
+ "uninstall",
19372
+ "restart"
19373
+ ]),
19374
+ targets: array(object({
19375
+ name: string().min(1),
19376
+ version: string().min(1)
19377
+ })).min(1),
19378
+ nodeIds: array(string()).optional()
19379
+ }), object({ jobId: string() }), {
19380
+ kind: "mutation",
19381
+ auth: "admin"
19382
+ }), method(object({ jobId: string() }), lifecycleJobSchema.nullable(), { auth: "admin" }), method(object({ activeOnly: boolean().optional() }), array(lifecycleJobSchema), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
19383
+ kind: "mutation",
19384
+ auth: "admin"
19385
+ }), method(object({
19151
19386
  addonId: string(),
19152
19387
  level: LogLevelSchema$1.optional()
19153
19388
  }), LogStreamEntrySchema, { kind: "subscription" });
@@ -19188,7 +19423,7 @@ Object.freeze({
19188
19423
  addonId: null,
19189
19424
  access: "create"
19190
19425
  },
19191
- "addons.cancelBulkUpdate": {
19426
+ "addons.cancelJob": {
19192
19427
  capName: "addons",
19193
19428
  capScope: "system",
19194
19429
  addonId: null,
@@ -19218,7 +19453,7 @@ Object.freeze({
19218
19453
  addonId: null,
19219
19454
  access: "view"
19220
19455
  },
19221
- "addons.getBulkUpdateState": {
19456
+ "addons.getJob": {
19222
19457
  capName: "addons",
19223
19458
  capScope: "system",
19224
19459
  addonId: null,
@@ -19266,19 +19501,19 @@ Object.freeze({
19266
19501
  addonId: null,
19267
19502
  access: "view"
19268
19503
  },
19269
- "addons.listActiveBulkUpdates": {
19504
+ "addons.listCapabilityProviders": {
19270
19505
  capName: "addons",
19271
19506
  capScope: "system",
19272
19507
  addonId: null,
19273
19508
  access: "view"
19274
19509
  },
19275
- "addons.listCapabilityProviders": {
19510
+ "addons.listFrameworkPackages": {
19276
19511
  capName: "addons",
19277
19512
  capScope: "system",
19278
19513
  addonId: null,
19279
19514
  access: "view"
19280
19515
  },
19281
- "addons.listFrameworkPackages": {
19516
+ "addons.listJobs": {
19282
19517
  capName: "addons",
19283
19518
  capScope: "system",
19284
19519
  addonId: null,
@@ -19362,7 +19597,7 @@ Object.freeze({
19362
19597
  addonId: null,
19363
19598
  access: "create"
19364
19599
  },
19365
- "addons.startBulkUpdate": {
19600
+ "addons.startJob": {
19366
19601
  capName: "addons",
19367
19602
  capScope: "system",
19368
19603
  addonId: null,
@@ -21588,6 +21823,12 @@ Object.freeze({
21588
21823
  addonId: null,
21589
21824
  access: "view"
21590
21825
  },
21826
+ "pipelineExecutor.getEngineProvisioning": {
21827
+ capName: "pipeline-executor",
21828
+ capScope: "system",
21829
+ addonId: null,
21830
+ access: "view"
21831
+ },
21591
21832
  "pipelineExecutor.getGlobalPipelineConfig": {
21592
21833
  capName: "pipeline-executor",
21593
21834
  capScope: "system",
@@ -21792,6 +22033,18 @@ Object.freeze({
21792
22033
  addonId: null,
21793
22034
  access: "view"
21794
22035
  },
22036
+ "pipelineOrchestrator.getCameraStatus": {
22037
+ capName: "pipeline-orchestrator",
22038
+ capScope: "system",
22039
+ addonId: null,
22040
+ access: "view"
22041
+ },
22042
+ "pipelineOrchestrator.getCameraStatuses": {
22043
+ capName: "pipeline-orchestrator",
22044
+ capScope: "system",
22045
+ addonId: null,
22046
+ access: "view"
22047
+ },
21795
22048
  "pipelineOrchestrator.getCameraStepOverrides": {
21796
22049
  capName: "pipeline-orchestrator",
21797
22050
  capScope: "system",
@@ -21876,6 +22129,12 @@ Object.freeze({
21876
22129
  addonId: null,
21877
22130
  access: "create"
21878
22131
  },
22132
+ "pipelineOrchestrator.setAgentMaxCameras": {
22133
+ capName: "pipeline-orchestrator",
22134
+ capScope: "system",
22135
+ addonId: null,
22136
+ access: "create"
22137
+ },
21879
22138
  "pipelineOrchestrator.setCameraPipelineForAgent": {
21880
22139
  capName: "pipeline-orchestrator",
21881
22140
  capScope: "system",
@@ -23349,6 +23608,32 @@ Object.freeze({
23349
23608
  "network-access": "ingress",
23350
23609
  "smtp-provider": "email"
23351
23610
  });
23611
+ var frameworkSwapPackageSchema = object({
23612
+ name: string(),
23613
+ stagedPath: string(),
23614
+ backupPath: string(),
23615
+ toVersion: string(),
23616
+ fromVersion: string().nullable()
23617
+ });
23618
+ object({
23619
+ jobId: string(),
23620
+ taskId: string(),
23621
+ packages: array(frameworkSwapPackageSchema),
23622
+ requestedAtMs: number(),
23623
+ schemaVersion: literal(1)
23624
+ });
23625
+ object({
23626
+ jobId: string(),
23627
+ taskId: string(),
23628
+ backups: array(object({
23629
+ name: string(),
23630
+ backupPath: string(),
23631
+ livePath: string()
23632
+ })),
23633
+ appliedAtMs: number(),
23634
+ bootAttempts: number(),
23635
+ schemaVersion: literal(1)
23636
+ });
23352
23637
  /**
23353
23638
  * Names that, when used as URL query parameters, almost certainly carry
23354
23639
  * a secret. Matching is case-insensitive and anchored to the full param
package/dist/addon.mjs CHANGED
@@ -4995,6 +4995,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4995
4995
  */
4996
4996
  EventCategory["PipelineEngineMetricsSnapshot"] = "pipeline.engine-metrics-snapshot";
4997
4997
  /**
4998
+ * Per-node detection-engine runtime-provisioning transition. Emitted by
4999
+ * the detection-pipeline provider on every state change of its lazy
5000
+ * engine-provisioning machine (idle → installing → verifying → ready,
5001
+ * or → failed with a `nextRetryAt`). Payload is the
5002
+ * `EngineProvisioningState` snapshot; `event.source.nodeId` carries the
5003
+ * node. The Pipeline page subscribes to drive a live "installing
5004
+ * OpenVINO… / ready" indicator per node without polling
5005
+ * `pipelineExecutor.getEngineProvisioning`. Telemetry-grade (D8): the UI
5006
+ * also reads the cap snapshot on mount / reconnect. Phase 2.
5007
+ */
5008
+ EventCategory["PipelineEngineProvisioning"] = "pipeline.engine-provisioning";
5009
+ /**
4998
5010
  * Cluster topology snapshot. Carries the same payload returned by
4999
5011
  * `nodes.topology` (every reachable node + addons + processes).
5000
5012
  * Emitted by the hub on any agent / addon lifecycle change
@@ -5144,14 +5156,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5144
5156
  EventCategory["DeviceSleeping"] = "device.sleeping";
5145
5157
  EventCategory["RetentionCleanup"] = "retention.cleanup";
5146
5158
  /**
5147
- * Progress snapshot emitted by `BulkUpdateCoordinator` on every state
5148
- * transition (item status change, phase change, completion, cancel).
5149
- * Payload is `BulkUpdateState`. Admin UI subscribes via `useLiveEvent`
5150
- * to drive the sticky `BulkUpdateBanner` and per-row `AddonRowBadge`.
5151
- *
5152
- * Spec: docs/superpowers/specs/2026-05-21-addons-bulk-update-progress-design.md
5159
+ * Legacy bulk-update progress snapshot (payload `BulkUpdateState`). No longer
5160
+ * emitted F3 removed the coordinator that produced it; "Update all" now runs
5161
+ * as one lifecycle engine job (`AddonsJobProgress`/`AddonsJobLog`). Retained
5162
+ * (with `BulkUpdateState`) only to avoid regenerating the event maps; removed
5163
+ * in F4 once live bulk progress is re-implemented over the engine events.
5153
5164
  */
5154
5165
  EventCategory["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
5166
+ EventCategory["AddonsJobProgress"] = "addons.job-progress";
5167
+ EventCategory["AddonsJobLog"] = "addons.job-log";
5155
5168
  /**
5156
5169
  * A container's child visibility toggled (hidden/shown). Emitted by the
5157
5170
  * `accessories` cap when a child device is hidden or revealed.
@@ -10389,6 +10402,24 @@ var DetectorOutputSchema = object({
10389
10402
  inferenceMs: number(),
10390
10403
  modelId: string()
10391
10404
  });
10405
+ var EngineProvisioningSchema = object({
10406
+ runtimeId: _enum([
10407
+ "onnx",
10408
+ "openvino",
10409
+ "coreml"
10410
+ ]).nullable(),
10411
+ device: string().nullable(),
10412
+ state: _enum([
10413
+ "idle",
10414
+ "installing",
10415
+ "verifying",
10416
+ "ready",
10417
+ "failed"
10418
+ ]),
10419
+ progress: number().optional(),
10420
+ error: string().optional(),
10421
+ nextRetryAt: number().optional()
10422
+ });
10392
10423
  var PipelineStepInputSchema = lazy(() => object({
10393
10424
  addonId: string(),
10394
10425
  modelId: string(),
@@ -10457,7 +10488,7 @@ var PipelineRunResultBridge = custom();
10457
10488
  method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
10458
10489
  kind: "mutation",
10459
10490
  auth: "admin"
10460
- }), method(_void(), record(string(), object({
10491
+ }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
10461
10492
  modelId: string(),
10462
10493
  settings: record(string(), unknown()).readonly()
10463
10494
  }))), method(object({ steps: record(string(), object({
@@ -15613,7 +15644,10 @@ var AgentAddonConfigSchema = object({
15613
15644
  modelId: string(),
15614
15645
  settings: record(string(), unknown()).readonly()
15615
15646
  });
15616
- var AgentPipelineSettingsSchema = object({ addonDefaults: record(string(), AgentAddonConfigSchema).readonly() });
15647
+ var AgentPipelineSettingsSchema = object({
15648
+ addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
15649
+ maxCameras: number().int().nonnegative().nullable().default(null)
15650
+ });
15617
15651
  var CameraPipelineForAgentSchema = object({
15618
15652
  steps: array(PipelineStepInputSchema).readonly(),
15619
15653
  audio: object({
@@ -15715,6 +15749,133 @@ var GlobalMetricsSchema = object({
15715
15749
  * capability providers.
15716
15750
  */
15717
15751
  var CapabilityBindingsSchema = record(string(), string());
15752
+ /** Source block — always present; derives from the stream catalog. */
15753
+ var CameraSourceStatusSchema = object({ streams: array(object({
15754
+ camStreamId: string(),
15755
+ codec: string(),
15756
+ width: number(),
15757
+ height: number(),
15758
+ fps: number(),
15759
+ kind: string()
15760
+ })).readonly() });
15761
+ /** Assignment block — always present (orchestrator-local, no remote call). */
15762
+ var CameraAssignmentStatusSchema = object({
15763
+ detectionNodeId: string().nullable(),
15764
+ decoderNodeId: string().nullable(),
15765
+ audioNodeId: string().nullable(),
15766
+ pinned: object({
15767
+ detection: boolean(),
15768
+ decoder: boolean(),
15769
+ audio: boolean()
15770
+ }),
15771
+ reasons: object({
15772
+ detection: string().optional(),
15773
+ decoder: string().optional(),
15774
+ audio: string().optional()
15775
+ })
15776
+ });
15777
+ /** Broker block — null when the broker stage is unreachable or inactive. */
15778
+ var CameraBrokerStatusSchema = object({
15779
+ profiles: array(object({
15780
+ profile: string(),
15781
+ status: string(),
15782
+ codec: string(),
15783
+ width: number(),
15784
+ height: number(),
15785
+ subscribers: number(),
15786
+ inFps: number(),
15787
+ outFps: number()
15788
+ })).readonly(),
15789
+ webrtcSessions: number(),
15790
+ rtspRestream: boolean()
15791
+ });
15792
+ /** Shared-memory ring statistics within the decoder block. */
15793
+ var CameraDecoderShmSchema = object({
15794
+ framesWritten: number(),
15795
+ getFrameHits: number(),
15796
+ getFrameMisses: number(),
15797
+ budgetMb: number()
15798
+ });
15799
+ /** Decoder block — null when the decoder stage is unreachable or inactive. */
15800
+ var CameraDecoderStatusSchema = object({
15801
+ nodeId: string(),
15802
+ formats: array(string()).readonly(),
15803
+ sessionCount: number(),
15804
+ shm: CameraDecoderShmSchema
15805
+ });
15806
+ /** Motion block — null when motion detection is not active for this device. */
15807
+ var CameraMotionStatusSchema = object({
15808
+ enabled: boolean(),
15809
+ fps: number()
15810
+ });
15811
+ /** Detection provisioning sub-block. */
15812
+ var CameraDetectionProvisioningSchema = object({
15813
+ state: _enum([
15814
+ "idle",
15815
+ "installing",
15816
+ "verifying",
15817
+ "ready",
15818
+ "failed"
15819
+ ]),
15820
+ error: string().optional()
15821
+ });
15822
+ /** Detection phase — derived from the runner's engine phase. */
15823
+ var CameraDetectionPhaseSchema = _enum([
15824
+ "idle",
15825
+ "watching",
15826
+ "active"
15827
+ ]);
15828
+ /** Detection block — null when no detection node is assigned or reachable. */
15829
+ var CameraDetectionStatusSchema = object({
15830
+ nodeId: string(),
15831
+ engine: object({
15832
+ backend: string(),
15833
+ device: string()
15834
+ }),
15835
+ phase: CameraDetectionPhaseSchema,
15836
+ configuredFps: number(),
15837
+ actualFps: number(),
15838
+ queueDepth: number(),
15839
+ avgInferenceMs: number(),
15840
+ provisioning: CameraDetectionProvisioningSchema
15841
+ });
15842
+ /** Audio block — null when no audio node is assigned or reachable. */
15843
+ var CameraAudioStatusSchema = object({
15844
+ nodeId: string(),
15845
+ enabled: boolean()
15846
+ });
15847
+ /** Recording block — null when no recording cap is active for this device. */
15848
+ var CameraRecordingStatusSchema = object({
15849
+ mode: _enum([
15850
+ "off",
15851
+ "continuous",
15852
+ "events"
15853
+ ]),
15854
+ active: boolean(),
15855
+ storageBytes: number()
15856
+ });
15857
+ /**
15858
+ * Aggregated per-camera pipeline status — server-composed, single call.
15859
+ *
15860
+ * The `assignment` and `source` blocks are always present.
15861
+ * Every other block is `null` when the stage is inactive or unreachable
15862
+ * during the bounded parallel fan-out in the orchestrator implementation.
15863
+ *
15864
+ * See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
15865
+ */
15866
+ var CameraStatusSchema = object({
15867
+ deviceId: number(),
15868
+ assignment: CameraAssignmentStatusSchema,
15869
+ source: CameraSourceStatusSchema,
15870
+ broker: CameraBrokerStatusSchema.nullable(),
15871
+ decoder: CameraDecoderStatusSchema.nullable(),
15872
+ motion: CameraMotionStatusSchema.nullable(),
15873
+ detection: CameraDetectionStatusSchema.nullable(),
15874
+ audio: CameraAudioStatusSchema.nullable(),
15875
+ recording: CameraRecordingStatusSchema.nullable(),
15876
+ /** Unix timestamp (ms) when this snapshot was composed server-side. */
15877
+ fetchedAt: number()
15878
+ });
15718
15879
  method(object({
15719
15880
  deviceId: number(),
15720
15881
  agentNodeId: string()
@@ -15782,6 +15943,12 @@ method(object({
15782
15943
  }), {
15783
15944
  kind: "mutation",
15784
15945
  auth: "admin"
15946
+ }), method(object({
15947
+ agentNodeId: string(),
15948
+ maxCameras: number().int().nonnegative().nullable()
15949
+ }), object({ success: literal(true) }), {
15950
+ kind: "mutation",
15951
+ auth: "admin"
15785
15952
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15786
15953
  deviceId: number(),
15787
15954
  addonId: string(),
@@ -15807,7 +15974,7 @@ method(object({
15807
15974
  }), method(object({
15808
15975
  deviceId: number(),
15809
15976
  agentNodeId: string().optional()
15810
- }), CameraPipelineConfigSchema), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
15977
+ }), CameraPipelineConfigSchema), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
15811
15978
  name: string(),
15812
15979
  description: string().optional(),
15813
15980
  config: CameraPipelineConfigSchema
@@ -18827,6 +18994,69 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
18827
18994
  kind: "mutation",
18828
18995
  auth: "admin"
18829
18996
  });
18997
+ var jobKindSchema = _enum([
18998
+ "install",
18999
+ "update",
19000
+ "uninstall",
19001
+ "restart"
19002
+ ]);
19003
+ var taskPhaseSchema = _enum([
19004
+ "queued",
19005
+ "fetching",
19006
+ "staged",
19007
+ "validating",
19008
+ "applying",
19009
+ "restarting",
19010
+ "applied",
19011
+ "done",
19012
+ "failed",
19013
+ "skipped"
19014
+ ]);
19015
+ var taskTargetSchema = _enum(["framework", "addon"]);
19016
+ var taskLogEntrySchema = object({
19017
+ tsMs: number(),
19018
+ nodeId: string(),
19019
+ packageName: string(),
19020
+ phase: taskPhaseSchema,
19021
+ message: string()
19022
+ });
19023
+ var lifecycleTaskSchema = object({
19024
+ taskId: string(),
19025
+ nodeId: string(),
19026
+ packageName: string(),
19027
+ fromVersion: string().nullable(),
19028
+ toVersion: string(),
19029
+ target: taskTargetSchema,
19030
+ phase: taskPhaseSchema,
19031
+ stagedPath: string().nullable(),
19032
+ attempts: number(),
19033
+ steps: array(taskLogEntrySchema),
19034
+ error: string().nullable(),
19035
+ startedAtMs: number().nullable(),
19036
+ finishedAtMs: number().nullable()
19037
+ });
19038
+ var lifecycleJobStateSchema = _enum([
19039
+ "running",
19040
+ "completed",
19041
+ "failed",
19042
+ "partially-failed",
19043
+ "cancelled"
19044
+ ]);
19045
+ var lifecycleJobScopeSchema = _enum([
19046
+ "single",
19047
+ "bulk",
19048
+ "cluster"
19049
+ ]);
19050
+ var lifecycleJobSchema = object({
19051
+ jobId: string(),
19052
+ kind: jobKindSchema,
19053
+ createdAtMs: number(),
19054
+ createdBy: string(),
19055
+ scope: lifecycleJobScopeSchema,
19056
+ tasks: array(lifecycleTaskSchema),
19057
+ state: lifecycleJobStateSchema,
19058
+ schemaVersion: literal(1)
19059
+ });
18830
19060
  /**
18831
19061
  * addons — system-scoped singleton capability for addon package
18832
19062
  * management (install, update, configure, restart) and per-addon log
@@ -19009,7 +19239,7 @@ var BulkUpdatePhaseSchema = _enum([
19009
19239
  "restarting",
19010
19240
  "finalizing"
19011
19241
  ]);
19012
- var BulkUpdateStateSchema = object({
19242
+ object({
19013
19243
  id: string(),
19014
19244
  nodeId: string(),
19015
19245
  startedAtMs: number(),
@@ -19112,20 +19342,7 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
19112
19342
  }), UpdateFrameworkPackageResultSchema, {
19113
19343
  kind: "mutation",
19114
19344
  auth: "admin"
19115
- }), method(object({
19116
- nodeId: string(),
19117
- items: array(object({
19118
- name: string(),
19119
- version: string(),
19120
- isSystem: boolean()
19121
- })).readonly()
19122
- }), object({ id: string() }), {
19123
- kind: "mutation",
19124
- auth: "admin"
19125
- }), method(object({ id: string() }), BulkUpdateStateSchema.nullable(), { auth: "admin" }), method(object({ id: string() }), object({ cancelled: boolean() }), {
19126
- kind: "mutation",
19127
- auth: "admin"
19128
- }), method(object({ nodeId: string().optional() }), array(BulkUpdateStateSchema).readonly(), { auth: "admin" }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
19345
+ }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
19129
19346
  kind: "mutation",
19130
19347
  auth: "admin"
19131
19348
  }), method(object({ packageName: string() }), object({ success: literal(true) }), {
@@ -19147,6 +19364,24 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
19147
19364
  kind: "mutation",
19148
19365
  auth: "admin"
19149
19366
  }), method(CustomActionInputSchema, unknown(), { kind: "mutation" }), method(object({
19367
+ kind: _enum([
19368
+ "install",
19369
+ "update",
19370
+ "uninstall",
19371
+ "restart"
19372
+ ]),
19373
+ targets: array(object({
19374
+ name: string().min(1),
19375
+ version: string().min(1)
19376
+ })).min(1),
19377
+ nodeIds: array(string()).optional()
19378
+ }), object({ jobId: string() }), {
19379
+ kind: "mutation",
19380
+ auth: "admin"
19381
+ }), method(object({ jobId: string() }), lifecycleJobSchema.nullable(), { auth: "admin" }), method(object({ activeOnly: boolean().optional() }), array(lifecycleJobSchema), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
19382
+ kind: "mutation",
19383
+ auth: "admin"
19384
+ }), method(object({
19150
19385
  addonId: string(),
19151
19386
  level: LogLevelSchema$1.optional()
19152
19387
  }), LogStreamEntrySchema, { kind: "subscription" });
@@ -19187,7 +19422,7 @@ Object.freeze({
19187
19422
  addonId: null,
19188
19423
  access: "create"
19189
19424
  },
19190
- "addons.cancelBulkUpdate": {
19425
+ "addons.cancelJob": {
19191
19426
  capName: "addons",
19192
19427
  capScope: "system",
19193
19428
  addonId: null,
@@ -19217,7 +19452,7 @@ Object.freeze({
19217
19452
  addonId: null,
19218
19453
  access: "view"
19219
19454
  },
19220
- "addons.getBulkUpdateState": {
19455
+ "addons.getJob": {
19221
19456
  capName: "addons",
19222
19457
  capScope: "system",
19223
19458
  addonId: null,
@@ -19265,19 +19500,19 @@ Object.freeze({
19265
19500
  addonId: null,
19266
19501
  access: "view"
19267
19502
  },
19268
- "addons.listActiveBulkUpdates": {
19503
+ "addons.listCapabilityProviders": {
19269
19504
  capName: "addons",
19270
19505
  capScope: "system",
19271
19506
  addonId: null,
19272
19507
  access: "view"
19273
19508
  },
19274
- "addons.listCapabilityProviders": {
19509
+ "addons.listFrameworkPackages": {
19275
19510
  capName: "addons",
19276
19511
  capScope: "system",
19277
19512
  addonId: null,
19278
19513
  access: "view"
19279
19514
  },
19280
- "addons.listFrameworkPackages": {
19515
+ "addons.listJobs": {
19281
19516
  capName: "addons",
19282
19517
  capScope: "system",
19283
19518
  addonId: null,
@@ -19361,7 +19596,7 @@ Object.freeze({
19361
19596
  addonId: null,
19362
19597
  access: "create"
19363
19598
  },
19364
- "addons.startBulkUpdate": {
19599
+ "addons.startJob": {
19365
19600
  capName: "addons",
19366
19601
  capScope: "system",
19367
19602
  addonId: null,
@@ -21587,6 +21822,12 @@ Object.freeze({
21587
21822
  addonId: null,
21588
21823
  access: "view"
21589
21824
  },
21825
+ "pipelineExecutor.getEngineProvisioning": {
21826
+ capName: "pipeline-executor",
21827
+ capScope: "system",
21828
+ addonId: null,
21829
+ access: "view"
21830
+ },
21590
21831
  "pipelineExecutor.getGlobalPipelineConfig": {
21591
21832
  capName: "pipeline-executor",
21592
21833
  capScope: "system",
@@ -21791,6 +22032,18 @@ Object.freeze({
21791
22032
  addonId: null,
21792
22033
  access: "view"
21793
22034
  },
22035
+ "pipelineOrchestrator.getCameraStatus": {
22036
+ capName: "pipeline-orchestrator",
22037
+ capScope: "system",
22038
+ addonId: null,
22039
+ access: "view"
22040
+ },
22041
+ "pipelineOrchestrator.getCameraStatuses": {
22042
+ capName: "pipeline-orchestrator",
22043
+ capScope: "system",
22044
+ addonId: null,
22045
+ access: "view"
22046
+ },
21794
22047
  "pipelineOrchestrator.getCameraStepOverrides": {
21795
22048
  capName: "pipeline-orchestrator",
21796
22049
  capScope: "system",
@@ -21875,6 +22128,12 @@ Object.freeze({
21875
22128
  addonId: null,
21876
22129
  access: "create"
21877
22130
  },
22131
+ "pipelineOrchestrator.setAgentMaxCameras": {
22132
+ capName: "pipeline-orchestrator",
22133
+ capScope: "system",
22134
+ addonId: null,
22135
+ access: "create"
22136
+ },
21878
22137
  "pipelineOrchestrator.setCameraPipelineForAgent": {
21879
22138
  capName: "pipeline-orchestrator",
21880
22139
  capScope: "system",
@@ -23348,6 +23607,32 @@ Object.freeze({
23348
23607
  "network-access": "ingress",
23349
23608
  "smtp-provider": "email"
23350
23609
  });
23610
+ var frameworkSwapPackageSchema = object({
23611
+ name: string(),
23612
+ stagedPath: string(),
23613
+ backupPath: string(),
23614
+ toVersion: string(),
23615
+ fromVersion: string().nullable()
23616
+ });
23617
+ object({
23618
+ jobId: string(),
23619
+ taskId: string(),
23620
+ packages: array(frameworkSwapPackageSchema),
23621
+ requestedAtMs: number(),
23622
+ schemaVersion: literal(1)
23623
+ });
23624
+ object({
23625
+ jobId: string(),
23626
+ taskId: string(),
23627
+ backups: array(object({
23628
+ name: string(),
23629
+ backupPath: string(),
23630
+ livePath: string()
23631
+ })),
23632
+ appliedAtMs: number(),
23633
+ bootAttempts: number(),
23634
+ schemaVersion: literal(1)
23635
+ });
23351
23636
  /**
23352
23637
  * Names that, when used as URL query parameters, almost certainly carry
23353
23638
  * a secret. Matching is case-insensitive and anchored to the full param
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rtsp",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Generic RTSP camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",