@camstack/sdk 0.1.23 → 0.1.24

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 (109) hide show
  1. package/dist/index.cjs +1769 -6
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1764 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/sdk/src/adaptive-stream.d.ts +91 -0
  6. package/dist/sdk/src/backend-client.d.ts +306 -0
  7. package/dist/sdk/src/backend-router.d.ts +5 -0
  8. package/dist/sdk/src/camera.d.ts +37 -0
  9. package/dist/sdk/src/detection.d.ts +58 -0
  10. package/dist/sdk/src/devices.d.ts +147 -0
  11. package/dist/sdk/src/features.d.ts +31 -0
  12. package/dist/sdk/src/index.d.ts +15 -0
  13. package/dist/sdk/src/nvr.d.ts +285 -0
  14. package/dist/sdk/src/timeline.d.ts +177 -0
  15. package/dist/sdk/src/types.d.ts +44 -0
  16. package/dist/types/src/catalogs/coco-classmap.d.ts +4 -0
  17. package/dist/types/src/constants.d.ts +2 -0
  18. package/dist/types/src/generated/addon-api.d.ts +4869 -0
  19. package/dist/types/src/index.d.ts +81 -0
  20. package/dist/types/src/interfaces/addon-i18n.d.ts +40 -0
  21. package/dist/types/src/interfaces/addon-routes.d.ts +49 -0
  22. package/dist/types/src/interfaces/addon.d.ts +293 -0
  23. package/dist/types/src/interfaces/advanced-notifier.d.ts +58 -0
  24. package/dist/types/src/interfaces/agent-protocol.d.ts +188 -0
  25. package/dist/types/src/interfaces/agent.d.ts +86 -0
  26. package/dist/types/src/interfaces/analysis-persistence.d.ts +277 -0
  27. package/dist/types/src/interfaces/analysis.d.ts +26 -0
  28. package/dist/types/src/interfaces/api-shared.d.ts +167 -0
  29. package/dist/types/src/interfaces/auth-provider.d.ts +38 -0
  30. package/dist/types/src/interfaces/auth.d.ts +46 -0
  31. package/dist/types/src/interfaces/camera-pipeline.d.ts +120 -0
  32. package/dist/types/src/interfaces/capability.d.ts +83 -0
  33. package/dist/types/src/interfaces/classifier.d.ts +7 -0
  34. package/dist/types/src/interfaces/config-ui.d.ts +151 -0
  35. package/dist/types/src/interfaces/context.d.ts +43 -0
  36. package/dist/types/src/interfaces/cropper.d.ts +7 -0
  37. package/dist/types/src/interfaces/decoder.d.ts +26 -0
  38. package/dist/types/src/interfaces/detection-addon.d.ts +14 -0
  39. package/dist/types/src/interfaces/detector.d.ts +7 -0
  40. package/dist/types/src/interfaces/device-capabilities/accessory.d.ts +13 -0
  41. package/dist/types/src/interfaces/device-capabilities/audio-detector.d.ts +11 -0
  42. package/dist/types/src/interfaces/device-capabilities/camera.d.ts +21 -0
  43. package/dist/types/src/interfaces/device-capabilities/doorbell.d.ts +9 -0
  44. package/dist/types/src/interfaces/device-capabilities/events.d.ts +46 -0
  45. package/dist/types/src/interfaces/device-capabilities/index.d.ts +14 -0
  46. package/dist/types/src/interfaces/device-capabilities/motion-sensor.d.ts +6 -0
  47. package/dist/types/src/interfaces/device-capabilities/native-detection.d.ts +13 -0
  48. package/dist/types/src/interfaces/device-capabilities/object-detector.d.ts +58 -0
  49. package/dist/types/src/interfaces/device-capabilities/pan-tilt-zoom.d.ts +28 -0
  50. package/dist/types/src/interfaces/device-capabilities/recording.d.ts +17 -0
  51. package/dist/types/src/interfaces/device-capabilities/siren.d.ts +7 -0
  52. package/dist/types/src/interfaces/device-capabilities/status-light.d.ts +6 -0
  53. package/dist/types/src/interfaces/device-capabilities/switch.d.ts +7 -0
  54. package/dist/types/src/interfaces/device-capabilities/two-way-audio.d.ts +7 -0
  55. package/dist/types/src/interfaces/device-capability.d.ts +13 -0
  56. package/dist/types/src/interfaces/device-provider.d.ts +42 -0
  57. package/dist/types/src/interfaces/device.d.ts +39 -0
  58. package/dist/types/src/interfaces/event-bus.d.ts +21 -0
  59. package/dist/types/src/interfaces/feature-flags.d.ts +13 -0
  60. package/dist/types/src/interfaces/ffmpeg.d.ts +9 -0
  61. package/dist/types/src/interfaces/inference-capabilities.d.ts +100 -0
  62. package/dist/types/src/interfaces/inference-engine.d.ts +16 -0
  63. package/dist/types/src/interfaces/lifecycle.d.ts +18 -0
  64. package/dist/types/src/interfaces/logging.d.ts +32 -0
  65. package/dist/types/src/interfaces/model-catalog.d.ts +24 -0
  66. package/dist/types/src/interfaces/network-quality.d.ts +24 -0
  67. package/dist/types/src/interfaces/network.d.ts +42 -0
  68. package/dist/types/src/interfaces/notification.d.ts +52 -0
  69. package/dist/types/src/interfaces/pipeline-runner.d.ts +22 -0
  70. package/dist/types/src/interfaces/pipeline-slot.d.ts +9 -0
  71. package/dist/types/src/interfaces/platform.d.ts +54 -0
  72. package/dist/types/src/interfaces/process.d.ts +40 -0
  73. package/dist/types/src/interfaces/python-env.d.ts +19 -0
  74. package/dist/types/src/interfaces/refiner.d.ts +7 -0
  75. package/dist/types/src/interfaces/repl.d.ts +25 -0
  76. package/dist/types/src/interfaces/repositories.d.ts +19 -0
  77. package/dist/types/src/interfaces/restreamer.d.ts +23 -0
  78. package/dist/types/src/interfaces/router.d.ts +29 -0
  79. package/dist/types/src/interfaces/scene-intelligence.d.ts +20 -0
  80. package/dist/types/src/interfaces/scoped-token.d.ts +21 -0
  81. package/dist/types/src/interfaces/server-analysis.d.ts +145 -0
  82. package/dist/types/src/interfaces/server-network.d.ts +77 -0
  83. package/dist/types/src/interfaces/storage-backend.d.ts +26 -0
  84. package/dist/types/src/interfaces/storage.d.ts +173 -0
  85. package/dist/types/src/interfaces/stream-broker.d.ts +91 -0
  86. package/dist/types/src/interfaces/streaming.d.ts +28 -0
  87. package/dist/types/src/interfaces/task-handler.d.ts +45 -0
  88. package/dist/types/src/interfaces/webrtc-provider.d.ts +10 -0
  89. package/dist/types/src/interfaces/worker-protocol.d.ts +109 -0
  90. package/dist/types/src/schemas/system-settings-schemas.d.ts +26 -0
  91. package/dist/types/src/types/analytics.d.ts +74 -0
  92. package/dist/types/src/types/benchmark.d.ts +111 -0
  93. package/dist/types/src/types/camera-detection.d.ts +33 -0
  94. package/dist/types/src/types/config.d.ts +36 -0
  95. package/dist/types/src/types/detection.d.ts +92 -0
  96. package/dist/types/src/types/device-type.d.ts +9 -0
  97. package/dist/types/src/types/entities.d.ts +34 -0
  98. package/dist/types/src/types/events.d.ts +34 -0
  99. package/dist/types/src/types/io.d.ts +24 -0
  100. package/dist/types/src/types/labels.d.ts +11 -0
  101. package/dist/types/src/types/live-state.d.ts +46 -0
  102. package/dist/types/src/types/models.d.ts +78 -0
  103. package/dist/types/src/types/pipeline-schema.d.ts +77 -0
  104. package/dist/types/src/types/pipeline.d.ts +41 -0
  105. package/dist/types/src/types/tracked.d.ts +20 -0
  106. package/dist/types/src/types/zones.d.ts +47 -0
  107. package/dist/types/src/utils/cosine-similarity.d.ts +2 -0
  108. package/dist/types/src/utils/hf-url.d.ts +1 -0
  109. package/package.json +6 -5
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Adaptive Stream Session — negotiates optimal stream quality with the proxy.
3
+ *
4
+ * The client reports viewport size and network conditions periodically.
5
+ * The proxy selects the best stream from the provider's available streams
6
+ * and instructs the client to switch via go2rtc stream renegotiation.
7
+ *
8
+ * Flow:
9
+ * 1. Client opens session → sends initial constraints (viewport, network)
10
+ * 2. Server evaluates available streams → picks optimal → responds with stream assignment
11
+ * 3. Client connects to assigned go2rtc stream via WebRTC WHEP
12
+ * 4. Periodically, client reports updated stats → server may switch stream
13
+ * 5. On switch: client tears down old PC, creates new PC to new go2rtc stream
14
+ */
15
+ /** Client-reported constraints for stream selection. */
16
+ export interface StreamConstraints {
17
+ /** Viewport width in CSS pixels. */
18
+ viewportWidth: number;
19
+ /** Viewport height in CSS pixels. */
20
+ viewportHeight: number;
21
+ /** Device pixel ratio (retina = 2+). */
22
+ pixelRatio?: number;
23
+ /** Estimated downlink bandwidth in Mbps (from navigator.connection or WebRTC stats). */
24
+ bandwidthMbps?: number;
25
+ /** Round-trip time in ms (from WebRTC stats). */
26
+ rttMs?: number;
27
+ /** Packet loss ratio 0-1 (from WebRTC stats). */
28
+ packetLoss?: number;
29
+ /** Whether the client is on a cellular network. */
30
+ isCellular?: boolean;
31
+ /** Whether the client prefers low latency over quality. */
32
+ preferLowLatency?: boolean;
33
+ /** Maximum resolution the client wants (e.g., from a user setting). */
34
+ maxResolution?: "auto" | "high" | "medium" | "low";
35
+ }
36
+ /** Server-assigned stream for the client. */
37
+ export interface StreamAssignment {
38
+ /** go2rtc stream name to connect to. */
39
+ streamName: string;
40
+ /** Stream profile (main/sub/ext). */
41
+ profile: string;
42
+ /** Transport type (native/rtsp/rtmp). */
43
+ transport: string;
44
+ /** Human-readable label. */
45
+ label: string;
46
+ /** Stream metadata (if known). */
47
+ metadata?: {
48
+ width?: number;
49
+ height?: number;
50
+ fps?: number;
51
+ bitrate?: number;
52
+ codec?: string;
53
+ };
54
+ /** Reason for this selection. */
55
+ reason: string;
56
+ }
57
+ /** Stream selection request from client → server. */
58
+ export interface StreamSelectionRequest {
59
+ providerId: string;
60
+ camera: string;
61
+ constraints: StreamConstraints;
62
+ /** Current stream (for comparison — only switch if significantly better). */
63
+ currentStreamName?: string;
64
+ }
65
+ /** Stream selection response from server → client. */
66
+ export interface StreamSelectionResponse {
67
+ assignment: StreamAssignment;
68
+ /** Available alternatives the client can manually pick. */
69
+ alternatives: StreamAssignment[];
70
+ /** Seconds until next automatic re-evaluation. */
71
+ nextEvalSeconds: number;
72
+ }
73
+ /**
74
+ * Select the optimal stream from available options based on client constraints.
75
+ * This is a pure function — no side effects.
76
+ */
77
+ export declare function selectOptimalStream(streams: Array<{
78
+ streamName: string;
79
+ profile: string;
80
+ transport: string;
81
+ label: string;
82
+ metadata?: {
83
+ width?: number;
84
+ height?: number;
85
+ fps?: number;
86
+ bitrate?: number;
87
+ codec?: string;
88
+ };
89
+ }>, constraints: StreamConstraints, defaultTransport?: string): StreamAssignment | null;
90
+ /** Determine seconds until next re-evaluation based on stability. */
91
+ export declare function getNextEvalInterval(constraints: StreamConstraints, wasSwitch: boolean): number;
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Backend client — connects directly to the CamStack NestJS backend via tRPC.
3
+ *
4
+ * Use this when the client needs to talk to the backend server directly
5
+ * (admin UI, local agent, embedded mode) rather than going through the proxy.
6
+ *
7
+ * Features: full typed access to all backend tRPC routes (auth, devices, providers,
8
+ * pipeline, agents, addons, bridge pipeline, recording, events, live subscriptions).
9
+ */
10
+ import { createTRPCClient } from "@trpc/client";
11
+ import type { BackendAppRouter } from "./backend-router.js";
12
+ export type SettingsSection = 'server' | 'auth' | 'features' | 'storage' | 'logging' | 'addons' | 'recording' | 'streaming' | 'ffmpeg' | 'detection' | 'backup' | 'retention';
13
+ export interface BackendClientConfig {
14
+ /** Backend server URL (e.g. "http://localhost:4443") */
15
+ readonly serverUrl: string;
16
+ /** JWT token for authentication */
17
+ readonly token?: string;
18
+ /** Connection timeout in ms (default: 10000) */
19
+ readonly connectTimeoutMs?: number;
20
+ /** Use WebSocket for all queries/mutations (default: true in browser, false in Node) */
21
+ readonly useWebSocket?: boolean;
22
+ }
23
+ export declare class BackendClient {
24
+ /** Raw tRPC client — for advanced usage / direct path access */
25
+ readonly trpc: ReturnType<typeof createTRPCClient<BackendAppRouter>>;
26
+ readonly serverUrl: string;
27
+ private token;
28
+ private wsClient;
29
+ constructor(config: BackendClientConfig);
30
+ /** Update the auth token (e.g. after login) */
31
+ setToken(token: string): void;
32
+ /** Close the WebSocket connection (if using WS transport) */
33
+ close(): void;
34
+ login(username: string, password: string): Promise<{
35
+ token: string;
36
+ user: {
37
+ id: string;
38
+ username: string;
39
+ role: import("@camstack/types").UserRole;
40
+ };
41
+ }>;
42
+ getMe(): Promise<import("@camstack/types").AuthenticatedUser>;
43
+ logout(): Promise<{
44
+ success: boolean;
45
+ }>;
46
+ getSystemInfo(): Promise<{
47
+ version: string;
48
+ uptime: number;
49
+ nodeVersion: string;
50
+ platform: NodeJS.Platform;
51
+ features: import("@camstack/types").FeatureManifest;
52
+ }>;
53
+ getFeatureFlags(): Promise<import("@camstack/types").FeatureManifest>;
54
+ listProviders(): Promise<readonly import("@camstack/types").ProviderListItem[]>;
55
+ getProvider(providerId: string): Promise<{
56
+ id: string;
57
+ type: string;
58
+ name: string;
59
+ discoveryMode: "auto" | "manual" | "both";
60
+ status: import("@camstack/types").ProviderStatus;
61
+ deviceCount: number;
62
+ }>;
63
+ startProvider(providerId: string): Promise<{
64
+ success: boolean;
65
+ }>;
66
+ stopProvider(providerId: string): Promise<{
67
+ success: boolean;
68
+ }>;
69
+ listProviderTypes(): Promise<{
70
+ addonId: string;
71
+ name: string;
72
+ description: string;
73
+ iconUrl: string | null;
74
+ color: string;
75
+ instanceMode: "unique" | "multiple";
76
+ discoveryMode: "auto" | "manual" | "both";
77
+ existingInstances: {
78
+ id: string;
79
+ name: string;
80
+ }[];
81
+ canAdd: boolean;
82
+ }[]>;
83
+ listDevices(): Promise<{
84
+ id: string;
85
+ name: string;
86
+ providerId: string;
87
+ type: import("@camstack/types").DeviceType;
88
+ capabilities: import("@camstack/types").DeviceCapabilityName[];
89
+ state: import("@camstack/types").DeviceState;
90
+ }[]>;
91
+ getDevice(deviceId: string): Promise<{
92
+ id: string;
93
+ name: string;
94
+ providerId: string;
95
+ type: import("@camstack/types").DeviceType;
96
+ capabilities: import("@camstack/types").DeviceCapabilityName[];
97
+ state: import("@camstack/types").DeviceState;
98
+ metadata: import("@camstack/types").DeviceMetadata;
99
+ }>;
100
+ discoverDevices(providerId: string): Promise<import("@camstack/types").DiscoveredDevice[]>;
101
+ adoptDevice(providerId: string, externalId: string): Promise<import("@camstack/types").IDevice>;
102
+ createDevice(providerId: string, config: Record<string, unknown>): Promise<import("@camstack/types").IDevice>;
103
+ /** Returns the URL path for a static asset served by an addon. */
104
+ getAddonAssetUrl(addonId: string, assetPath: string): string;
105
+ listAddons(): Promise<{
106
+ manifest: import("@camstack/types").AddonManifest & {
107
+ packageName: string;
108
+ packageVersion: string;
109
+ packageDisplayName?: string;
110
+ protected?: boolean;
111
+ removable?: boolean;
112
+ };
113
+ declaration?: import("@camstack/types").AddonDeclaration;
114
+ hasConfigSchema: boolean;
115
+ source: "core" | "installed" | "workspace";
116
+ }[]>;
117
+ getAddonConfigSchema(addonId: string): Promise<import("@camstack/types").ConfigUISchema | null>;
118
+ getAddonConfig(addonId: string): Promise<Record<string, unknown>>;
119
+ updateAddonConfig(addonId: string, config: Record<string, unknown>): Promise<{
120
+ success: boolean;
121
+ }>;
122
+ getAddonLogs(addonId: string, options?: {
123
+ limit?: number;
124
+ level?: 'debug' | 'info' | 'warn' | 'error';
125
+ }): Promise<import("@camstack/types").LogEntry[]>;
126
+ listKnownFaces(): Promise<{
127
+ id: string;
128
+ label: string;
129
+ group?: string;
130
+ cropBase64: string;
131
+ createdAt: number;
132
+ updatedAt: number;
133
+ source?: string;
134
+ metadata?: Readonly<Record<string, unknown>>;
135
+ }[]>;
136
+ registerFace(label: string, cropBase64: string, group?: string): Promise<never>;
137
+ listPipelines(): Promise<{
138
+ id: string;
139
+ packageName: string;
140
+ slot: import("@camstack/types").PipelineSlot | null;
141
+ }[]>;
142
+ getPipelineStatus(deviceId: string): Promise<import("@camstack/types").PipelineConfig | null>;
143
+ listAgents(): Promise<readonly import("@camstack/types").AgentListItem[]>;
144
+ dispatchTask(agentId: string, task: Record<string, unknown>): Promise<import("@camstack/types").AgentTaskResult>;
145
+ getProcessTree(): Promise<{
146
+ id: string;
147
+ name: string;
148
+ pid: number;
149
+ state: "running";
150
+ cpuPercent: number;
151
+ memoryPercent: number;
152
+ memoryMB: number;
153
+ isHub: boolean;
154
+ platform: string;
155
+ arch: string;
156
+ host: string;
157
+ capabilities: string[];
158
+ installedAddons: string[];
159
+ pythonRuntimes: string[];
160
+ connectedSince: number;
161
+ subProcesses: unknown[];
162
+ }[]>;
163
+ bridgeListAddons(): Promise<{
164
+ id: string;
165
+ packageName: string;
166
+ slot: import("@camstack/types").PipelineSlot | null;
167
+ }[]>;
168
+ bridgeGetPipeline(deviceId: string): Promise<import("@camstack/types").PipelineConfig | null>;
169
+ bridgeSetPipeline(deviceId: string, config: {
170
+ video: unknown[];
171
+ audio?: unknown;
172
+ }): Promise<{
173
+ success: boolean;
174
+ }>;
175
+ bridgeValidatePipeline(config: {
176
+ video: unknown[];
177
+ audio?: unknown;
178
+ }): Promise<import("@camstack/types").ValidationResult>;
179
+ bridgeGetAddonConfig(addonId: string): Promise<Record<string, unknown>>;
180
+ bridgeSetAddonConfig(addonId: string, config: Record<string, unknown>): Promise<{
181
+ success: boolean;
182
+ }>;
183
+ bridgeListPackages(): Promise<import("@camstack/types").InstalledPackage[]>;
184
+ bridgeListAddonsPackages(): Promise<{
185
+ id: string;
186
+ packageName: string;
187
+ slot: import("@camstack/types").PipelineSlot | null;
188
+ }[]>;
189
+ bridgeInstallPackage(packageName: string, version?: string): Promise<{
190
+ success: boolean;
191
+ loaded: string[];
192
+ failed: string[];
193
+ }>;
194
+ bridgeUninstallPackage(packageName: string): Promise<{
195
+ success: boolean;
196
+ }>;
197
+ getRecordingConfig(deviceId: string): Promise<unknown>;
198
+ getRecordingPolicy(deviceId: string): Promise<unknown>;
199
+ getRecordingPolicyStatus(deviceId: string): Promise<{
200
+ deviceId: string;
201
+ policyExists: boolean;
202
+ enabled: any;
203
+ mode: any;
204
+ isRecording: boolean;
205
+ }>;
206
+ getRecordingSegments(deviceId: string, streamId: string, startTime: number, endTime: number): Promise<unknown>;
207
+ getEvents(deviceId: string, options?: {
208
+ limit?: number;
209
+ offset?: number;
210
+ }): Promise<import("@camstack/types").EventQueryResult>;
211
+ getLogs(options?: {
212
+ level?: 'debug' | 'info' | 'warn' | 'error';
213
+ limit?: number;
214
+ since?: number;
215
+ until?: number;
216
+ scope?: string[];
217
+ }): Promise<import("@camstack/types").LogEntry[]>;
218
+ replEval(code: string, scope?: {
219
+ type: 'system';
220
+ } | {
221
+ type: 'device';
222
+ deviceId: string;
223
+ } | {
224
+ type: 'provider';
225
+ providerId: string;
226
+ } | {
227
+ type: 'addon';
228
+ addonId: string;
229
+ }): Promise<import("@camstack/types").ReplResult>;
230
+ listUsers(): Promise<Omit<import("@camstack/types").UserRecord, "passwordHash">[]>;
231
+ createUser(username: string, password: string, role: 'super_admin' | 'admin' | 'viewer'): Promise<{
232
+ id: string;
233
+ username: string;
234
+ role: import("@camstack/types").UserRole;
235
+ allowedProviders: string[] | "*";
236
+ allowedDevices: Record<string, string[] | "*">;
237
+ createdAt: number;
238
+ updatedAt: number;
239
+ }>;
240
+ getTrackingSessions(deviceId?: string): Promise<{
241
+ trackId: string;
242
+ deviceId: string;
243
+ className: string;
244
+ label: string | undefined;
245
+ firstSeen: number;
246
+ lastSeen: number;
247
+ totalFrames: number;
248
+ state: string;
249
+ globalId: string | undefined;
250
+ positions: readonly {
251
+ readonly x: number;
252
+ readonly y: number;
253
+ readonly t: number;
254
+ }[];
255
+ hasEmbedding: boolean;
256
+ hasCrop: boolean;
257
+ }[]>;
258
+ listProcesses(): Promise<(import("@camstack/types").ManagedProcessStatus | {
259
+ id: string;
260
+ label: string;
261
+ state: "running" | "stopped" | "crashed" | "starting";
262
+ pid?: number;
263
+ stats?: {
264
+ pid: number;
265
+ cpu: number;
266
+ memory: number;
267
+ uptime: number;
268
+ restartCount: number;
269
+ };
270
+ restartCount: number;
271
+ mode: "forked" | "in-process";
272
+ })[]>;
273
+ enableProvider(providerId: string): Promise<{
274
+ success: boolean;
275
+ }>;
276
+ disableProvider(providerId: string): Promise<{
277
+ success: boolean;
278
+ }>;
279
+ /** Fetch the UI schema for a single section, or all sections if omitted. */
280
+ getSettingsSchema(section?: SettingsSection): Promise<{
281
+ section: "auth" | "features" | "server" | "storage" | "logging" | "addons" | "recording" | "streaming" | "ffmpeg" | "detection" | "backup" | "retention";
282
+ schema: import("@camstack/types").ConfigUISchema | null;
283
+ readOnly: boolean;
284
+ tabs?: undefined;
285
+ schemas?: undefined;
286
+ } | {
287
+ tabs: readonly import("@camstack/types").SettingsTabDef[];
288
+ schemas: Record<string, unknown>;
289
+ section?: undefined;
290
+ schema?: undefined;
291
+ readOnly?: undefined;
292
+ }>;
293
+ getSettings(section: SettingsSection): Promise<{
294
+ section: "auth" | "features" | "server" | "storage" | "logging" | "addons" | "recording" | "streaming" | "ffmpeg" | "detection" | "backup" | "retention";
295
+ data: Record<string, unknown>;
296
+ }>;
297
+ updateSettings(section: SettingsSection, data: Record<string, unknown>): Promise<{
298
+ success: boolean;
299
+ section: "auth" | "features" | "server" | "storage" | "logging" | "addons" | "recording" | "streaming" | "ffmpeg" | "detection" | "backup" | "retention";
300
+ }>;
301
+ }
302
+ /**
303
+ * Create a BackendClient instance with the given config.
304
+ * Convenience factory function.
305
+ */
306
+ export declare function createBackendClient(config: BackendClientConfig): BackendClient;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-export AppRouter type from @camstack/types (pre-generated from server router).
3
+ * Type-only — no runtime dependency on the backend package.
4
+ */
5
+ export type { AppRouter as BackendAppRouter } from "@camstack/types";
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Camera & PTZ types — shared between CamStack app and proxy.
3
+ */
4
+ /** Camera source type discriminator. */
5
+ export type CameraSourceType = "scrypted" | "frigate" | "onvif" | "rtsp" | "camstack";
6
+ /** Streaming method. */
7
+ export type StreamMethod = "webrtc" | "mjpeg";
8
+ /** Scrypted-compatible PTZ command. */
9
+ export interface PanTiltZoomCommand {
10
+ movement?: "Relative" | "Absolute" | "Continuous" | "Home" | "Preset";
11
+ pan?: number;
12
+ tilt?: number;
13
+ zoom?: number;
14
+ preset?: string;
15
+ timeout?: number;
16
+ }
17
+ /** PTZ capabilities reported by the device. */
18
+ export interface PanTiltZoomCapabilities {
19
+ pan?: boolean;
20
+ tilt?: boolean;
21
+ zoom?: boolean;
22
+ presets?: Record<string, string>;
23
+ }
24
+ /** Accessory switch kinds exposed by the Advanced Notifier plugin. */
25
+ export type CameraAccessorySwitchKind = "siren_on_motion" | "siren" | "light_on_motion" | "light" | "pir" | "autotracking";
26
+ /** Extended camera status with accessory switches (from AN plugin). */
27
+ export interface CameraStatusEntry {
28
+ notificationsEnabled: boolean;
29
+ isRecording: boolean;
30
+ isSnapshotsEnabled: boolean;
31
+ isRebroadcastEnabled: boolean;
32
+ accessorySwitchStates: Partial<Record<CameraAccessorySwitchKind, boolean>>;
33
+ }
34
+ /** Batch camera status response. */
35
+ export interface CamerasStatusResult {
36
+ cameras: Record<string, CameraStatusEntry>;
37
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Detection classes — shared between CamStack app and proxy.
3
+ * Aligned with scrypted-advanced-notifier/src/detectionClasses.ts.
4
+ */
5
+ export declare enum DetectionClass {
6
+ Motion = "motion",
7
+ Person = "person",
8
+ Vehicle = "vehicle",
9
+ Animal = "animal",
10
+ Audio = "audio",
11
+ Face = "face",
12
+ Plate = "plate",
13
+ Package = "package",
14
+ Doorbell = "doorbell",
15
+ Sensor = "sensor"
16
+ }
17
+ export declare const animalClasses: string[];
18
+ export declare const personClasses: string[];
19
+ export declare const vehicleClasses: string[];
20
+ export declare const faceClasses: string[];
21
+ export declare const licensePlateClasses: string[];
22
+ export declare const motionClasses: string[];
23
+ export declare const packageClasses: string[];
24
+ export declare const audioClasses: string[];
25
+ /** Common YAMNet audio labels (advanced-notifier). Parent: Audio. */
26
+ export declare const audioLabelClasses: string[];
27
+ export declare const doorbellClasses: string[];
28
+ /** Sensor types (advanced-notifier SupportedSensorType). Parent: Sensor. */
29
+ export declare const sensorLabelClasses: string[];
30
+ export declare const detectionClassesDefaultMap: Record<string, DetectionClass>;
31
+ export declare const isFaceClassname: (c: string) => boolean;
32
+ export declare const isPlateClassname: (c: string) => boolean;
33
+ export declare const isAnimalClassname: (c: string) => boolean;
34
+ export declare const isPersonClassname: (c: string) => boolean;
35
+ export declare const isVehicleClassname: (c: string) => boolean;
36
+ export declare const isMotionClassname: (c: string) => boolean;
37
+ export declare const isDoorbellClassname: (c: string) => boolean;
38
+ export declare const isPackageClassname: (c: string) => boolean;
39
+ export declare const isAudioClassname: (c: string) => boolean;
40
+ export declare const isSensorLabelClassname: (c: string) => boolean;
41
+ export declare const isLabelDetection: (c: string) => boolean;
42
+ export declare const getParentClass: (className: string) => DetectionClass | undefined;
43
+ export declare const getParentDetectionClass: (det: {
44
+ label?: string;
45
+ className: string;
46
+ }) => DetectionClass | undefined;
47
+ export declare const defaultDetectionClasses: DetectionClass[];
48
+ /** Default enabled classes: all except Motion. */
49
+ export declare const DEFAULT_ENABLED_CLASSES: (DetectionClass.Person | DetectionClass.Vehicle | DetectionClass.Animal | DetectionClass.Audio | DetectionClass.Face | DetectionClass.Plate | DetectionClass.Package | DetectionClass.Doorbell | DetectionClass.Sensor)[];
50
+ export type TimelineEventPreset = "all" | "important" | "critical" | "custom";
51
+ /** Classes for "critical" preset: security-relevant only (person, doorbell, package). */
52
+ export declare const TIMELINE_PRESET_CRITICAL: string[];
53
+ /** Classes for "important" preset: critical + vehicle, animal, audio, face, plate. */
54
+ export declare const TIMELINE_PRESET_IMPORTANT: string[];
55
+ /** Classes for "all" preset: same as DEFAULT_ENABLED_CLASSES. */
56
+ export declare const TIMELINE_PRESET_ALL: string[];
57
+ /** Get enabled classes for a preset. For "custom", pass customClasses. */
58
+ export declare function getClassesForTimelinePreset(preset: TimelineEventPreset, customClasses?: string[]): string[];
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Device types, mappings, and filtering constants — shared between CamStack app and proxy.
3
+ *
4
+ * Covers:
5
+ * - Canonical device type normalization (Scrypted PascalCase + HA domains → canonical)
6
+ * - Eligible device type lists for Scrypted and Home Assistant
7
+ * - Unified Device / DeviceCommand / CommandResult interfaces
8
+ * - AssociatedDeviceState shape
9
+ */
10
+ export type CanonicalDeviceType = "light" | "switch" | "cover" | "lock" | "alarm" | "button" | "select" | "siren" | "sensor" | "entry" | "media_player" | "script";
11
+ /**
12
+ * Maps raw device types from Scrypted (PascalCase) and Home Assistant (lowercase domains)
13
+ * to canonical CamStack device types.
14
+ */
15
+ export declare const RAW_TO_CANONICAL: Record<string, CanonicalDeviceType>;
16
+ /**
17
+ * Extended HA domain → type map (includes non-eligible domains for display/categorization).
18
+ * Superset of RAW_TO_CANONICAL for HA-specific domains.
19
+ */
20
+ export declare const HA_DOMAIN_TYPE_MAP: Record<string, string>;
21
+ /**
22
+ * Extended Scrypted type → canonical map (includes non-eligible types for display).
23
+ * Superset of RAW_TO_CANONICAL for Scrypted-specific types.
24
+ */
25
+ export declare const SCRYPTED_TYPE_TO_CANONICAL: Record<string, string>;
26
+ /** Normalize raw type (Scrypted or HA) to canonical key for filtering and display. */
27
+ export declare function getCanonicalDeviceType(rawType: string): CanonicalDeviceType | null;
28
+ /** Scrypted device types eligible for device control in CamStack. PascalCase. */
29
+ export declare const ELIGIBLE_SCRYPTED_DEVICE_TYPES: readonly ["Entry", "Light", "Switch", "Lock", "SecuritySystem", "Buttons", "WindowCovering", "Siren", "Sensor", "Select", "Program"];
30
+ /** Set version for O(1) lookup. */
31
+ export declare const ELIGIBLE_SCRYPTED_DEVICE_TYPES_SET: Set<string>;
32
+ /** Home Assistant domains eligible for device control in CamStack. */
33
+ export declare const ELIGIBLE_HA_DOMAINS: readonly ["light", "switch", "input_boolean", "cover", "lock", "alarm_control_panel", "input_button", "button", "input_select", "select", "siren", "media_player", "script"];
34
+ /** Set version for O(1) lookup. */
35
+ export declare const ELIGIBLE_HA_DOMAINS_SET: Set<string>;
36
+ /** All device command actions supported by CamStack. */
37
+ export type DeviceCommandAction = "turnOn" | "turnOff" | "openEntry" | "closeEntry" | "stopEntry" | "lock" | "unlock" | "disarm" | "arm" | "pressButton" | "selectOption" | "volumeUp" | "volumeDown" | "volumeMute";
38
+ /**
39
+ * State snapshot shape for an associated device.
40
+ * Used by both app (AssociatedDeviceStateSnapshot) and proxy (Device.state).
41
+ */
42
+ export interface AssociatedDeviceState {
43
+ name?: string;
44
+ type?: string;
45
+ interfaces?: string[];
46
+ on?: boolean;
47
+ hasBrightnessControl?: boolean;
48
+ brightness?: number;
49
+ lockState?: string;
50
+ securitySystemState?: {
51
+ mode?: string;
52
+ supportedModes?: string[];
53
+ };
54
+ buttons?: string[];
55
+ entryOpen?: boolean | "jammed";
56
+ value?: string;
57
+ options?: string[];
58
+ volumeLevel?: number;
59
+ isVolumeMuted?: boolean;
60
+ coverSupportsStop?: boolean;
61
+ coverPosition?: number;
62
+ }
63
+ /** A device from an automation system (Scrypted, Home Assistant, etc.). */
64
+ export interface Device {
65
+ id: string;
66
+ name: string;
67
+ /**
68
+ * Canonical device type (lowercase): "light", "switch", "cover", "lock",
69
+ * "alarm", "button", "select", "siren", "sensor", "entry", "media_player",
70
+ * "script", "camera", "nvr".
71
+ */
72
+ type: string;
73
+ /** Original type from the source system (e.g. Scrypted "WindowCovering", HA domain "cover"). */
74
+ rawType?: string;
75
+ /** Provider that owns this device. */
76
+ providerId?: string;
77
+ model?: string;
78
+ manufacturer?: string;
79
+ firmware?: string;
80
+ online: boolean;
81
+ interfaces: string[];
82
+ /** Current state (key-value pairs, device-type-dependent). See AssociatedDeviceState. */
83
+ state: Record<string, unknown>;
84
+ /** Available actions for this device (defined by the provider). */
85
+ actions?: DeviceAction[];
86
+ /** Child devices (e.g. NVR → camera channels). */
87
+ children?: Device[];
88
+ }
89
+ /** A command to send to a device. */
90
+ export interface DeviceCommand {
91
+ deviceId: string;
92
+ command: string;
93
+ params?: Record<string, unknown>;
94
+ }
95
+ /** Result of a command execution. */
96
+ export interface CommandResult {
97
+ success: boolean;
98
+ error?: string;
99
+ state?: Record<string, unknown>;
100
+ }
101
+ /** Device source type (integration that provides the device). */
102
+ export type AssociatedDeviceSource = "scrypted" | "ha";
103
+ /** Eligible device summary (for device picker UI). */
104
+ export interface EligibleDevice {
105
+ id: string;
106
+ name: string;
107
+ type: string;
108
+ source: AssociatedDeviceSource;
109
+ }
110
+ /**
111
+ * An action that can be performed on a device.
112
+ * Actions are declared by the provider and rendered dynamically in the UI.
113
+ */
114
+ export interface DeviceAction {
115
+ /** Unique action ID (e.g. "toggle", "setBrightness", "ptzMove", "reboot"). */
116
+ id: string;
117
+ /** Display label (e.g. "Toggle", "Set Brightness", "Move Camera"). */
118
+ label: string;
119
+ /** Action category for UI grouping. */
120
+ category?: "power" | "control" | "ptz" | "media" | "system" | "custom";
121
+ /** Icon hint (lucide icon name or emoji). */
122
+ icon?: string;
123
+ /** Parameters this action accepts. */
124
+ params?: DeviceActionParam[];
125
+ /** Whether this action is destructive (shown with warning). */
126
+ destructive?: boolean;
127
+ }
128
+ /** A parameter for a device action. */
129
+ export interface DeviceActionParam {
130
+ /** Parameter key. */
131
+ key: string;
132
+ /** Display label. */
133
+ label: string;
134
+ /** Type for UI rendering. */
135
+ type: "boolean" | "number" | "string" | "select" | "slider";
136
+ /** Default value. */
137
+ default?: unknown;
138
+ /** For select type: available options. */
139
+ options?: {
140
+ value: string;
141
+ label: string;
142
+ }[];
143
+ /** For slider/number: min/max/step. */
144
+ min?: number;
145
+ max?: number;
146
+ step?: number;
147
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Feature capability matrix — shared between CamStack app and proxy.
3
+ *
4
+ * Maps each app feature to:
5
+ * - Which source types (Frigate, Scrypted, RTSP) support it
6
+ * - Which platforms (iOS, Android, Web, Scrypted embed) it works on
7
+ * - Whether the camstack-server backend is required
8
+ * - The ICameraSource method that enables the feature
9
+ */
10
+ export type FeatureId = "liveStream" | "multiResolution" | "motion" | "objectDetection" | "audioVolume" | "audioVolumes" | "ptz" | "intercom" | "deviceStatus" | "timeline" | "clusteredTimeline" | "detectionClasses" | "videoClips" | "nvrPlayback" | "nvrScrub" | "recordingThumbnail" | "nvrSeekToLive";
11
+ export type PlatformId = "ios" | "android" | "web" | "scryptedEmbed";
12
+ export type SourceType = "frigate" | "scrypted" | "rtsp";
13
+ export interface FeatureEntry {
14
+ id: FeatureId;
15
+ label: string;
16
+ /** Which source types support this feature. */
17
+ sources: Partial<Record<SourceType, boolean>>;
18
+ /** Platform availability overrides. When omitted, all platforms are supported. */
19
+ platforms?: Partial<Record<PlatformId, boolean>>;
20
+ /** True when this feature needs the camstack-server backend. */
21
+ requiresBackend?: boolean;
22
+ /** The ICameraSource method name that enables this feature at runtime. */
23
+ adapterMethod?: string;
24
+ }
25
+ export declare const FEATURE_MATRIX: FeatureEntry[];
26
+ /** Check if a feature is available for a given source type and platform. */
27
+ export declare function isFeatureAvailable(featureId: FeatureId, source: SourceType, platform: PlatformId): boolean;
28
+ /** Get all features supported by a source type. */
29
+ export declare function getSourceFeatures(source: SourceType): FeatureEntry[];
30
+ /** Get all features that require the backend proxy. */
31
+ export declare function getBackendRequiredFeatures(): FeatureEntry[];