@camstack/addon-static-turn 1.0.4 → 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.
@@ -4982,6 +4982,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4982
4982
  */
4983
4983
  EventCategory["PipelineEngineMetricsSnapshot"] = "pipeline.engine-metrics-snapshot";
4984
4984
  /**
4985
+ * Per-node detection-engine runtime-provisioning transition. Emitted by
4986
+ * the detection-pipeline provider on every state change of its lazy
4987
+ * engine-provisioning machine (idle → installing → verifying → ready,
4988
+ * or → failed with a `nextRetryAt`). Payload is the
4989
+ * `EngineProvisioningState` snapshot; `event.source.nodeId` carries the
4990
+ * node. The Pipeline page subscribes to drive a live "installing
4991
+ * OpenVINO… / ready" indicator per node without polling
4992
+ * `pipelineExecutor.getEngineProvisioning`. Telemetry-grade (D8): the UI
4993
+ * also reads the cap snapshot on mount / reconnect. Phase 2.
4994
+ */
4995
+ EventCategory["PipelineEngineProvisioning"] = "pipeline.engine-provisioning";
4996
+ /**
4985
4997
  * Cluster topology snapshot. Carries the same payload returned by
4986
4998
  * `nodes.topology` (every reachable node + addons + processes).
4987
4999
  * Emitted by the hub on any agent / addon lifecycle change
@@ -9146,6 +9158,24 @@ var DetectorOutputSchema = object({
9146
9158
  inferenceMs: number(),
9147
9159
  modelId: string()
9148
9160
  });
9161
+ var EngineProvisioningSchema = object({
9162
+ runtimeId: _enum([
9163
+ "onnx",
9164
+ "openvino",
9165
+ "coreml"
9166
+ ]).nullable(),
9167
+ device: string().nullable(),
9168
+ state: _enum([
9169
+ "idle",
9170
+ "installing",
9171
+ "verifying",
9172
+ "ready",
9173
+ "failed"
9174
+ ]),
9175
+ progress: number().optional(),
9176
+ error: string().optional(),
9177
+ nextRetryAt: number().optional()
9178
+ });
9149
9179
  var PipelineStepInputSchema = lazy(() => object({
9150
9180
  addonId: string(),
9151
9181
  modelId: string(),
@@ -9214,7 +9244,7 @@ var PipelineRunResultBridge = custom();
9214
9244
  method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
9215
9245
  kind: "mutation",
9216
9246
  auth: "admin"
9217
- }), method(_void(), record(string(), object({
9247
+ }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
9218
9248
  modelId: string(),
9219
9249
  settings: record(string(), unknown()).readonly()
9220
9250
  }))), method(object({ steps: record(string(), object({
@@ -12801,7 +12831,10 @@ var AgentAddonConfigSchema = object({
12801
12831
  modelId: string(),
12802
12832
  settings: record(string(), unknown()).readonly()
12803
12833
  });
12804
- var AgentPipelineSettingsSchema = object({ addonDefaults: record(string(), AgentAddonConfigSchema).readonly() });
12834
+ var AgentPipelineSettingsSchema = object({
12835
+ addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
12836
+ maxCameras: number().int().nonnegative().nullable().default(null)
12837
+ });
12805
12838
  var CameraPipelineForAgentSchema = object({
12806
12839
  steps: array(PipelineStepInputSchema).readonly(),
12807
12840
  audio: object({
@@ -12903,6 +12936,133 @@ var GlobalMetricsSchema = object({
12903
12936
  * capability providers.
12904
12937
  */
12905
12938
  var CapabilityBindingsSchema = record(string(), string());
12939
+ /** Source block — always present; derives from the stream catalog. */
12940
+ var CameraSourceStatusSchema = object({ streams: array(object({
12941
+ camStreamId: string(),
12942
+ codec: string(),
12943
+ width: number(),
12944
+ height: number(),
12945
+ fps: number(),
12946
+ kind: string()
12947
+ })).readonly() });
12948
+ /** Assignment block — always present (orchestrator-local, no remote call). */
12949
+ var CameraAssignmentStatusSchema = object({
12950
+ detectionNodeId: string().nullable(),
12951
+ decoderNodeId: string().nullable(),
12952
+ audioNodeId: string().nullable(),
12953
+ pinned: object({
12954
+ detection: boolean(),
12955
+ decoder: boolean(),
12956
+ audio: boolean()
12957
+ }),
12958
+ reasons: object({
12959
+ detection: string().optional(),
12960
+ decoder: string().optional(),
12961
+ audio: string().optional()
12962
+ })
12963
+ });
12964
+ /** Broker block — null when the broker stage is unreachable or inactive. */
12965
+ var CameraBrokerStatusSchema = object({
12966
+ profiles: array(object({
12967
+ profile: string(),
12968
+ status: string(),
12969
+ codec: string(),
12970
+ width: number(),
12971
+ height: number(),
12972
+ subscribers: number(),
12973
+ inFps: number(),
12974
+ outFps: number()
12975
+ })).readonly(),
12976
+ webrtcSessions: number(),
12977
+ rtspRestream: boolean()
12978
+ });
12979
+ /** Shared-memory ring statistics within the decoder block. */
12980
+ var CameraDecoderShmSchema = object({
12981
+ framesWritten: number(),
12982
+ getFrameHits: number(),
12983
+ getFrameMisses: number(),
12984
+ budgetMb: number()
12985
+ });
12986
+ /** Decoder block — null when the decoder stage is unreachable or inactive. */
12987
+ var CameraDecoderStatusSchema = object({
12988
+ nodeId: string(),
12989
+ formats: array(string()).readonly(),
12990
+ sessionCount: number(),
12991
+ shm: CameraDecoderShmSchema
12992
+ });
12993
+ /** Motion block — null when motion detection is not active for this device. */
12994
+ var CameraMotionStatusSchema = object({
12995
+ enabled: boolean(),
12996
+ fps: number()
12997
+ });
12998
+ /** Detection provisioning sub-block. */
12999
+ var CameraDetectionProvisioningSchema = object({
13000
+ state: _enum([
13001
+ "idle",
13002
+ "installing",
13003
+ "verifying",
13004
+ "ready",
13005
+ "failed"
13006
+ ]),
13007
+ error: string().optional()
13008
+ });
13009
+ /** Detection phase — derived from the runner's engine phase. */
13010
+ var CameraDetectionPhaseSchema = _enum([
13011
+ "idle",
13012
+ "watching",
13013
+ "active"
13014
+ ]);
13015
+ /** Detection block — null when no detection node is assigned or reachable. */
13016
+ var CameraDetectionStatusSchema = object({
13017
+ nodeId: string(),
13018
+ engine: object({
13019
+ backend: string(),
13020
+ device: string()
13021
+ }),
13022
+ phase: CameraDetectionPhaseSchema,
13023
+ configuredFps: number(),
13024
+ actualFps: number(),
13025
+ queueDepth: number(),
13026
+ avgInferenceMs: number(),
13027
+ provisioning: CameraDetectionProvisioningSchema
13028
+ });
13029
+ /** Audio block — null when no audio node is assigned or reachable. */
13030
+ var CameraAudioStatusSchema = object({
13031
+ nodeId: string(),
13032
+ enabled: boolean()
13033
+ });
13034
+ /** Recording block — null when no recording cap is active for this device. */
13035
+ var CameraRecordingStatusSchema = object({
13036
+ mode: _enum([
13037
+ "off",
13038
+ "continuous",
13039
+ "events"
13040
+ ]),
13041
+ active: boolean(),
13042
+ storageBytes: number()
13043
+ });
13044
+ /**
13045
+ * Aggregated per-camera pipeline status — server-composed, single call.
13046
+ *
13047
+ * The `assignment` and `source` blocks are always present.
13048
+ * Every other block is `null` when the stage is inactive or unreachable
13049
+ * during the bounded parallel fan-out in the orchestrator implementation.
13050
+ *
13051
+ * See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
13052
+ */
13053
+ var CameraStatusSchema = object({
13054
+ deviceId: number(),
13055
+ assignment: CameraAssignmentStatusSchema,
13056
+ source: CameraSourceStatusSchema,
13057
+ broker: CameraBrokerStatusSchema.nullable(),
13058
+ decoder: CameraDecoderStatusSchema.nullable(),
13059
+ motion: CameraMotionStatusSchema.nullable(),
13060
+ detection: CameraDetectionStatusSchema.nullable(),
13061
+ audio: CameraAudioStatusSchema.nullable(),
13062
+ recording: CameraRecordingStatusSchema.nullable(),
13063
+ /** Unix timestamp (ms) when this snapshot was composed server-side. */
13064
+ fetchedAt: number()
13065
+ });
12906
13066
  method(object({
12907
13067
  deviceId: number(),
12908
13068
  agentNodeId: string()
@@ -12970,6 +13130,12 @@ method(object({
12970
13130
  }), {
12971
13131
  kind: "mutation",
12972
13132
  auth: "admin"
13133
+ }), method(object({
13134
+ agentNodeId: string(),
13135
+ maxCameras: number().int().nonnegative().nullable()
13136
+ }), object({ success: literal(true) }), {
13137
+ kind: "mutation",
13138
+ auth: "admin"
12973
13139
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
12974
13140
  deviceId: number(),
12975
13141
  addonId: string(),
@@ -12995,7 +13161,7 @@ method(object({
12995
13161
  }), method(object({
12996
13162
  deviceId: number(),
12997
13163
  agentNodeId: string().optional()
12998
- }), CameraPipelineConfigSchema), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
13164
+ }), CameraPipelineConfigSchema), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
12999
13165
  name: string(),
13000
13166
  description: string().optional(),
13001
13167
  config: CameraPipelineConfigSchema
@@ -18810,6 +18976,12 @@ Object.freeze({
18810
18976
  addonId: null,
18811
18977
  access: "view"
18812
18978
  },
18979
+ "pipelineExecutor.getEngineProvisioning": {
18980
+ capName: "pipeline-executor",
18981
+ capScope: "system",
18982
+ addonId: null,
18983
+ access: "view"
18984
+ },
18813
18985
  "pipelineExecutor.getGlobalPipelineConfig": {
18814
18986
  capName: "pipeline-executor",
18815
18987
  capScope: "system",
@@ -19014,6 +19186,18 @@ Object.freeze({
19014
19186
  addonId: null,
19015
19187
  access: "view"
19016
19188
  },
19189
+ "pipelineOrchestrator.getCameraStatus": {
19190
+ capName: "pipeline-orchestrator",
19191
+ capScope: "system",
19192
+ addonId: null,
19193
+ access: "view"
19194
+ },
19195
+ "pipelineOrchestrator.getCameraStatuses": {
19196
+ capName: "pipeline-orchestrator",
19197
+ capScope: "system",
19198
+ addonId: null,
19199
+ access: "view"
19200
+ },
19017
19201
  "pipelineOrchestrator.getCameraStepOverrides": {
19018
19202
  capName: "pipeline-orchestrator",
19019
19203
  capScope: "system",
@@ -19098,6 +19282,12 @@ Object.freeze({
19098
19282
  addonId: null,
19099
19283
  access: "create"
19100
19284
  },
19285
+ "pipelineOrchestrator.setAgentMaxCameras": {
19286
+ capName: "pipeline-orchestrator",
19287
+ capScope: "system",
19288
+ addonId: null,
19289
+ access: "create"
19290
+ },
19101
19291
  "pipelineOrchestrator.setCameraPipelineForAgent": {
19102
19292
  capName: "pipeline-orchestrator",
19103
19293
  capScope: "system",
@@ -4981,6 +4981,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4981
4981
  */
4982
4982
  EventCategory["PipelineEngineMetricsSnapshot"] = "pipeline.engine-metrics-snapshot";
4983
4983
  /**
4984
+ * Per-node detection-engine runtime-provisioning transition. Emitted by
4985
+ * the detection-pipeline provider on every state change of its lazy
4986
+ * engine-provisioning machine (idle → installing → verifying → ready,
4987
+ * or → failed with a `nextRetryAt`). Payload is the
4988
+ * `EngineProvisioningState` snapshot; `event.source.nodeId` carries the
4989
+ * node. The Pipeline page subscribes to drive a live "installing
4990
+ * OpenVINO… / ready" indicator per node without polling
4991
+ * `pipelineExecutor.getEngineProvisioning`. Telemetry-grade (D8): the UI
4992
+ * also reads the cap snapshot on mount / reconnect. Phase 2.
4993
+ */
4994
+ EventCategory["PipelineEngineProvisioning"] = "pipeline.engine-provisioning";
4995
+ /**
4984
4996
  * Cluster topology snapshot. Carries the same payload returned by
4985
4997
  * `nodes.topology` (every reachable node + addons + processes).
4986
4998
  * Emitted by the hub on any agent / addon lifecycle change
@@ -9145,6 +9157,24 @@ var DetectorOutputSchema = object({
9145
9157
  inferenceMs: number(),
9146
9158
  modelId: string()
9147
9159
  });
9160
+ var EngineProvisioningSchema = object({
9161
+ runtimeId: _enum([
9162
+ "onnx",
9163
+ "openvino",
9164
+ "coreml"
9165
+ ]).nullable(),
9166
+ device: string().nullable(),
9167
+ state: _enum([
9168
+ "idle",
9169
+ "installing",
9170
+ "verifying",
9171
+ "ready",
9172
+ "failed"
9173
+ ]),
9174
+ progress: number().optional(),
9175
+ error: string().optional(),
9176
+ nextRetryAt: number().optional()
9177
+ });
9148
9178
  var PipelineStepInputSchema = lazy(() => object({
9149
9179
  addonId: string(),
9150
9180
  modelId: string(),
@@ -9213,7 +9243,7 @@ var PipelineRunResultBridge = custom();
9213
9243
  method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
9214
9244
  kind: "mutation",
9215
9245
  auth: "admin"
9216
- }), method(_void(), record(string(), object({
9246
+ }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
9217
9247
  modelId: string(),
9218
9248
  settings: record(string(), unknown()).readonly()
9219
9249
  }))), method(object({ steps: record(string(), object({
@@ -12800,7 +12830,10 @@ var AgentAddonConfigSchema = object({
12800
12830
  modelId: string(),
12801
12831
  settings: record(string(), unknown()).readonly()
12802
12832
  });
12803
- var AgentPipelineSettingsSchema = object({ addonDefaults: record(string(), AgentAddonConfigSchema).readonly() });
12833
+ var AgentPipelineSettingsSchema = object({
12834
+ addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
12835
+ maxCameras: number().int().nonnegative().nullable().default(null)
12836
+ });
12804
12837
  var CameraPipelineForAgentSchema = object({
12805
12838
  steps: array(PipelineStepInputSchema).readonly(),
12806
12839
  audio: object({
@@ -12902,6 +12935,133 @@ var GlobalMetricsSchema = object({
12902
12935
  * capability providers.
12903
12936
  */
12904
12937
  var CapabilityBindingsSchema = record(string(), string());
12938
+ /** Source block — always present; derives from the stream catalog. */
12939
+ var CameraSourceStatusSchema = object({ streams: array(object({
12940
+ camStreamId: string(),
12941
+ codec: string(),
12942
+ width: number(),
12943
+ height: number(),
12944
+ fps: number(),
12945
+ kind: string()
12946
+ })).readonly() });
12947
+ /** Assignment block — always present (orchestrator-local, no remote call). */
12948
+ var CameraAssignmentStatusSchema = object({
12949
+ detectionNodeId: string().nullable(),
12950
+ decoderNodeId: string().nullable(),
12951
+ audioNodeId: string().nullable(),
12952
+ pinned: object({
12953
+ detection: boolean(),
12954
+ decoder: boolean(),
12955
+ audio: boolean()
12956
+ }),
12957
+ reasons: object({
12958
+ detection: string().optional(),
12959
+ decoder: string().optional(),
12960
+ audio: string().optional()
12961
+ })
12962
+ });
12963
+ /** Broker block — null when the broker stage is unreachable or inactive. */
12964
+ var CameraBrokerStatusSchema = object({
12965
+ profiles: array(object({
12966
+ profile: string(),
12967
+ status: string(),
12968
+ codec: string(),
12969
+ width: number(),
12970
+ height: number(),
12971
+ subscribers: number(),
12972
+ inFps: number(),
12973
+ outFps: number()
12974
+ })).readonly(),
12975
+ webrtcSessions: number(),
12976
+ rtspRestream: boolean()
12977
+ });
12978
+ /** Shared-memory ring statistics within the decoder block. */
12979
+ var CameraDecoderShmSchema = object({
12980
+ framesWritten: number(),
12981
+ getFrameHits: number(),
12982
+ getFrameMisses: number(),
12983
+ budgetMb: number()
12984
+ });
12985
+ /** Decoder block — null when the decoder stage is unreachable or inactive. */
12986
+ var CameraDecoderStatusSchema = object({
12987
+ nodeId: string(),
12988
+ formats: array(string()).readonly(),
12989
+ sessionCount: number(),
12990
+ shm: CameraDecoderShmSchema
12991
+ });
12992
+ /** Motion block — null when motion detection is not active for this device. */
12993
+ var CameraMotionStatusSchema = object({
12994
+ enabled: boolean(),
12995
+ fps: number()
12996
+ });
12997
+ /** Detection provisioning sub-block. */
12998
+ var CameraDetectionProvisioningSchema = object({
12999
+ state: _enum([
13000
+ "idle",
13001
+ "installing",
13002
+ "verifying",
13003
+ "ready",
13004
+ "failed"
13005
+ ]),
13006
+ error: string().optional()
13007
+ });
13008
+ /** Detection phase — derived from the runner's engine phase. */
13009
+ var CameraDetectionPhaseSchema = _enum([
13010
+ "idle",
13011
+ "watching",
13012
+ "active"
13013
+ ]);
13014
+ /** Detection block — null when no detection node is assigned or reachable. */
13015
+ var CameraDetectionStatusSchema = object({
13016
+ nodeId: string(),
13017
+ engine: object({
13018
+ backend: string(),
13019
+ device: string()
13020
+ }),
13021
+ phase: CameraDetectionPhaseSchema,
13022
+ configuredFps: number(),
13023
+ actualFps: number(),
13024
+ queueDepth: number(),
13025
+ avgInferenceMs: number(),
13026
+ provisioning: CameraDetectionProvisioningSchema
13027
+ });
13028
+ /** Audio block — null when no audio node is assigned or reachable. */
13029
+ var CameraAudioStatusSchema = object({
13030
+ nodeId: string(),
13031
+ enabled: boolean()
13032
+ });
13033
+ /** Recording block — null when no recording cap is active for this device. */
13034
+ var CameraRecordingStatusSchema = object({
13035
+ mode: _enum([
13036
+ "off",
13037
+ "continuous",
13038
+ "events"
13039
+ ]),
13040
+ active: boolean(),
13041
+ storageBytes: number()
13042
+ });
13043
+ /**
13044
+ * Aggregated per-camera pipeline status — server-composed, single call.
13045
+ *
13046
+ * The `assignment` and `source` blocks are always present.
13047
+ * Every other block is `null` when the stage is inactive or unreachable
13048
+ * during the bounded parallel fan-out in the orchestrator implementation.
13049
+ *
13050
+ * See spec: `docs/superpowers/specs/2026-06-24-camera-status-aggregator-cap.md`
13051
+ */
13052
+ var CameraStatusSchema = object({
13053
+ deviceId: number(),
13054
+ assignment: CameraAssignmentStatusSchema,
13055
+ source: CameraSourceStatusSchema,
13056
+ broker: CameraBrokerStatusSchema.nullable(),
13057
+ decoder: CameraDecoderStatusSchema.nullable(),
13058
+ motion: CameraMotionStatusSchema.nullable(),
13059
+ detection: CameraDetectionStatusSchema.nullable(),
13060
+ audio: CameraAudioStatusSchema.nullable(),
13061
+ recording: CameraRecordingStatusSchema.nullable(),
13062
+ /** Unix timestamp (ms) when this snapshot was composed server-side. */
13063
+ fetchedAt: number()
13064
+ });
12905
13065
  method(object({
12906
13066
  deviceId: number(),
12907
13067
  agentNodeId: string()
@@ -12969,6 +13129,12 @@ method(object({
12969
13129
  }), {
12970
13130
  kind: "mutation",
12971
13131
  auth: "admin"
13132
+ }), method(object({
13133
+ agentNodeId: string(),
13134
+ maxCameras: number().int().nonnegative().nullable()
13135
+ }), object({ success: literal(true) }), {
13136
+ kind: "mutation",
13137
+ auth: "admin"
12972
13138
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
12973
13139
  deviceId: number(),
12974
13140
  addonId: string(),
@@ -12994,7 +13160,7 @@ method(object({
12994
13160
  }), method(object({
12995
13161
  deviceId: number(),
12996
13162
  agentNodeId: string().optional()
12997
- }), CameraPipelineConfigSchema), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
13163
+ }), CameraPipelineConfigSchema), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
12998
13164
  name: string(),
12999
13165
  description: string().optional(),
13000
13166
  config: CameraPipelineConfigSchema
@@ -18809,6 +18975,12 @@ Object.freeze({
18809
18975
  addonId: null,
18810
18976
  access: "view"
18811
18977
  },
18978
+ "pipelineExecutor.getEngineProvisioning": {
18979
+ capName: "pipeline-executor",
18980
+ capScope: "system",
18981
+ addonId: null,
18982
+ access: "view"
18983
+ },
18812
18984
  "pipelineExecutor.getGlobalPipelineConfig": {
18813
18985
  capName: "pipeline-executor",
18814
18986
  capScope: "system",
@@ -19013,6 +19185,18 @@ Object.freeze({
19013
19185
  addonId: null,
19014
19186
  access: "view"
19015
19187
  },
19188
+ "pipelineOrchestrator.getCameraStatus": {
19189
+ capName: "pipeline-orchestrator",
19190
+ capScope: "system",
19191
+ addonId: null,
19192
+ access: "view"
19193
+ },
19194
+ "pipelineOrchestrator.getCameraStatuses": {
19195
+ capName: "pipeline-orchestrator",
19196
+ capScope: "system",
19197
+ addonId: null,
19198
+ access: "view"
19199
+ },
19016
19200
  "pipelineOrchestrator.getCameraStepOverrides": {
19017
19201
  capName: "pipeline-orchestrator",
19018
19202
  capScope: "system",
@@ -19097,6 +19281,12 @@ Object.freeze({
19097
19281
  addonId: null,
19098
19282
  access: "create"
19099
19283
  },
19284
+ "pipelineOrchestrator.setAgentMaxCameras": {
19285
+ capName: "pipeline-orchestrator",
19286
+ capScope: "system",
19287
+ addonId: null,
19288
+ access: "create"
19289
+ },
19100
19290
  "pipelineOrchestrator.setCameraPipelineForAgent": {
19101
19291
  capName: "pipeline-orchestrator",
19102
19292
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-static-turn",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Static / self-hosted (coturn) TURN provider for CamStack",
5
5
  "keywords": [
6
6
  "camstack",