@camstack/types 0.1.2 → 0.1.4

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 (200) hide show
  1. package/dist/__tests__/addon-capability-provider.test.d.ts +2 -0
  2. package/dist/__tests__/addon-capability-provider.test.d.ts.map +1 -0
  3. package/dist/__tests__/addon-declaration.test.d.ts +2 -0
  4. package/dist/__tests__/addon-declaration.test.d.ts.map +1 -0
  5. package/dist/__tests__/capability.test.d.ts +2 -0
  6. package/dist/__tests__/capability.test.d.ts.map +1 -0
  7. package/dist/catalogs/coco-classmap.d.ts +5 -0
  8. package/dist/catalogs/coco-classmap.d.ts.map +1 -0
  9. package/dist/catalogs/index.d.ts +2 -0
  10. package/dist/catalogs/index.d.ts.map +1 -0
  11. package/dist/constants.d.ts +3 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/generated/addon-api.d.ts +4870 -0
  14. package/dist/generated/addon-api.d.ts.map +1 -0
  15. package/dist/index.d.ts +82 -6702
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +744 -550
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +777 -529
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/interfaces/addon-i18n.d.ts +41 -0
  22. package/dist/interfaces/addon-i18n.d.ts.map +1 -0
  23. package/dist/interfaces/addon-routes.d.ts +50 -0
  24. package/dist/interfaces/addon-routes.d.ts.map +1 -0
  25. package/dist/interfaces/addon.d.ts +294 -0
  26. package/dist/interfaces/addon.d.ts.map +1 -0
  27. package/dist/interfaces/advanced-notifier.d.ts +59 -0
  28. package/dist/interfaces/advanced-notifier.d.ts.map +1 -0
  29. package/dist/interfaces/agent-protocol.d.ts +189 -0
  30. package/dist/interfaces/agent-protocol.d.ts.map +1 -0
  31. package/dist/interfaces/agent.d.ts +87 -0
  32. package/dist/interfaces/agent.d.ts.map +1 -0
  33. package/dist/interfaces/analysis-persistence.d.ts +278 -0
  34. package/dist/interfaces/analysis-persistence.d.ts.map +1 -0
  35. package/dist/interfaces/analysis.d.ts +27 -0
  36. package/dist/interfaces/analysis.d.ts.map +1 -0
  37. package/dist/interfaces/api-shared.d.ts +169 -0
  38. package/dist/interfaces/api-shared.d.ts.map +1 -0
  39. package/dist/interfaces/auth-provider.d.ts +39 -0
  40. package/dist/interfaces/auth-provider.d.ts.map +1 -0
  41. package/dist/interfaces/auth.d.ts +47 -0
  42. package/dist/interfaces/auth.d.ts.map +1 -0
  43. package/dist/interfaces/camera-pipeline.d.ts +121 -0
  44. package/dist/interfaces/camera-pipeline.d.ts.map +1 -0
  45. package/dist/interfaces/capability.d.ts +84 -0
  46. package/dist/interfaces/capability.d.ts.map +1 -0
  47. package/dist/interfaces/classifier.d.ts +8 -0
  48. package/dist/interfaces/classifier.d.ts.map +1 -0
  49. package/dist/interfaces/config-ui.d.ts +152 -0
  50. package/dist/interfaces/config-ui.d.ts.map +1 -0
  51. package/dist/interfaces/context.d.ts +44 -0
  52. package/dist/interfaces/context.d.ts.map +1 -0
  53. package/dist/interfaces/cropper.d.ts +8 -0
  54. package/dist/interfaces/cropper.d.ts.map +1 -0
  55. package/dist/interfaces/decoder.d.ts +27 -0
  56. package/dist/interfaces/decoder.d.ts.map +1 -0
  57. package/dist/interfaces/detection-addon.d.ts +15 -0
  58. package/dist/interfaces/detection-addon.d.ts.map +1 -0
  59. package/dist/interfaces/detector.d.ts +8 -0
  60. package/dist/interfaces/detector.d.ts.map +1 -0
  61. package/dist/interfaces/device-capabilities/accessory.d.ts +14 -0
  62. package/dist/interfaces/device-capabilities/accessory.d.ts.map +1 -0
  63. package/dist/interfaces/device-capabilities/audio-detector.d.ts +12 -0
  64. package/dist/interfaces/device-capabilities/audio-detector.d.ts.map +1 -0
  65. package/dist/interfaces/device-capabilities/camera.d.ts +22 -0
  66. package/dist/interfaces/device-capabilities/camera.d.ts.map +1 -0
  67. package/dist/interfaces/device-capabilities/doorbell.d.ts +10 -0
  68. package/dist/interfaces/device-capabilities/doorbell.d.ts.map +1 -0
  69. package/dist/interfaces/device-capabilities/events.d.ts +47 -0
  70. package/dist/interfaces/device-capabilities/events.d.ts.map +1 -0
  71. package/dist/interfaces/device-capabilities/index.d.ts +15 -0
  72. package/dist/interfaces/device-capabilities/index.d.ts.map +1 -0
  73. package/dist/interfaces/device-capabilities/motion-sensor.d.ts +7 -0
  74. package/dist/interfaces/device-capabilities/motion-sensor.d.ts.map +1 -0
  75. package/dist/interfaces/device-capabilities/native-detection.d.ts +14 -0
  76. package/dist/interfaces/device-capabilities/native-detection.d.ts.map +1 -0
  77. package/dist/interfaces/device-capabilities/object-detector.d.ts +59 -0
  78. package/dist/interfaces/device-capabilities/object-detector.d.ts.map +1 -0
  79. package/dist/interfaces/device-capabilities/pan-tilt-zoom.d.ts +29 -0
  80. package/dist/interfaces/device-capabilities/pan-tilt-zoom.d.ts.map +1 -0
  81. package/dist/interfaces/device-capabilities/recording.d.ts +18 -0
  82. package/dist/interfaces/device-capabilities/recording.d.ts.map +1 -0
  83. package/dist/interfaces/device-capabilities/siren.d.ts +8 -0
  84. package/dist/interfaces/device-capabilities/siren.d.ts.map +1 -0
  85. package/dist/interfaces/device-capabilities/status-light.d.ts +7 -0
  86. package/dist/interfaces/device-capabilities/status-light.d.ts.map +1 -0
  87. package/dist/interfaces/device-capabilities/switch.d.ts +8 -0
  88. package/dist/interfaces/device-capabilities/switch.d.ts.map +1 -0
  89. package/dist/interfaces/device-capabilities/two-way-audio.d.ts +8 -0
  90. package/dist/interfaces/device-capabilities/two-way-audio.d.ts.map +1 -0
  91. package/dist/interfaces/device-capability.d.ts +14 -0
  92. package/dist/interfaces/device-capability.d.ts.map +1 -0
  93. package/dist/interfaces/device-provider.d.ts +43 -0
  94. package/dist/interfaces/device-provider.d.ts.map +1 -0
  95. package/dist/interfaces/device.d.ts +40 -0
  96. package/dist/interfaces/device.d.ts.map +1 -0
  97. package/dist/interfaces/event-bus.d.ts +22 -0
  98. package/dist/interfaces/event-bus.d.ts.map +1 -0
  99. package/dist/interfaces/feature-flags.d.ts +14 -0
  100. package/dist/interfaces/feature-flags.d.ts.map +1 -0
  101. package/dist/interfaces/ffmpeg.d.ts +10 -0
  102. package/dist/interfaces/ffmpeg.d.ts.map +1 -0
  103. package/dist/interfaces/inference-capabilities.d.ts +101 -0
  104. package/dist/interfaces/inference-capabilities.d.ts.map +1 -0
  105. package/dist/interfaces/inference-engine.d.ts +17 -0
  106. package/dist/interfaces/inference-engine.d.ts.map +1 -0
  107. package/dist/interfaces/lifecycle.d.ts +19 -0
  108. package/dist/interfaces/lifecycle.d.ts.map +1 -0
  109. package/dist/interfaces/logging.d.ts +33 -0
  110. package/dist/interfaces/logging.d.ts.map +1 -0
  111. package/dist/interfaces/model-catalog.d.ts +25 -0
  112. package/dist/interfaces/model-catalog.d.ts.map +1 -0
  113. package/dist/interfaces/network-quality.d.ts +25 -0
  114. package/dist/interfaces/network-quality.d.ts.map +1 -0
  115. package/dist/interfaces/network.d.ts +43 -0
  116. package/dist/interfaces/network.d.ts.map +1 -0
  117. package/dist/interfaces/notification.d.ts +53 -0
  118. package/dist/interfaces/notification.d.ts.map +1 -0
  119. package/dist/interfaces/pipeline-runner.d.ts +23 -0
  120. package/dist/interfaces/pipeline-runner.d.ts.map +1 -0
  121. package/dist/interfaces/pipeline-slot.d.ts +10 -0
  122. package/dist/interfaces/pipeline-slot.d.ts.map +1 -0
  123. package/dist/interfaces/platform.d.ts +55 -0
  124. package/dist/interfaces/platform.d.ts.map +1 -0
  125. package/dist/interfaces/process.d.ts +41 -0
  126. package/dist/interfaces/process.d.ts.map +1 -0
  127. package/dist/interfaces/python-env.d.ts +20 -0
  128. package/dist/interfaces/python-env.d.ts.map +1 -0
  129. package/dist/interfaces/refiner.d.ts +8 -0
  130. package/dist/interfaces/refiner.d.ts.map +1 -0
  131. package/dist/interfaces/repl.d.ts +26 -0
  132. package/dist/interfaces/repl.d.ts.map +1 -0
  133. package/dist/interfaces/repositories.d.ts +20 -0
  134. package/dist/interfaces/repositories.d.ts.map +1 -0
  135. package/dist/interfaces/restreamer.d.ts +24 -0
  136. package/dist/interfaces/restreamer.d.ts.map +1 -0
  137. package/dist/interfaces/router.d.ts +30 -0
  138. package/dist/interfaces/router.d.ts.map +1 -0
  139. package/dist/interfaces/scene-intelligence.d.ts +21 -0
  140. package/dist/interfaces/scene-intelligence.d.ts.map +1 -0
  141. package/dist/interfaces/scoped-token.d.ts +22 -0
  142. package/dist/interfaces/scoped-token.d.ts.map +1 -0
  143. package/dist/interfaces/server-analysis.d.ts +146 -0
  144. package/dist/interfaces/server-analysis.d.ts.map +1 -0
  145. package/dist/interfaces/server-network.d.ts +78 -0
  146. package/dist/interfaces/server-network.d.ts.map +1 -0
  147. package/dist/interfaces/storage-backend.d.ts +27 -0
  148. package/dist/interfaces/storage-backend.d.ts.map +1 -0
  149. package/dist/interfaces/storage.d.ts +174 -0
  150. package/dist/interfaces/storage.d.ts.map +1 -0
  151. package/dist/interfaces/stream-broker.d.ts +92 -0
  152. package/dist/interfaces/stream-broker.d.ts.map +1 -0
  153. package/dist/interfaces/streaming.d.ts +29 -0
  154. package/dist/interfaces/streaming.d.ts.map +1 -0
  155. package/dist/interfaces/task-handler.d.ts +46 -0
  156. package/dist/interfaces/task-handler.d.ts.map +1 -0
  157. package/dist/interfaces/webrtc-provider.d.ts +11 -0
  158. package/dist/interfaces/webrtc-provider.d.ts.map +1 -0
  159. package/dist/interfaces/worker-protocol.d.ts +110 -0
  160. package/dist/interfaces/worker-protocol.d.ts.map +1 -0
  161. package/dist/schemas/system-settings-schemas.d.ts +27 -0
  162. package/dist/schemas/system-settings-schemas.d.ts.map +1 -0
  163. package/dist/types/analytics.d.ts +75 -0
  164. package/dist/types/analytics.d.ts.map +1 -0
  165. package/dist/types/benchmark.d.ts +112 -0
  166. package/dist/types/benchmark.d.ts.map +1 -0
  167. package/dist/types/camera-detection.d.ts +34 -0
  168. package/dist/types/camera-detection.d.ts.map +1 -0
  169. package/dist/types/config.d.ts +37 -0
  170. package/dist/types/config.d.ts.map +1 -0
  171. package/dist/types/detection.d.ts +93 -0
  172. package/dist/types/detection.d.ts.map +1 -0
  173. package/dist/types/device-type.d.ts +10 -0
  174. package/dist/types/device-type.d.ts.map +1 -0
  175. package/dist/types/entities.d.ts +35 -0
  176. package/dist/types/entities.d.ts.map +1 -0
  177. package/dist/types/events.d.ts +35 -0
  178. package/dist/types/events.d.ts.map +1 -0
  179. package/dist/types/io.d.ts +25 -0
  180. package/dist/types/io.d.ts.map +1 -0
  181. package/dist/types/labels.d.ts +12 -0
  182. package/dist/types/labels.d.ts.map +1 -0
  183. package/dist/types/live-state.d.ts +47 -0
  184. package/dist/types/live-state.d.ts.map +1 -0
  185. package/dist/types/models.d.ts +79 -0
  186. package/dist/types/models.d.ts.map +1 -0
  187. package/dist/types/pipeline-schema.d.ts +78 -0
  188. package/dist/types/pipeline-schema.d.ts.map +1 -0
  189. package/dist/types/pipeline.d.ts +42 -0
  190. package/dist/types/pipeline.d.ts.map +1 -0
  191. package/dist/types/tracked.d.ts +21 -0
  192. package/dist/types/tracked.d.ts.map +1 -0
  193. package/dist/types/zones.d.ts +48 -0
  194. package/dist/types/zones.d.ts.map +1 -0
  195. package/dist/utils/cosine-similarity.d.ts +3 -0
  196. package/dist/utils/cosine-similarity.d.ts.map +1 -0
  197. package/dist/utils/hf-url.d.ts +2 -0
  198. package/dist/utils/hf-url.d.ts.map +1 -0
  199. package/package.json +3 -2
  200. package/dist/index.d.mts +0 -6702
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/interfaces/storage-backend.ts","../src/interfaces/addon-i18n.ts","../src/interfaces/feature-flags.ts","../src/interfaces/agent-protocol.ts","../src/interfaces/server-analysis.ts","../src/interfaces/analysis-persistence.ts","../src/schemas/system-settings-schemas.ts","../src/constants.ts","../src/utils/hf-url.ts","../src/utils/cosine-similarity.ts","../src/catalogs/coco-classmap.ts","../src/types/device-type.ts"],"sourcesContent":["export * from './types/io.js'\nexport * from './types/labels.js'\nexport * from './types/detection.js'\nexport * from './types/tracked.js'\nexport * from './types/events.js'\nexport * from './types/config.js'\nexport * from './types/entities.js'\nexport * from './types/zones.js'\nexport * from './types/models.js'\nexport * from './types/pipeline.js'\nexport * from './types/live-state.js'\nexport * from './types/analytics.js'\nexport type * from './types/benchmark.js'\nexport type {\n PipelineAddonSchema,\n PipelineModelOption,\n PipelineSlotSchema,\n PipelineSchema,\n PipelineDefaultStep,\n PipelineTemplateStep,\n PipelineTemplate,\n TemplateValidationResult,\n} from './types/pipeline-schema.js'\n\n// --- Core interfaces (used by addons and server) ---\nexport type * from './interfaces/addon.js'\nexport type * from './interfaces/capability.js'\nexport type * from './interfaces/config-ui.js'\nexport type * from './interfaces/pipeline-slot.js'\nexport type * from './interfaces/detector.js'\nexport type * from './interfaces/cropper.js'\nexport type * from './interfaces/classifier.js'\nexport type * from './interfaces/refiner.js'\nexport type * from './interfaces/detection-addon.js'\nexport type * from './interfaces/inference-engine.js'\nexport type * from './interfaces/inference-capabilities.js'\nexport type * from './interfaces/repositories.js'\nexport type * from './interfaces/analysis.js'\nexport type * from './interfaces/scene-intelligence.js'\nexport type * from './interfaces/advanced-notifier.js'\nexport type * from './interfaces/python-env.js'\nexport type * from './interfaces/network.js'\nexport type * from './interfaces/router.js'\nexport * from './interfaces/storage-backend.js'\nexport type * from './interfaces/logging.js'\nexport type * from './interfaces/event-bus.js'\nexport type * from './interfaces/pipeline-runner.js'\nexport type * from './interfaces/auth-provider.js'\nexport type * from './interfaces/notification.js'\nexport type * from './interfaces/addon-routes.js'\nexport type * from './interfaces/addon-i18n.js'\nexport { resolveTranslation } from './interfaces/addon-i18n.js'\nexport type * from './interfaces/scoped-token.js'\nexport type * from './interfaces/task-handler.js'\nexport type * from './interfaces/worker-protocol.js'\n\n// --- Server interfaces (consolidated from server/backend/src/interfaces/) ---\nexport type * from './interfaces/storage.js'\nexport type * from './interfaces/context.js'\nexport type * from './interfaces/device-capability.js'\nexport type * from './interfaces/device.js'\nexport type * from './interfaces/device-provider.js'\nexport type * from './interfaces/device-capabilities/index.js'\nexport type * from './interfaces/streaming.js'\nexport type * from './interfaces/auth.js'\nexport type * from './interfaces/lifecycle.js'\nexport type * from './interfaces/server-network.js'\nexport type * from './interfaces/process.js'\nexport * from './interfaces/feature-flags.js'\nexport type * from './interfaces/agent.js'\nexport type * from './interfaces/agent-protocol.js'\nexport * from './interfaces/agent-protocol.js'\nexport type * from './interfaces/camera-pipeline.js'\nexport type * from './interfaces/server-analysis.js'\nexport * from './interfaces/server-analysis.js'\nexport type * from './interfaces/stream-broker.js'\nexport * from './interfaces/analysis-persistence.js'\nexport type * from './interfaces/restreamer.js'\nexport type * from './interfaces/decoder.js'\nexport type * from './interfaces/ffmpeg.js'\nexport type {\n ModelType as ServerModelType,\n ServerModelCatalogEntry,\n IModelCatalogProvider,\n} from './interfaces/model-catalog.js'\nexport type * from './interfaces/network-quality.js'\nexport type * from './interfaces/webrtc-provider.js'\nexport type * from './interfaces/repl.js'\nexport type * from './interfaces/platform.js'\nexport type * from './interfaces/api-shared.js'\n\n// Schemas (runtime objects — system settings UI definitions)\nexport * from './schemas/system-settings-schemas.js'\n\n// Constants\nexport * from './constants.js'\n\n// Utils\nexport { hfModelUrl } from './utils/hf-url.js'\nexport { cosineSimilarity } from './utils/cosine-similarity.js'\n\n// Catalogs (coco-classmap stays in types — used by object-detection addon and other consumers)\nexport {\n COCO_80_LABELS,\n COCO_TO_MACRO,\n MACRO_LABELS,\n} from './catalogs/coco-classmap.js'\n\nexport type {\n CameraMotionConfig,\n CameraNativeDetectionConfig,\n CameraDetectionCapabilities,\n} from './types/camera-detection.js'\n\nexport { DeviceType, type DeviceTypeInfo, DEVICE_TYPE_INFO } from './types/device-type.js'\n\nexport type { AppRouter } from './generated/addon-api.js'\n","/**\n * @deprecated — This file contains legacy storage backend interfaces.\n * Use the new interfaces from './storage.ts' instead:\n * - IStorageProvider (capability: 'storage')\n * - ISettingsBackend (capability: 'settings-store')\n * - IEmbeddingsBackend (capability: 'embeddings')\n */\n\nimport type { StorageLocationType } from './storage.js'\n\n/** @deprecated Use IStorageProvider from storage.ts */\nexport interface IStorageBackend {\n readonly type: string\n readonly basePath: string\n resolve(subpath: string): string\n resolve(location: StorageLocationType, ...segments: string[]): string\n isAvailable(location?: StorageLocationType): boolean\n initialize(): Promise<void>\n getLocationPath?(location: StorageLocationType): string\n}\n\n/** @deprecated */\nexport interface StorageLocationConfig {\n readonly name: string\n readonly basePath: string\n readonly backendType?: string\n}\n\n/** @deprecated Use DEFAULT_LOCATION_SUBDIRS from storage.ts */\nexport const DEFAULT_LOCATION_SUBPATHS: Record<string, string> = {\n 'recordings-high': 'recordings-high',\n 'recordings-low': 'recordings-low',\n 'recordings-clips': 'recordings-clips',\n 'event-images': 'event-images',\n 'models': 'models',\n 'addons-data': 'addons-data',\n 'cache': '/tmp/camstack-cache',\n 'logs': 'logs',\n}\n","/**\n * Addon i18n interface -- allows addons to provide translations\n * for their UI labels, descriptions, and config schema fields.\n *\n * Addons implement IAddonTranslationProvider to supply translations\n * either as a static map or via a dynamic lookup method.\n */\n\n/** A flat key-value map of translation strings for a single locale */\nexport type TranslationMap = Readonly<Record<string, string>>\n\n/** A complete translations bundle keyed by locale code (e.g. 'en', 'it', 'de') */\nexport type TranslationBundle = Readonly<Record<string, TranslationMap>>\n\n/**\n * Provider interface for addons that supply translations.\n *\n * Addons can provide translations in two ways:\n * 1. A static bundle via `getTranslationBundle()` containing all locales\n * 2. A per-locale lookup via `getTranslations(locale)` for lazy loading\n *\n * At least one method must be implemented. If both are present,\n * `getTranslations()` takes precedence for the requested locale.\n */\nexport interface IAddonTranslationProvider {\n readonly id: string\n\n /**\n * Return translations for a specific locale.\n * Returns undefined if the locale is not supported.\n */\n getTranslations?(locale: string): TranslationMap | undefined\n\n /**\n * Return the full translation bundle containing all supported locales.\n * Useful when the addon ships all translations statically.\n */\n getTranslationBundle?(): TranslationBundle\n}\n\n/**\n * Resolve a translation key against a provider for the given locale.\n * Falls back to 'en' if the requested locale is not available,\n * then falls back to the key itself if no translation is found.\n */\nexport function resolveTranslation(\n provider: IAddonTranslationProvider,\n locale: string,\n key: string,\n): string {\n // Try provider's per-locale method first\n if (provider.getTranslations) {\n const map = provider.getTranslations(locale)\n if (map && key in map) return map[key]!\n\n // Fallback to 'en' if different locale was requested\n if (locale !== 'en') {\n const fallback = provider.getTranslations('en')\n if (fallback && key in fallback) return fallback[key]!\n }\n }\n\n // Try static bundle\n if (provider.getTranslationBundle) {\n const bundle = provider.getTranslationBundle()\n const map = bundle[locale]\n if (map && key in map) return map[key]!\n\n // Fallback to 'en'\n if (locale !== 'en') {\n const fallback = bundle['en']\n if (fallback && key in fallback) return fallback[key]!\n }\n }\n\n // No translation found -- return the key as-is\n return key\n}\n","export interface FeatureManifest {\n streaming: boolean\n notifications: boolean\n objectDetection: boolean\n remoteAccess: boolean\n agentCluster: boolean\n smartHome: boolean\n recordings: boolean\n backup: boolean\n repl: boolean\n}\n\nexport type FeatureFlag = keyof FeatureManifest\n\nexport const DEFAULT_FEATURES: FeatureManifest = {\n streaming: true,\n notifications: true,\n objectDetection: false,\n remoteAccess: true,\n agentCluster: false,\n smartHome: true,\n recordings: true,\n backup: true,\n repl: true,\n}\n","import type { TaskProgress } from './task-handler.js'\n\n// --- Agent capabilities & roles ---\nexport type AgentCapability = 'decoder' | 'transcoder' | 'detector' | 'recorder'\nexport type RolePriority = 'primary' | 'backup' | 'overflow'\n\nexport interface CameraRoleAssignment {\n cameraId: string\n role: AgentCapability\n agentId: string\n priority: RolePriority\n rtspUrl?: string\n detectionConfig?: {\n modelId: string\n runtime: string\n confidence: number\n fps: number\n classes?: string[]\n }\n}\n\n// --- Hub -> Agent messages ---\nexport type HubToAgentMessage =\n | { type: 'assign'; assignment: CameraRoleAssignment }\n | { type: 'unassign'; cameraId: string; role: AgentCapability }\n | { type: 'recording.start'; cameraId: string; rtspUrl: string }\n | { type: 'recording.stop'; cameraId: string }\n | { type: 'benchmark.run'; config: RemoteBenchmarkConfig }\n | { type: 'config.update'; addonId: string; config: Record<string, unknown> }\n | { type: 'task.execute'; taskId: string; taskType: string; payload: unknown }\n | { type: 'task.cancel'; taskId: string }\n | { type: 'addon.install'; package: string; version?: string }\n | { type: 'addon.uninstall'; package: string }\n | { type: 'addon.update'; package: string; version?: string }\n | { type: 'addon.restart' }\n | { type: 'ping' }\n\n// --- Agent -> Hub messages ---\nexport type AgentToHubMessage =\n | { type: 'register'; info: AgentRegistrationInfo }\n | { type: 'heartbeat'; status: AgentRuntimeStatus }\n | { type: 'detection.result'; cameraId: string; detections: DetectionResult[]; timestamp: number; inferenceMs: number }\n | { type: 'recording.segment'; cameraId: string; segment: RecordingSegmentInfo }\n | { type: 'recording.status'; cameraId: string; recording: boolean }\n | { type: 'benchmark.progress'; event: BenchmarkStreamEvent }\n | { type: 'benchmark.result'; report: BenchmarkReport }\n | { type: 'task.result'; taskId: string; success: boolean; result?: unknown; error?: string }\n | { type: 'task.progress'; taskId: string; progress: TaskProgress }\n | { type: 'addon.install-result'; package: string; success: boolean; version?: string; error?: string }\n | { type: 'addon.uninstall-result'; package: string; success: boolean; error?: string }\n | { type: 'addon.update-result'; package: string; success: boolean; version?: string; error?: string }\n | { type: 'log'; level: string; scope: string; message: string }\n | { type: 'pong' }\n\n// --- Binary frame header (29 bytes) ---\nexport const BINARY_FRAME_HEADER_SIZE = 29\nexport const BINARY_FRAME_TYPE = 0x01\n\nexport interface AgentRegistrationInfo {\n id: string\n name: string\n capabilities: AgentCapability[]\n host: string\n port: number\n platform: string\n arch: string\n cpuCores: number\n memoryMB: number\n gpuModel?: string\n pythonRuntimes: string[]\n httpPort: number\n /** Task types this agent can handle (e.g., 'pipeline.decode', 'system.info') */\n taskTypes?: string[]\n /** Installed addons on this agent */\n installedAddons?: string[]\n}\n\nexport interface AgentRuntimeStatus {\n activeCameras: number\n cpuPercent: number\n memoryPercent: number\n fps: Record<string, number>\n errors: string[]\n}\n\nexport interface DetectionResult {\n className: string\n score: number\n bbox: [number, number, number, number]\n}\n\nexport interface RecordingSegmentInfo {\n id: string\n startTime: number\n endTime: number\n duration: number\n sizeBytes: number\n path: string\n format: 'mp4' | 'ts'\n}\n\nexport interface RemoteBenchmarkConfig {\n runtime: string\n modelId?: string\n durationMs: number\n warmupMs: number\n inputWidth: number\n inputHeight: number\n}\n\nexport interface BenchmarkStreamEvent {\n phase: 'warmup' | 'running'\n iteration: number\n inferenceMs: number\n}\n\nexport interface BenchmarkReport {\n runtime: string\n modelId?: string\n iterations: number\n meanMs: number\n p50Ms: number\n p95Ms: number\n p99Ms: number\n minMs: number\n maxMs: number\n}\n","/**\n * Detection Analysis Pipeline -- processes raw detections through\n * configurable stages to produce tracked, enriched, actionable events.\n */\n\nimport type { Detection } from './device-capabilities/object-detector.js'\nimport type { VideoFrame } from './camera-pipeline.js'\n\n// --- Detection type const unions ---\n\nexport const DETECTION_TYPES = ['person', 'vehicle', 'animal', 'package'] as const\nexport type DetectionType = typeof DETECTION_TYPES[number]\n\nexport const SUB_DETECTION_TYPES = ['face', 'plate'] as const\nexport type SubDetectionType = typeof SUB_DETECTION_TYPES[number]\n\nexport const RECOGNITION_TYPES = ['face', 'plate', 'clip', 'custom'] as const\nexport type RecognitionType = typeof RECOGNITION_TYPES[number]\n\n// --- Analysis Context ---\n\nexport interface AnalysisContext {\n readonly deviceId: string\n readonly frame: VideoFrame\n readonly timestamp: number\n readonly rawDetections: readonly Detection[]\n readonly trackedDetections: readonly ServerTrackedDetection[]\n readonly events: readonly AnalysisEvent[]\n readonly metadata: Readonly<Record<string, unknown>>\n}\n\n// --- Tracked Detection ---\n\nexport interface ServerTrackedDetection {\n readonly trackId: string\n readonly detection: Detection\n readonly crop?: Buffer\n readonly tracking: TrackingInfo\n readonly subDetections: readonly SubDetection[]\n readonly recognitions: readonly RecognitionResult[]\n readonly zones: readonly string[]\n readonly previousZones: readonly string[]\n}\n\nexport interface TrackingInfo {\n readonly age: number\n readonly state: 'moving' | 'stationary' | 'new' | 'lost'\n readonly stationaryDuration: number\n readonly velocity: { readonly dx: number; readonly dy: number }\n readonly positionHistory: ReadonlyArray<{ readonly x: number; readonly y: number; readonly t: number }>\n}\n\n// --- Sub-Detection ---\n\nexport interface SubDetection {\n readonly detectionType: SubDetectionType\n readonly boundingBox: readonly [number, number, number, number]\n readonly score: number\n readonly crop?: Buffer\n}\n\n// --- Recognition ---\n\nexport interface RecognitionResult {\n readonly recognitionType: RecognitionType\n readonly label: string\n readonly score: number\n readonly embedding?: readonly number[]\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n// --- Analysis Events ---\n\nexport interface AnalysisEvent {\n readonly category: string\n readonly severity: 'info' | 'warning' | 'alert'\n readonly detection: ServerTrackedDetection\n readonly description: string\n readonly data: Readonly<Record<string, unknown>>\n}\n\n// --- Analysis Stage ---\n\nexport interface IAnalysisStage {\n readonly id: string\n readonly name: string\n readonly priority: number\n enabled: boolean\n process(ctx: AnalysisContext): Promise<AnalysisContext>\n}\n\n// --- Sub-Detector Interface ---\n\nexport interface ISubDetector {\n readonly detectionType: SubDetectionType\n readonly targetClasses: readonly string[]\n detect(crop: Buffer, cropWidth: number, cropHeight: number): Promise<SubDetection[]>\n}\n\nexport interface IFaceDetector extends ISubDetector {\n readonly detectionType: 'face'\n}\n\nexport interface IPlateDetector extends ISubDetector {\n readonly detectionType: 'plate'\n}\n\n// --- Recognizer Interface ---\n\nexport interface IRecognizer {\n readonly recognitionType: RecognitionType\n recognize(crop: Buffer, width: number, height: number): Promise<RecognitionResult | null>\n}\n\nexport interface IFaceRecognizer extends IRecognizer {\n getEmbedding(crop: Buffer): Promise<Float32Array>\n registerKnown(label: string, embedding: Float32Array): void\n}\n\nexport interface IPlateRecognizer extends IRecognizer {\n readonly recognitionType: 'plate'\n}\n\n// --- Audio Classifier ---\n\nexport interface IAudioClassifier {\n readonly ready: boolean\n initialize(): Promise<void>\n classify(\n audioSamples: Float32Array,\n sampleRate: number,\n topN?: number,\n ): Promise<readonly AudioClassification[]>\n release(): Promise<void>\n}\n\nexport interface AudioClassification {\n readonly classIndex: number\n readonly className: string\n readonly score: number\n readonly isSurveillanceRelevant: boolean\n}\n\n// --- Pipeline Stage Interfaces ---\n\nexport interface IClassFilterStage extends IAnalysisStage {\n readonly id: 'class-filter'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n getConfig(deviceId: string): Record<string, unknown>\n}\n\nexport interface ITrackerStage extends IAnalysisStage {\n readonly id: 'tracker'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n getConfig(deviceId: string): Record<string, unknown>\n resetDevice(deviceId: string): void\n}\n\nexport interface ISubDetectionStage extends IAnalysisStage {\n readonly id: 'sub-detection'\n registerDetector(detector: ISubDetector): void\n}\n\nexport interface IRecognitionStage extends IAnalysisStage {\n readonly id: 'recognition'\n registerRecognizer(recognizer: IRecognizer): void\n}\n\nexport interface IZoneAnalysisStage extends IAnalysisStage {\n readonly id: 'zone-analysis'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\nexport interface IEventGenerationStage extends IAnalysisStage {\n readonly id: 'event-generation'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\nexport interface IObjectSnapshotStage extends IAnalysisStage {\n readonly id: 'object-snapshot'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\n// --- Analysis Pipeline ---\n\nexport interface IAnalysisPipeline {\n addStage(stage: IAnalysisStage): void\n removeStage(stageId: string): void\n getStages(): readonly IAnalysisStage[]\n analyze(deviceId: string, frame: VideoFrame, rawDetections: Detection[]): Promise<AnalysisContext>\n}\n\n// --- Helper functions ---\n\nexport function createAnalysisContext(\n deviceId: string,\n frame: VideoFrame,\n rawDetections: Detection[],\n): AnalysisContext {\n return {\n deviceId,\n frame,\n timestamp: frame.timestamp,\n rawDetections,\n trackedDetections: [],\n events: [],\n metadata: {},\n }\n}\n\nexport function enrichContext(\n ctx: AnalysisContext,\n updates: Partial<Pick<AnalysisContext, 'trackedDetections' | 'events' | 'metadata'>>,\n): AnalysisContext {\n return {\n ...ctx,\n trackedDetections: updates.trackedDetections ?? ctx.trackedDetections,\n events: updates.events ?? ctx.events,\n metadata: updates.metadata ? { ...ctx.metadata, ...updates.metadata } : ctx.metadata,\n }\n}\n","/**\n * Analysis Persistence Types — interfaces for event persistence, track trails,\n * retention, session tracking, and known faces.\n *\n * These interfaces define the contracts used by the server; concrete\n * implementations live in addon-pipeline and are received via CapabilityRegistry.\n */\n\nimport type { ServerTrackedDetection } from './server-analysis.js'\n\n// ---------------------------------------------------------------------------\n// Event Persistence\n// ---------------------------------------------------------------------------\n\nexport interface ObjectSnapshotResult {\n readonly trackId: string\n readonly thumbnail?: Buffer\n readonly fullCrop?: Buffer\n}\n\nexport interface AnnotatedSnapshotResult {\n readonly thumbnail: Buffer\n readonly full: Buffer\n}\n\nexport interface PersistableEvent {\n readonly id: string\n readonly timestamp: number\n readonly deviceId: string\n readonly category: string\n readonly className: string\n readonly score: number\n readonly trackId: string\n readonly severity: string\n readonly description: string\n readonly data: Record<string, unknown>\n readonly mediaFiles: readonly string[]\n}\n\nexport interface EventBufferStatus {\n readonly eventCount: number\n readonly mediaCount: number\n readonly mediaSizeMB: number\n}\n\nexport type TrackMediaType =\n | 'crop-thumb'\n | 'crop-full'\n | 'debug-annotated-thumb'\n | 'debug-annotated-full'\n | 'original'\n | 'original-thumb'\n | 'inline-crop'\n | 'unknown'\n\nexport interface TrackMediaFile {\n readonly path: string\n readonly type: TrackMediaType\n readonly data: Buffer\n readonly source: 'buffer' | 'storage'\n}\n\n// ---------------------------------------------------------------------------\n// Track Trail\n// ---------------------------------------------------------------------------\n\nexport interface TrackCaptureConfig {\n readonly enabled: boolean\n readonly snapshotIntervalMs: number\n readonly maxTrailLength: number\n readonly saveThumbnails: boolean\n readonly thumbnailSize: { readonly width: number; readonly height: number }\n}\n\nexport interface TrackPosition {\n readonly x: number\n readonly y: number\n readonly timestamp: number\n readonly bbox: readonly [number, number, number, number]\n}\n\nexport interface TrackSnapshot {\n readonly timestamp: number\n readonly position: TrackPosition\n readonly thumbnailPath: string\n}\n\nexport interface TrackTrail {\n readonly trackId: string\n readonly deviceId: string\n readonly className: string\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly positions: readonly TrackPosition[]\n readonly snapshots: readonly TrackSnapshot[]\n readonly totalDistance: number\n readonly zonesVisited: readonly string[]\n readonly active: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Retention\n// ---------------------------------------------------------------------------\n\nexport interface RetentionConfig {\n readonly cleanupIntervalMs: number\n readonly detectionEventsDays: number\n readonly audioLevelsDays: number\n /** @deprecated — snapshots are tied to events, use detectionEventsDays */\n readonly snapshotsDays: number\n readonly deviceOverrides?: Readonly<Record<string, Partial<Pick<RetentionConfig, 'detectionEventsDays' | 'audioLevelsDays' | 'snapshotsDays'>>>>\n}\n\nexport const DEFAULT_RETENTION: RetentionConfig = {\n cleanupIntervalMs: 60 * 60 * 1000,\n detectionEventsDays: 30,\n audioLevelsDays: 7,\n snapshotsDays: 14,\n}\n\nexport interface RetentionReport {\n readonly deletedEvents: number\n readonly deletedAudioRecords: number\n readonly deletedSnapshots: number\n}\n\n// ---------------------------------------------------------------------------\n// Session Tracker\n// ---------------------------------------------------------------------------\n\nexport interface SessionTrack {\n readonly trackId: string\n readonly deviceId: string\n readonly className: string\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly totalFrames: number\n readonly lastDetection: ServerTrackedDetection\n readonly state: string\n readonly positions: ReadonlyArray<{ readonly x: number; readonly y: number; readonly t: number }>\n readonly embedding?: Float32Array\n readonly globalId?: string\n readonly bestCrop?: Buffer\n}\n\nexport interface GlobalIdentity {\n readonly globalId: string\n readonly embedding: Float32Array\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly deviceIds: ReadonlyArray<string>\n}\n\n// ---------------------------------------------------------------------------\n// Known Faces\n// ---------------------------------------------------------------------------\n\nexport interface ClipRecognizer {\n getEmbedding(imageBuffer: Buffer): Promise<Float32Array>\n}\n\nexport interface KnownFaceEntry {\n readonly id: string\n readonly label: string\n readonly group?: string\n readonly embedding: readonly number[]\n readonly cropBase64: string\n readonly createdAt: number\n readonly updatedAt: number\n readonly source?: string\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n// ---------------------------------------------------------------------------\n// Recording Addon (generic interface for recording engine access)\n// ---------------------------------------------------------------------------\n\n/**\n * Interface for the recording addon — the server uses this instead of\n * importing PipelineAddon directly from addon-pipeline.\n */\nexport interface IRecordingAddon {\n getCoordinator(): IRecordingCoordinator\n getRecordingDb(): IRecordingDb\n}\n\n/**\n * Minimal coordinator interface for the server's recording router.\n */\nexport interface IRecordingCoordinator {\n enableRecording(deviceId: string, options: {\n policy: unknown\n ffmpegOverrides?: unknown\n }): Promise<void>\n disableRecording(deviceId: string): Promise<void>\n isRecording(deviceId: string): boolean\n readonly playlistGenerator: {\n generate(\n deviceId: string,\n streamId: string,\n startTime: number,\n endTime: number,\n options?: { live?: boolean },\n ): unknown\n }\n readonly storageEstimator: {\n estimateForDevice(\n deviceId: string,\n motionInput?: { avgEventsPerDay: number; avgDurationSec: number },\n ): { totalEstimatedGb: number; [key: string]: unknown }\n }\n}\n\n/**\n * Minimal recording database interface for the server's recording router.\n */\nexport interface IRecordingDb {\n upsertStorageConfig(config: {\n deviceId: string\n dataCategory: string\n storageName: string\n subDirectory: string\n retentionDays: number | null\n retentionGb: number | null\n }): void\n getPolicy(deviceId: string): unknown\n getEnabledPolicies(): Array<{ deviceId: string; [key: string]: unknown }>\n querySegments(deviceId: string, streamId: string, startTime: number, endTime: number): unknown\n getAvailability(deviceId: string, startTime: number, endTime: number): unknown\n getStorageUsage(deviceId: string, streamId: string): unknown\n upsertPolicy(policy: unknown): void\n findNearestThumbnail(deviceId: string, timestamp: number, category: string): unknown\n getMotionStats(deviceId: string, startTime: number, endTime: number): {\n avgEventsPerDay: number\n avgDurationSec: number\n dutyCyclePercent: number\n totalEvents: number\n }\n resolveStorageConfig(deviceId: string, dataCategory: string): unknown\n}\n\n// ---------------------------------------------------------------------------\n// Sub-service interfaces — used by the server's thin NestJS wrappers\n// to receive delegates via CapabilityRegistry.\n// ---------------------------------------------------------------------------\n\nexport interface IEventPersistence {\n start(): void\n stop(): void\n saveDetectionCrops(eventId: string, crops: readonly ObjectSnapshotResult[]): void\n saveAnnotatedFrame(eventId: string, result: AnnotatedSnapshotResult): void\n saveOriginalFrame(eventId: string, frame: import('./camera-pipeline.js').VideoFrame): Promise<void>\n getEventMedia(eventId: string): Promise<unknown>\n getTrackMedia(trackId: string): Promise<unknown>\n getDeviceMedia(deviceId: string, since?: number, until?: number): Promise<unknown>\n getBufferStatus(): unknown\n flush(): Promise<void>\n}\n\nexport interface ITrackTrail {\n setConfig(deviceId: string, config: Partial<TrackCaptureConfig>): void\n getConfig(deviceId: string): unknown\n recordFrame(ctx: unknown): Promise<void>\n getActiveTrail(trackId: string): unknown\n getActiveTrails(deviceId: string): unknown\n getPersistedTrail(trackId: string): Promise<unknown>\n getTrail(trackId: string): Promise<unknown>\n listTrails(deviceId: string, options?: {\n since?: number\n until?: number\n limit?: number\n className?: string\n }): Promise<unknown>\n}\n\nexport interface IRetention {\n start(): void\n stop(): void\n runCleanup(): Promise<unknown>\n setConfig(update: Partial<RetentionConfig>): void\n getConfig(): unknown\n forceCleanup(): Promise<unknown>\n}\n\nexport interface ISessionTracker {\n updateFromAnalysis(deviceId: string, ctx: unknown): void\n getActiveTracks(deviceId: string): unknown\n getAllActiveTracks(): unknown\n getTrack(deviceId: string, trackId: string): unknown\n getTrackCounts(): unknown\n clearDevice(deviceId: string): void\n clearAll(): void\n getGlobalPool(): unknown\n}\n\nexport interface IKnownFaces {\n register(entry: KnownFaceEntry): Promise<void>\n listAll(): Promise<unknown>\n delete(id: string): Promise<void>\n update(id: string, updates: Partial<Pick<KnownFaceEntry, 'label' | 'group'>>): Promise<void>\n recalculateEmbedding(id: string, clipRecognizer: ClipRecognizer): Promise<void>\n findMatch(embedding: Float32Array, threshold: number): Promise<unknown>\n batchRegister(\n entries: ReadonlyArray<{ readonly label: string; readonly cropBase64: string; readonly group?: string }>,\n clipRecognizer: ClipRecognizer,\n ): Promise<unknown>\n}\n\n/**\n * Composite interface exposed via CapabilityRegistry as the\n * 'analysis-data-persistence' singleton. Each sub-service is wired\n * individually to the corresponding NestJS wrapper service.\n */\nexport interface IAnalysisDataPersistence {\n readonly eventPersistence: IEventPersistence\n readonly knownFaces: IKnownFaces\n readonly sessionTracker: ISessionTracker\n readonly retention: IRetention\n readonly trackTrail: ITrackTrail\n}\n\n// ---------------------------------------------------------------------------\n// Provider Connection Testing\n// ---------------------------------------------------------------------------\n\nexport interface TestConnectionResult {\n readonly success: boolean\n readonly version?: string\n readonly cameraCount?: number\n readonly error?: string\n}\n\n/**\n * Generic interface for testing provider connections.\n * Each provider addon can expose a connection tester.\n */\nexport interface IProviderConnectionTester {\n testConnection(): Promise<TestConnectionResult>\n}\n","/**\n * System settings UI schemas — the single source of truth for all settings sections.\n *\n * These are defined in @camstack/types so that:\n * - The backend can serve them via API\n * - Addons can reference/extend them\n * - The frontend fetches them at runtime (no hardcoded duplication)\n *\n * Values are stored in the SQL system_settings table, not config.yaml.\n * Only `server` is read-only (loaded from config.yaml at bootstrap).\n */\n\nimport type { ConfigUISchema } from '../interfaces/config-ui.js'\n\n// ---------------------------------------------------------------------------\n// Section type\n// ---------------------------------------------------------------------------\n\nexport type SystemSettingsSection =\n | 'server' | 'auth' | 'features' | 'storage' | 'logging' | 'addons'\n | 'recording' | 'streaming' | 'ffmpeg' | 'detection' | 'backup' | 'retention'\n\n/** Sections where fields are read-only (bootstrap from config.yaml). */\nexport const READ_ONLY_SECTIONS: ReadonlySet<SystemSettingsSection> = new Set<SystemSettingsSection>([\n 'server',\n])\n\n// ---------------------------------------------------------------------------\n// Tab definitions (rendering order)\n// ---------------------------------------------------------------------------\n\nexport interface SettingsTabDef {\n readonly id: SystemSettingsSection\n readonly label: string\n}\n\nexport const SETTINGS_TABS: readonly SettingsTabDef[] = [\n { id: 'server', label: 'Server' },\n { id: 'logging', label: 'Logs' },\n { id: 'recording', label: 'Recording' },\n { id: 'ffmpeg', label: 'FFmpeg' },\n { id: 'detection', label: 'Detection' },\n { id: 'auth', label: 'Auth' },\n { id: 'retention', label: 'Retention' },\n] as const\n\n// ---------------------------------------------------------------------------\n// Schemas\n// ---------------------------------------------------------------------------\n\nconst SERVER_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'server-info',\n title: 'Server',\n description: 'Core server connection settings (read-only)',\n columns: 2,\n fields: [\n {\n type: 'info',\n key: 'server-restart-note',\n label: 'Restart required',\n content: 'Server settings are read-only. Change them in config.yaml and restart.',\n variant: 'warning',\n },\n {\n type: 'text',\n key: 'port',\n label: 'Port',\n disabled: true,\n description: 'Listening port',\n },\n {\n type: 'text',\n key: 'host',\n label: 'Host',\n disabled: true,\n description: 'Bind address',\n },\n {\n type: 'text',\n key: 'dataPath',\n label: 'Data Path',\n disabled: true,\n description: 'Root data directory',\n span: 2,\n },\n ],\n },\n ],\n}\n\n// Storage paths are managed via CAMSTACK_DATA env var — no UI settings needed.\nconst STORAGE_SCHEMA: ConfigUISchema = {\n sections: [],\n}\n\nconst LOGGING_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'logging-settings',\n title: 'Logging',\n description: 'Global log verbosity. Retention is managed per log-destination addon.',\n columns: 1,\n fields: [\n {\n type: 'select',\n key: 'level',\n label: 'Log Level',\n options: [\n { value: 'debug', label: 'Debug' },\n { value: 'info', label: 'Info' },\n { value: 'warn', label: 'Warn' },\n { value: 'error', label: 'Error' },\n ],\n },\n ],\n },\n ],\n}\n\nconst RECORDING_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'recording-settings',\n title: 'Recording',\n description: 'Video recording segment and retention defaults',\n columns: 2,\n fields: [\n {\n type: 'number',\n key: 'segmentDurationSeconds',\n label: 'Segment Duration',\n description: 'Length of each recording segment',\n min: 1,\n max: 60,\n step: 1,\n unit: 'seconds',\n },\n {\n type: 'number',\n key: 'defaultRetentionDays',\n label: 'Default Retention',\n description: 'Days to keep recordings before auto-delete',\n min: 1,\n max: 365,\n step: 1,\n unit: 'days',\n },\n ],\n },\n ],\n}\n\n// Streaming ports are addon-specific (go2rtc owns its ports).\n// No system-level streaming schema needed.\n\nconst FFMPEG_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'ffmpeg-settings',\n title: 'FFmpeg',\n description: 'FFmpeg binary and hardware acceleration settings',\n columns: 2,\n fields: [\n {\n type: 'text',\n key: 'binaryPath',\n label: 'Binary Path',\n description: 'Path to ffmpeg executable',\n placeholder: 'ffmpeg',\n span: 2,\n },\n {\n type: 'select',\n key: 'hwAccel',\n label: 'Hardware Acceleration',\n description: 'GPU decoding/encoding backend',\n options: [\n { value: 'auto', label: 'Auto-detect' },\n { value: 'none', label: 'None (CPU only)' },\n { value: 'videotoolbox', label: 'VideoToolbox (macOS)' },\n { value: 'vaapi', label: 'VA-API (Linux Intel/AMD)' },\n { value: 'qsv', label: 'QSV (Intel Quick Sync)' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n {\n type: 'number',\n key: 'threadCount',\n label: 'Thread Count',\n description: '0 = auto (let FFmpeg decide)',\n min: 0,\n max: 16,\n step: 1,\n },\n ],\n },\n ],\n}\n\nconst DETECTION_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'detection-fps',\n title: 'Frame Rates',\n description: 'Default analysis frame rates for new cameras',\n columns: 2,\n fields: [\n {\n type: 'number',\n key: 'defaultMotionFps',\n label: 'Motion FPS',\n description: 'Frames per second for motion detection',\n min: 1,\n max: 30,\n step: 1,\n unit: 'fps',\n },\n {\n type: 'number',\n key: 'defaultDetectionFps',\n label: 'Detection FPS',\n description: 'Frames per second for object detection',\n min: 1,\n max: 30,\n step: 1,\n unit: 'fps',\n },\n ],\n },\n {\n id: 'detection-thresholds',\n title: 'Thresholds',\n description: 'Default confidence and cooldown for detections',\n columns: 2,\n fields: [\n {\n type: 'slider',\n key: 'defaultConfidenceThreshold',\n label: 'Confidence Threshold',\n description: 'Minimum confidence to trigger a detection event',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n showValue: true,\n },\n {\n type: 'number',\n key: 'defaultCooldownSeconds',\n label: 'Cooldown',\n description: 'Seconds between duplicate events',\n min: 0,\n max: 300,\n step: 1,\n unit: 'seconds',\n },\n ],\n },\n {\n id: 'detection-tracker',\n title: 'Tracker',\n description: 'SORT/IoU tracker parameters',\n columns: 3,\n fields: [\n {\n type: 'number',\n key: 'trackerMaxAgeFrames',\n label: 'Max Age',\n description: 'Frames before a lost track is removed',\n min: 1,\n max: 120,\n step: 1,\n unit: 'frames',\n },\n {\n type: 'number',\n key: 'trackerMinHits',\n label: 'Min Hits',\n description: 'Consecutive detections to confirm a track',\n min: 1,\n max: 20,\n step: 1,\n },\n {\n type: 'slider',\n key: 'trackerIouThreshold',\n label: 'IoU Threshold',\n description: 'Minimum IoU to associate detection with track',\n min: 0.1,\n max: 0.9,\n step: 0.05,\n showValue: true,\n },\n ],\n },\n ],\n}\n\n// Backup retention is addon-specific (local-backup owns its retention count).\n// No system-level backup schema needed.\n\nconst AUTH_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'auth-settings',\n title: 'Authentication',\n description: 'Token and session settings',\n columns: 1,\n fields: [\n {\n type: 'text',\n key: 'tokenExpiry',\n label: 'Token Expiry',\n description: 'JWT token lifetime (e.g. 24h, 7d, 1h)',\n placeholder: '24h',\n },\n ],\n },\n ],\n}\n\nconst RETENTION_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'retention-settings',\n title: 'Retention',\n description: 'Data retention periods for analytics data',\n columns: 1,\n fields: [\n {\n type: 'slider',\n key: 'detectionEventsDays',\n label: 'Detection Events Retention',\n min: 1,\n max: 365,\n unit: 'days',\n showValue: true,\n span: 1,\n },\n {\n type: 'slider',\n key: 'audioLevelsDays',\n label: 'Audio Levels Retention',\n min: 1,\n max: 90,\n unit: 'days',\n showValue: true,\n span: 1,\n },\n ],\n },\n ],\n}\n\n// ---------------------------------------------------------------------------\n// Registry: section → schema\n// ---------------------------------------------------------------------------\n\nexport const SYSTEM_SETTINGS_SCHEMAS: Readonly<Record<SystemSettingsSection, ConfigUISchema>> = {\n server: SERVER_SCHEMA,\n storage: STORAGE_SCHEMA,\n logging: LOGGING_SCHEMA,\n recording: RECORDING_SCHEMA,\n ffmpeg: FFMPEG_SCHEMA,\n detection: DETECTION_SCHEMA,\n auth: AUTH_SCHEMA,\n retention: RETENTION_SCHEMA,\n // These sections have no UI form — managed programmatically or addon-specific\n streaming: { sections: [] },\n backup: { sections: [] },\n features: { sections: [] },\n addons: { sections: [] },\n}\n\n/**\n * Get the UI schema for a settings section.\n * Returns undefined for unknown sections.\n */\nexport function getSystemSettingsSchema(section: string): ConfigUISchema | undefined {\n return (SYSTEM_SETTINGS_SCHEMAS as Record<string, ConfigUISchema>)[section]\n}\n","export const HF_REPO = 'camstack/camstack-models'\nexport const HF_BASE_URL = `https://huggingface.co/${HF_REPO}/resolve/main`\n","export function hfModelUrl(repo: string, path: string): string {\n return `https://huggingface.co/${repo}/resolve/main/${path}`\n}\n","/** Cosine similarity between two embedding vectors */\nexport function cosineSimilarity(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) return 0\n let dotProduct = 0\n let normA = 0\n let normB = 0\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i]! * b[i]!\n normA += a[i]! * a[i]!\n normB += b[i]! * b[i]!\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB)\n return denom === 0 ? 0 : dotProduct / denom\n}\n","import type { LabelDefinition, ClassMapDefinition } from '../types/labels.js'\n\nexport const COCO_80_LABELS: readonly LabelDefinition[] = [\n { id: 'person', name: 'Person' },\n { id: 'bicycle', name: 'Bicycle' },\n { id: 'car', name: 'Car' },\n { id: 'motorcycle', name: 'Motorcycle' },\n { id: 'airplane', name: 'Airplane' },\n { id: 'bus', name: 'Bus' },\n { id: 'train', name: 'Train' },\n { id: 'truck', name: 'Truck' },\n { id: 'boat', name: 'Boat' },\n { id: 'traffic light', name: 'Traffic Light' },\n { id: 'fire hydrant', name: 'Fire Hydrant' },\n { id: 'stop sign', name: 'Stop Sign' },\n { id: 'parking meter', name: 'Parking Meter' },\n { id: 'bench', name: 'Bench' },\n { id: 'bird', name: 'Bird' },\n { id: 'cat', name: 'Cat' },\n { id: 'dog', name: 'Dog' },\n { id: 'horse', name: 'Horse' },\n { id: 'sheep', name: 'Sheep' },\n { id: 'cow', name: 'Cow' },\n { id: 'elephant', name: 'Elephant' },\n { id: 'bear', name: 'Bear' },\n { id: 'zebra', name: 'Zebra' },\n { id: 'giraffe', name: 'Giraffe' },\n { id: 'backpack', name: 'Backpack' },\n { id: 'umbrella', name: 'Umbrella' },\n { id: 'handbag', name: 'Handbag' },\n { id: 'tie', name: 'Tie' },\n { id: 'suitcase', name: 'Suitcase' },\n { id: 'frisbee', name: 'Frisbee' },\n { id: 'skis', name: 'Skis' },\n { id: 'snowboard', name: 'Snowboard' },\n { id: 'sports ball', name: 'Sports Ball' },\n { id: 'kite', name: 'Kite' },\n { id: 'baseball bat', name: 'Baseball Bat' },\n { id: 'baseball glove', name: 'Baseball Glove' },\n { id: 'skateboard', name: 'Skateboard' },\n { id: 'surfboard', name: 'Surfboard' },\n { id: 'tennis racket', name: 'Tennis Racket' },\n { id: 'bottle', name: 'Bottle' },\n { id: 'wine glass', name: 'Wine Glass' },\n { id: 'cup', name: 'Cup' },\n { id: 'fork', name: 'Fork' },\n { id: 'knife', name: 'Knife' },\n { id: 'spoon', name: 'Spoon' },\n { id: 'bowl', name: 'Bowl' },\n { id: 'banana', name: 'Banana' },\n { id: 'apple', name: 'Apple' },\n { id: 'sandwich', name: 'Sandwich' },\n { id: 'orange', name: 'Orange' },\n { id: 'broccoli', name: 'Broccoli' },\n { id: 'carrot', name: 'Carrot' },\n { id: 'hot dog', name: 'Hot Dog' },\n { id: 'pizza', name: 'Pizza' },\n { id: 'donut', name: 'Donut' },\n { id: 'cake', name: 'Cake' },\n { id: 'chair', name: 'Chair' },\n { id: 'couch', name: 'Couch' },\n { id: 'potted plant', name: 'Potted Plant' },\n { id: 'bed', name: 'Bed' },\n { id: 'dining table', name: 'Dining Table' },\n { id: 'toilet', name: 'Toilet' },\n { id: 'tv', name: 'TV' },\n { id: 'laptop', name: 'Laptop' },\n { id: 'mouse', name: 'Mouse' },\n { id: 'remote', name: 'Remote' },\n { id: 'keyboard', name: 'Keyboard' },\n { id: 'cell phone', name: 'Cell Phone' },\n { id: 'microwave', name: 'Microwave' },\n { id: 'oven', name: 'Oven' },\n { id: 'toaster', name: 'Toaster' },\n { id: 'sink', name: 'Sink' },\n { id: 'refrigerator', name: 'Refrigerator' },\n { id: 'book', name: 'Book' },\n { id: 'clock', name: 'Clock' },\n { id: 'vase', name: 'Vase' },\n { id: 'scissors', name: 'Scissors' },\n { id: 'teddy bear', name: 'Teddy Bear' },\n { id: 'hair drier', name: 'Hair Drier' },\n { id: 'toothbrush', name: 'Toothbrush' },\n] as const\n\nexport const MACRO_LABELS: readonly LabelDefinition[] = [\n { id: 'person', name: 'Person' },\n { id: 'vehicle', name: 'Vehicle' },\n { id: 'animal', name: 'Animal' },\n] as const\n\nexport const COCO_TO_MACRO: ClassMapDefinition = {\n mapping: {\n person: 'person',\n bicycle: 'vehicle',\n car: 'vehicle',\n motorcycle: 'vehicle',\n airplane: 'vehicle',\n bus: 'vehicle',\n train: 'vehicle',\n truck: 'vehicle',\n boat: 'vehicle',\n bird: 'animal',\n cat: 'animal',\n dog: 'animal',\n horse: 'animal',\n sheep: 'animal',\n cow: 'animal',\n elephant: 'animal',\n bear: 'animal',\n zebra: 'animal',\n giraffe: 'animal',\n },\n preserveOriginal: true,\n}\n","export enum DeviceType {\n Camera = 'camera',\n}\n\nexport interface DeviceTypeInfo {\n readonly type: DeviceType\n readonly label: string\n readonly icon: string // lucide icon name\n}\n\nexport const DEVICE_TYPE_INFO: Record<DeviceType, DeviceTypeInfo> = {\n [DeviceType.Camera]: { type: DeviceType.Camera, label: 'Camera', icon: 'camera' },\n}\n"],"mappings":"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","names":["DeviceType"]}
1
+ {"version":3,"sources":["../src/types/io.js","../src/types/labels.js","../src/types/detection.js","../src/types/tracked.js","../src/types/events.js","../src/types/config.js","../src/types/entities.js","../src/types/zones.js","../src/types/models.js","../src/types/pipeline.js","../src/types/live-state.js","../src/types/analytics.js","../src/interfaces/storage-backend.ts","../src/interfaces/addon-i18n.ts","../src/interfaces/feature-flags.ts","../src/interfaces/agent-protocol.ts","../src/interfaces/server-analysis.ts","../src/interfaces/analysis-persistence.ts","../src/schemas/system-settings-schemas.ts","../src/constants.ts","../src/utils/hf-url.ts","../src/utils/cosine-similarity.ts","../src/catalogs/coco-classmap.ts","../src/types/device-type.ts","../src/index.ts"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=io.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=labels.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=detection.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=tracked.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=events.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=config.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=entities.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=zones.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=models.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=pipeline.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=live-state.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=analytics.js.map","/**\n * @deprecated — This file contains legacy storage backend interfaces.\n * Use the new interfaces from './storage.ts' instead:\n * - IStorageProvider (capability: 'storage')\n * - ISettingsBackend (capability: 'settings-store')\n * - IEmbeddingsBackend (capability: 'embeddings')\n */\n\nimport type { StorageLocationType } from './storage.js'\n\n/** @deprecated Use IStorageProvider from storage.ts */\nexport interface IStorageBackend {\n readonly type: string\n readonly basePath: string\n resolve(subpath: string): string\n resolve(location: StorageLocationType, ...segments: string[]): string\n isAvailable(location?: StorageLocationType): boolean\n initialize(): Promise<void>\n getLocationPath?(location: StorageLocationType): string\n}\n\n/** @deprecated */\nexport interface StorageLocationConfig {\n readonly name: string\n readonly basePath: string\n readonly backendType?: string\n}\n\n/** @deprecated Use DEFAULT_LOCATION_SUBDIRS from storage.ts */\nexport const DEFAULT_LOCATION_SUBPATHS: Record<string, string> = {\n 'recordings-high': 'recordings-high',\n 'recordings-low': 'recordings-low',\n 'recordings-clips': 'recordings-clips',\n 'event-images': 'event-images',\n 'models': 'models',\n 'addons-data': 'addons-data',\n 'cache': '/tmp/camstack-cache',\n 'logs': 'logs',\n}\n","/**\n * Addon i18n interface -- allows addons to provide translations\n * for their UI labels, descriptions, and config schema fields.\n *\n * Addons implement IAddonTranslationProvider to supply translations\n * either as a static map or via a dynamic lookup method.\n */\n\n/** A flat key-value map of translation strings for a single locale */\nexport type TranslationMap = Readonly<Record<string, string>>\n\n/** A complete translations bundle keyed by locale code (e.g. 'en', 'it', 'de') */\nexport type TranslationBundle = Readonly<Record<string, TranslationMap>>\n\n/**\n * Provider interface for addons that supply translations.\n *\n * Addons can provide translations in two ways:\n * 1. A static bundle via `getTranslationBundle()` containing all locales\n * 2. A per-locale lookup via `getTranslations(locale)` for lazy loading\n *\n * At least one method must be implemented. If both are present,\n * `getTranslations()` takes precedence for the requested locale.\n */\nexport interface IAddonTranslationProvider {\n readonly id: string\n\n /**\n * Return translations for a specific locale.\n * Returns undefined if the locale is not supported.\n */\n getTranslations?(locale: string): TranslationMap | undefined\n\n /**\n * Return the full translation bundle containing all supported locales.\n * Useful when the addon ships all translations statically.\n */\n getTranslationBundle?(): TranslationBundle\n}\n\n/**\n * Resolve a translation key against a provider for the given locale.\n * Falls back to 'en' if the requested locale is not available,\n * then falls back to the key itself if no translation is found.\n */\nexport function resolveTranslation(\n provider: IAddonTranslationProvider,\n locale: string,\n key: string,\n): string {\n // Try provider's per-locale method first\n if (provider.getTranslations) {\n const map = provider.getTranslations(locale)\n if (map && key in map) return map[key]!\n\n // Fallback to 'en' if different locale was requested\n if (locale !== 'en') {\n const fallback = provider.getTranslations('en')\n if (fallback && key in fallback) return fallback[key]!\n }\n }\n\n // Try static bundle\n if (provider.getTranslationBundle) {\n const bundle = provider.getTranslationBundle()\n const map = bundle[locale]\n if (map && key in map) return map[key]!\n\n // Fallback to 'en'\n if (locale !== 'en') {\n const fallback = bundle['en']\n if (fallback && key in fallback) return fallback[key]!\n }\n }\n\n // No translation found -- return the key as-is\n return key\n}\n","export interface FeatureManifest {\n streaming: boolean\n notifications: boolean\n objectDetection: boolean\n remoteAccess: boolean\n agentCluster: boolean\n smartHome: boolean\n recordings: boolean\n backup: boolean\n repl: boolean\n}\n\nexport type FeatureFlag = keyof FeatureManifest\n\nexport const DEFAULT_FEATURES: FeatureManifest = {\n streaming: true,\n notifications: true,\n objectDetection: false,\n remoteAccess: true,\n agentCluster: false,\n smartHome: true,\n recordings: true,\n backup: true,\n repl: true,\n}\n","import type { TaskProgress } from './task-handler.js'\n\n// --- Agent capabilities & roles ---\nexport type AgentCapability = 'decoder' | 'transcoder' | 'detector' | 'recorder'\nexport type RolePriority = 'primary' | 'backup' | 'overflow'\n\nexport interface CameraRoleAssignment {\n cameraId: string\n role: AgentCapability\n agentId: string\n priority: RolePriority\n rtspUrl?: string\n detectionConfig?: {\n modelId: string\n runtime: string\n confidence: number\n fps: number\n classes?: string[]\n }\n}\n\n// --- Hub -> Agent messages ---\nexport type HubToAgentMessage =\n | { type: 'assign'; assignment: CameraRoleAssignment }\n | { type: 'unassign'; cameraId: string; role: AgentCapability }\n | { type: 'recording.start'; cameraId: string; rtspUrl: string }\n | { type: 'recording.stop'; cameraId: string }\n | { type: 'benchmark.run'; config: RemoteBenchmarkConfig }\n | { type: 'config.update'; addonId: string; config: Record<string, unknown> }\n | { type: 'task.execute'; taskId: string; taskType: string; payload: unknown }\n | { type: 'task.cancel'; taskId: string }\n | { type: 'addon.install'; package: string; version?: string }\n | { type: 'addon.uninstall'; package: string }\n | { type: 'addon.update'; package: string; version?: string }\n | { type: 'addon.restart' }\n | { type: 'ping' }\n\n// --- Agent -> Hub messages ---\nexport type AgentToHubMessage =\n | { type: 'register'; info: AgentRegistrationInfo }\n | { type: 'heartbeat'; status: AgentRuntimeStatus }\n | { type: 'detection.result'; cameraId: string; detections: DetectionResult[]; timestamp: number; inferenceMs: number }\n | { type: 'recording.segment'; cameraId: string; segment: RecordingSegmentInfo }\n | { type: 'recording.status'; cameraId: string; recording: boolean }\n | { type: 'benchmark.progress'; event: BenchmarkStreamEvent }\n | { type: 'benchmark.result'; report: BenchmarkReport }\n | { type: 'task.result'; taskId: string; success: boolean; result?: unknown; error?: string }\n | { type: 'task.progress'; taskId: string; progress: TaskProgress }\n | { type: 'addon.install-result'; package: string; success: boolean; version?: string; error?: string }\n | { type: 'addon.uninstall-result'; package: string; success: boolean; error?: string }\n | { type: 'addon.update-result'; package: string; success: boolean; version?: string; error?: string }\n | { type: 'log'; level: string; scope: string; message: string }\n | { type: 'pong' }\n\n// --- Binary frame header (29 bytes) ---\nexport const BINARY_FRAME_HEADER_SIZE = 29\nexport const BINARY_FRAME_TYPE = 0x01\n\nexport interface AgentRegistrationInfo {\n id: string\n name: string\n capabilities: AgentCapability[]\n host: string\n port: number\n platform: string\n arch: string\n cpuCores: number\n memoryMB: number\n gpuModel?: string\n pythonRuntimes: string[]\n httpPort: number\n /** Task types this agent can handle (e.g., 'pipeline.decode', 'system.info') */\n taskTypes?: string[]\n /** Installed addons on this agent */\n installedAddons?: string[]\n}\n\nexport interface AgentRuntimeStatus {\n activeCameras: number\n cpuPercent: number\n memoryPercent: number\n fps: Record<string, number>\n errors: string[]\n}\n\nexport interface DetectionResult {\n className: string\n score: number\n bbox: [number, number, number, number]\n}\n\nexport interface RecordingSegmentInfo {\n id: string\n startTime: number\n endTime: number\n duration: number\n sizeBytes: number\n path: string\n format: 'mp4' | 'ts'\n}\n\nexport interface RemoteBenchmarkConfig {\n runtime: string\n modelId?: string\n durationMs: number\n warmupMs: number\n inputWidth: number\n inputHeight: number\n}\n\nexport interface BenchmarkStreamEvent {\n phase: 'warmup' | 'running'\n iteration: number\n inferenceMs: number\n}\n\nexport interface BenchmarkReport {\n runtime: string\n modelId?: string\n iterations: number\n meanMs: number\n p50Ms: number\n p95Ms: number\n p99Ms: number\n minMs: number\n maxMs: number\n}\n","/**\n * Detection Analysis Pipeline -- processes raw detections through\n * configurable stages to produce tracked, enriched, actionable events.\n */\n\nimport type { Detection } from './device-capabilities/object-detector.js'\nimport type { VideoFrame } from './camera-pipeline.js'\n\n// --- Detection type const unions ---\n\nexport const DETECTION_TYPES = ['person', 'vehicle', 'animal', 'package'] as const\nexport type DetectionType = typeof DETECTION_TYPES[number]\n\nexport const SUB_DETECTION_TYPES = ['face', 'plate'] as const\nexport type SubDetectionType = typeof SUB_DETECTION_TYPES[number]\n\nexport const RECOGNITION_TYPES = ['face', 'plate', 'clip', 'custom'] as const\nexport type RecognitionType = typeof RECOGNITION_TYPES[number]\n\n// --- Analysis Context ---\n\nexport interface AnalysisContext {\n readonly deviceId: string\n readonly frame: VideoFrame\n readonly timestamp: number\n readonly rawDetections: readonly Detection[]\n readonly trackedDetections: readonly ServerTrackedDetection[]\n readonly events: readonly AnalysisEvent[]\n readonly metadata: Readonly<Record<string, unknown>>\n}\n\n// --- Tracked Detection ---\n\nexport interface ServerTrackedDetection {\n readonly trackId: string\n readonly detection: Detection\n readonly crop?: Buffer\n readonly tracking: TrackingInfo\n readonly subDetections: readonly SubDetection[]\n readonly recognitions: readonly RecognitionResult[]\n readonly zones: readonly string[]\n readonly previousZones: readonly string[]\n}\n\nexport interface TrackingInfo {\n readonly age: number\n readonly state: 'moving' | 'stationary' | 'new' | 'lost'\n readonly stationaryDuration: number\n readonly velocity: { readonly dx: number; readonly dy: number }\n readonly positionHistory: ReadonlyArray<{ readonly x: number; readonly y: number; readonly t: number }>\n}\n\n// --- Sub-Detection ---\n\nexport interface SubDetection {\n readonly detectionType: SubDetectionType\n readonly boundingBox: readonly [number, number, number, number]\n readonly score: number\n readonly crop?: Buffer\n}\n\n// --- Recognition ---\n\nexport interface RecognitionResult {\n readonly recognitionType: RecognitionType\n readonly label: string\n readonly score: number\n readonly embedding?: readonly number[]\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n// --- Analysis Events ---\n\nexport interface AnalysisEvent {\n readonly category: string\n readonly severity: 'info' | 'warning' | 'alert'\n readonly detection: ServerTrackedDetection\n readonly description: string\n readonly data: Readonly<Record<string, unknown>>\n}\n\n// --- Analysis Stage ---\n\nexport interface IAnalysisStage {\n readonly id: string\n readonly name: string\n readonly priority: number\n enabled: boolean\n process(ctx: AnalysisContext): Promise<AnalysisContext>\n}\n\n// --- Sub-Detector Interface ---\n\nexport interface ISubDetector {\n readonly detectionType: SubDetectionType\n readonly targetClasses: readonly string[]\n detect(crop: Buffer, cropWidth: number, cropHeight: number): Promise<SubDetection[]>\n}\n\nexport interface IFaceDetector extends ISubDetector {\n readonly detectionType: 'face'\n}\n\nexport interface IPlateDetector extends ISubDetector {\n readonly detectionType: 'plate'\n}\n\n// --- Recognizer Interface ---\n\nexport interface IRecognizer {\n readonly recognitionType: RecognitionType\n recognize(crop: Buffer, width: number, height: number): Promise<RecognitionResult | null>\n}\n\nexport interface IFaceRecognizer extends IRecognizer {\n getEmbedding(crop: Buffer): Promise<Float32Array>\n registerKnown(label: string, embedding: Float32Array): void\n}\n\nexport interface IPlateRecognizer extends IRecognizer {\n readonly recognitionType: 'plate'\n}\n\n// --- Audio Classifier ---\n\nexport interface IAudioClassifier {\n readonly ready: boolean\n initialize(): Promise<void>\n classify(\n audioSamples: Float32Array,\n sampleRate: number,\n topN?: number,\n ): Promise<readonly AudioClassification[]>\n release(): Promise<void>\n}\n\nexport interface AudioClassification {\n readonly classIndex: number\n readonly className: string\n readonly score: number\n readonly isSurveillanceRelevant: boolean\n}\n\n// --- Pipeline Stage Interfaces ---\n\nexport interface IClassFilterStage extends IAnalysisStage {\n readonly id: 'class-filter'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n getConfig(deviceId: string): Record<string, unknown>\n}\n\nexport interface ITrackerStage extends IAnalysisStage {\n readonly id: 'tracker'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n getConfig(deviceId: string): Record<string, unknown>\n resetDevice(deviceId: string): void\n}\n\nexport interface ISubDetectionStage extends IAnalysisStage {\n readonly id: 'sub-detection'\n registerDetector(detector: ISubDetector): void\n}\n\nexport interface IRecognitionStage extends IAnalysisStage {\n readonly id: 'recognition'\n registerRecognizer(recognizer: IRecognizer): void\n}\n\nexport interface IZoneAnalysisStage extends IAnalysisStage {\n readonly id: 'zone-analysis'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\nexport interface IEventGenerationStage extends IAnalysisStage {\n readonly id: 'event-generation'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\nexport interface IObjectSnapshotStage extends IAnalysisStage {\n readonly id: 'object-snapshot'\n setConfig(deviceId: string, config: Record<string, unknown>): void\n}\n\n// --- Analysis Pipeline ---\n\nexport interface IAnalysisPipeline {\n addStage(stage: IAnalysisStage): void\n removeStage(stageId: string): void\n getStages(): readonly IAnalysisStage[]\n analyze(deviceId: string, frame: VideoFrame, rawDetections: Detection[]): Promise<AnalysisContext>\n}\n\n// --- Helper functions ---\n\nexport function createAnalysisContext(\n deviceId: string,\n frame: VideoFrame,\n rawDetections: Detection[],\n): AnalysisContext {\n return {\n deviceId,\n frame,\n timestamp: frame.timestamp,\n rawDetections,\n trackedDetections: [],\n events: [],\n metadata: {},\n }\n}\n\nexport function enrichContext(\n ctx: AnalysisContext,\n updates: Partial<Pick<AnalysisContext, 'trackedDetections' | 'events' | 'metadata'>>,\n): AnalysisContext {\n return {\n ...ctx,\n trackedDetections: updates.trackedDetections ?? ctx.trackedDetections,\n events: updates.events ?? ctx.events,\n metadata: updates.metadata ? { ...ctx.metadata, ...updates.metadata } : ctx.metadata,\n }\n}\n","/**\n * Analysis Persistence Types — interfaces for event persistence, track trails,\n * retention, session tracking, and known faces.\n *\n * These interfaces define the contracts used by the server; concrete\n * implementations live in addon-pipeline and are received via CapabilityRegistry.\n */\n\nimport type { ServerTrackedDetection } from './server-analysis.js'\n\n// ---------------------------------------------------------------------------\n// Event Persistence\n// ---------------------------------------------------------------------------\n\nexport interface ObjectSnapshotResult {\n readonly trackId: string\n readonly thumbnail?: Buffer\n readonly fullCrop?: Buffer\n}\n\nexport interface AnnotatedSnapshotResult {\n readonly thumbnail: Buffer\n readonly full: Buffer\n}\n\nexport interface PersistableEvent {\n readonly id: string\n readonly timestamp: number\n readonly deviceId: string\n readonly category: string\n readonly className: string\n readonly score: number\n readonly trackId: string\n readonly severity: string\n readonly description: string\n readonly data: Record<string, unknown>\n readonly mediaFiles: readonly string[]\n}\n\nexport interface EventBufferStatus {\n readonly eventCount: number\n readonly mediaCount: number\n readonly mediaSizeMB: number\n}\n\nexport type TrackMediaType =\n | 'crop-thumb'\n | 'crop-full'\n | 'debug-annotated-thumb'\n | 'debug-annotated-full'\n | 'original'\n | 'original-thumb'\n | 'inline-crop'\n | 'unknown'\n\nexport interface TrackMediaFile {\n readonly path: string\n readonly type: TrackMediaType\n readonly data: Buffer\n readonly source: 'buffer' | 'storage'\n}\n\n// ---------------------------------------------------------------------------\n// Track Trail\n// ---------------------------------------------------------------------------\n\nexport interface TrackCaptureConfig {\n readonly enabled: boolean\n readonly snapshotIntervalMs: number\n readonly maxTrailLength: number\n readonly saveThumbnails: boolean\n readonly thumbnailSize: { readonly width: number; readonly height: number }\n}\n\nexport interface TrackPosition {\n readonly x: number\n readonly y: number\n readonly timestamp: number\n readonly bbox: readonly [number, number, number, number]\n}\n\nexport interface TrackSnapshot {\n readonly timestamp: number\n readonly position: TrackPosition\n readonly thumbnailPath: string\n}\n\nexport interface TrackTrail {\n readonly trackId: string\n readonly deviceId: string\n readonly className: string\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly positions: readonly TrackPosition[]\n readonly snapshots: readonly TrackSnapshot[]\n readonly totalDistance: number\n readonly zonesVisited: readonly string[]\n readonly active: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Retention\n// ---------------------------------------------------------------------------\n\nexport interface RetentionConfig {\n readonly cleanupIntervalMs: number\n readonly detectionEventsDays: number\n readonly audioLevelsDays: number\n /** @deprecated — snapshots are tied to events, use detectionEventsDays */\n readonly snapshotsDays: number\n readonly deviceOverrides?: Readonly<Record<string, Partial<Pick<RetentionConfig, 'detectionEventsDays' | 'audioLevelsDays' | 'snapshotsDays'>>>>\n}\n\nexport const DEFAULT_RETENTION: RetentionConfig = {\n cleanupIntervalMs: 60 * 60 * 1000,\n detectionEventsDays: 30,\n audioLevelsDays: 7,\n snapshotsDays: 14,\n}\n\nexport interface RetentionReport {\n readonly deletedEvents: number\n readonly deletedAudioRecords: number\n readonly deletedSnapshots: number\n}\n\n// ---------------------------------------------------------------------------\n// Session Tracker\n// ---------------------------------------------------------------------------\n\nexport interface SessionTrack {\n readonly trackId: string\n readonly deviceId: string\n readonly className: string\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly totalFrames: number\n readonly lastDetection: ServerTrackedDetection\n readonly state: string\n readonly positions: ReadonlyArray<{ readonly x: number; readonly y: number; readonly t: number }>\n readonly embedding?: Float32Array\n readonly globalId?: string\n readonly bestCrop?: Buffer\n}\n\nexport interface GlobalIdentity {\n readonly globalId: string\n readonly embedding: Float32Array\n readonly label?: string\n readonly firstSeen: number\n readonly lastSeen: number\n readonly deviceIds: ReadonlyArray<string>\n}\n\n// ---------------------------------------------------------------------------\n// Known Faces\n// ---------------------------------------------------------------------------\n\nexport interface ClipRecognizer {\n getEmbedding(imageBuffer: Buffer): Promise<Float32Array>\n}\n\nexport interface KnownFaceEntry {\n readonly id: string\n readonly label: string\n readonly group?: string\n readonly embedding: readonly number[]\n readonly cropBase64: string\n readonly createdAt: number\n readonly updatedAt: number\n readonly source?: string\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n// ---------------------------------------------------------------------------\n// Recording Addon (generic interface for recording engine access)\n// ---------------------------------------------------------------------------\n\n/**\n * Interface for the recording addon — the server uses this instead of\n * importing PipelineAddon directly from addon-pipeline.\n */\nexport interface IRecordingAddon {\n getCoordinator(): IRecordingCoordinator\n getRecordingDb(): IRecordingDb\n}\n\n/**\n * Minimal coordinator interface for the server's recording router.\n */\nexport interface IRecordingCoordinator {\n enableRecording(deviceId: string, options: {\n policy: unknown\n ffmpegOverrides?: unknown\n }): Promise<void>\n disableRecording(deviceId: string): Promise<void>\n isRecording(deviceId: string): boolean\n readonly playlistGenerator: {\n generate(\n deviceId: string,\n streamId: string,\n startTime: number,\n endTime: number,\n options?: { live?: boolean },\n ): unknown\n }\n readonly storageEstimator: {\n estimateForDevice(\n deviceId: string,\n motionInput?: { avgEventsPerDay: number; avgDurationSec: number },\n ): { totalEstimatedGb: number; [key: string]: unknown }\n }\n}\n\n/**\n * Minimal recording database interface for the server's recording router.\n */\nexport interface IRecordingDb {\n upsertStorageConfig(config: {\n deviceId: string\n dataCategory: string\n storageName: string\n subDirectory: string\n retentionDays: number | null\n retentionGb: number | null\n }): void\n getPolicy(deviceId: string): unknown\n getEnabledPolicies(): Array<{ deviceId: string; [key: string]: unknown }>\n querySegments(deviceId: string, streamId: string, startTime: number, endTime: number): unknown\n getAvailability(deviceId: string, startTime: number, endTime: number): unknown\n getStorageUsage(deviceId: string, streamId: string): unknown\n upsertPolicy(policy: unknown): void\n findNearestThumbnail(deviceId: string, timestamp: number, category: string): unknown\n getMotionStats(deviceId: string, startTime: number, endTime: number): {\n avgEventsPerDay: number\n avgDurationSec: number\n dutyCyclePercent: number\n totalEvents: number\n }\n resolveStorageConfig(deviceId: string, dataCategory: string): unknown\n}\n\n// ---------------------------------------------------------------------------\n// Sub-service interfaces — used by the server's thin NestJS wrappers\n// to receive delegates via CapabilityRegistry.\n// ---------------------------------------------------------------------------\n\nexport interface IEventPersistence {\n start(): void\n stop(): void\n saveDetectionCrops(eventId: string, crops: readonly ObjectSnapshotResult[]): void\n saveAnnotatedFrame(eventId: string, result: AnnotatedSnapshotResult): void\n saveOriginalFrame(eventId: string, frame: import('./camera-pipeline.js').VideoFrame): Promise<void>\n getEventMedia(eventId: string): Promise<unknown>\n getTrackMedia(trackId: string): Promise<unknown>\n getDeviceMedia(deviceId: string, since?: number, until?: number): Promise<unknown>\n getBufferStatus(): unknown\n flush(): Promise<void>\n}\n\nexport interface ITrackTrail {\n setConfig(deviceId: string, config: Partial<TrackCaptureConfig>): void\n getConfig(deviceId: string): unknown\n recordFrame(ctx: unknown): Promise<void>\n getActiveTrail(trackId: string): unknown\n getActiveTrails(deviceId: string): unknown\n getPersistedTrail(trackId: string): Promise<unknown>\n getTrail(trackId: string): Promise<unknown>\n listTrails(deviceId: string, options?: {\n since?: number\n until?: number\n limit?: number\n className?: string\n }): Promise<unknown>\n}\n\nexport interface IRetention {\n start(): void\n stop(): void\n runCleanup(): Promise<unknown>\n setConfig(update: Partial<RetentionConfig>): void\n getConfig(): unknown\n forceCleanup(): Promise<unknown>\n}\n\nexport interface ISessionTracker {\n updateFromAnalysis(deviceId: string, ctx: unknown): void\n getActiveTracks(deviceId: string): unknown\n getAllActiveTracks(): unknown\n getTrack(deviceId: string, trackId: string): unknown\n getTrackCounts(): unknown\n clearDevice(deviceId: string): void\n clearAll(): void\n getGlobalPool(): unknown\n}\n\nexport interface IKnownFaces {\n register(entry: KnownFaceEntry): Promise<void>\n listAll(): Promise<unknown>\n delete(id: string): Promise<void>\n update(id: string, updates: Partial<Pick<KnownFaceEntry, 'label' | 'group'>>): Promise<void>\n recalculateEmbedding(id: string, clipRecognizer: ClipRecognizer): Promise<void>\n findMatch(embedding: Float32Array, threshold: number): Promise<unknown>\n batchRegister(\n entries: ReadonlyArray<{ readonly label: string; readonly cropBase64: string; readonly group?: string }>,\n clipRecognizer: ClipRecognizer,\n ): Promise<unknown>\n}\n\n/**\n * Composite interface exposed via CapabilityRegistry as the\n * 'analysis-data-persistence' singleton. Each sub-service is wired\n * individually to the corresponding NestJS wrapper service.\n */\nexport interface IAnalysisDataPersistence {\n readonly eventPersistence: IEventPersistence\n readonly knownFaces: IKnownFaces\n readonly sessionTracker: ISessionTracker\n readonly retention: IRetention\n readonly trackTrail: ITrackTrail\n}\n\n// ---------------------------------------------------------------------------\n// Provider Connection Testing\n// ---------------------------------------------------------------------------\n\nexport interface TestConnectionResult {\n readonly success: boolean\n readonly version?: string\n readonly cameraCount?: number\n readonly error?: string\n}\n\n/**\n * Generic interface for testing provider connections.\n * Each provider addon can expose a connection tester.\n */\nexport interface IProviderConnectionTester {\n testConnection(): Promise<TestConnectionResult>\n}\n","/**\n * System settings UI schemas — the single source of truth for all settings sections.\n *\n * These are defined in @camstack/types so that:\n * - The backend can serve them via API\n * - Addons can reference/extend them\n * - The frontend fetches them at runtime (no hardcoded duplication)\n *\n * Values are stored in the SQL system_settings table, not config.yaml.\n * Only `server` is read-only (loaded from config.yaml at bootstrap).\n */\n\nimport type { ConfigUISchema } from '../interfaces/config-ui.js'\n\n// ---------------------------------------------------------------------------\n// Section type\n// ---------------------------------------------------------------------------\n\nexport type SystemSettingsSection =\n | 'server' | 'auth' | 'features' | 'storage' | 'logging' | 'addons'\n | 'recording' | 'streaming' | 'ffmpeg' | 'detection' | 'backup' | 'retention'\n\n/** Sections where fields are read-only (bootstrap from config.yaml). */\nexport const READ_ONLY_SECTIONS: ReadonlySet<SystemSettingsSection> = new Set<SystemSettingsSection>([\n 'server',\n])\n\n// ---------------------------------------------------------------------------\n// Tab definitions (rendering order)\n// ---------------------------------------------------------------------------\n\nexport interface SettingsTabDef {\n readonly id: SystemSettingsSection\n readonly label: string\n}\n\nexport const SETTINGS_TABS: readonly SettingsTabDef[] = [\n { id: 'server', label: 'Server' },\n { id: 'logging', label: 'Logs' },\n { id: 'recording', label: 'Recording' },\n { id: 'ffmpeg', label: 'FFmpeg' },\n { id: 'detection', label: 'Detection' },\n { id: 'auth', label: 'Auth' },\n { id: 'retention', label: 'Retention' },\n] as const\n\n// ---------------------------------------------------------------------------\n// Schemas\n// ---------------------------------------------------------------------------\n\nconst SERVER_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'server-info',\n title: 'Server',\n description: 'Core server connection settings (read-only)',\n columns: 2,\n fields: [\n {\n type: 'info',\n key: 'server-restart-note',\n label: 'Restart required',\n content: 'Server settings are read-only. Change them in config.yaml and restart.',\n variant: 'warning',\n },\n {\n type: 'text',\n key: 'port',\n label: 'Port',\n disabled: true,\n description: 'Listening port',\n },\n {\n type: 'text',\n key: 'host',\n label: 'Host',\n disabled: true,\n description: 'Bind address',\n },\n {\n type: 'text',\n key: 'dataPath',\n label: 'Data Path',\n disabled: true,\n description: 'Root data directory',\n span: 2,\n },\n ],\n },\n ],\n}\n\n// Storage paths are managed via CAMSTACK_DATA env var — no UI settings needed.\nconst STORAGE_SCHEMA: ConfigUISchema = {\n sections: [],\n}\n\nconst LOGGING_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'logging-settings',\n title: 'Logging',\n description: 'Global log verbosity. Retention is managed per log-destination addon.',\n columns: 1,\n fields: [\n {\n type: 'select',\n key: 'level',\n label: 'Log Level',\n options: [\n { value: 'debug', label: 'Debug' },\n { value: 'info', label: 'Info' },\n { value: 'warn', label: 'Warn' },\n { value: 'error', label: 'Error' },\n ],\n },\n ],\n },\n ],\n}\n\nconst RECORDING_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'recording-settings',\n title: 'Recording',\n description: 'Video recording segment and retention defaults',\n columns: 2,\n fields: [\n {\n type: 'number',\n key: 'segmentDurationSeconds',\n label: 'Segment Duration',\n description: 'Length of each recording segment',\n min: 1,\n max: 60,\n step: 1,\n unit: 'seconds',\n },\n {\n type: 'number',\n key: 'defaultRetentionDays',\n label: 'Default Retention',\n description: 'Days to keep recordings before auto-delete',\n min: 1,\n max: 365,\n step: 1,\n unit: 'days',\n },\n ],\n },\n ],\n}\n\n// Streaming ports are addon-specific (go2rtc owns its ports).\n// No system-level streaming schema needed.\n\nconst FFMPEG_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'ffmpeg-settings',\n title: 'FFmpeg',\n description: 'FFmpeg binary and hardware acceleration settings',\n columns: 2,\n fields: [\n {\n type: 'text',\n key: 'binaryPath',\n label: 'Binary Path',\n description: 'Path to ffmpeg executable',\n placeholder: 'ffmpeg',\n span: 2,\n },\n {\n type: 'select',\n key: 'hwAccel',\n label: 'Hardware Acceleration',\n description: 'GPU decoding/encoding backend',\n options: [\n { value: 'auto', label: 'Auto-detect' },\n { value: 'none', label: 'None (CPU only)' },\n { value: 'videotoolbox', label: 'VideoToolbox (macOS)' },\n { value: 'vaapi', label: 'VA-API (Linux Intel/AMD)' },\n { value: 'qsv', label: 'QSV (Intel Quick Sync)' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n {\n type: 'number',\n key: 'threadCount',\n label: 'Thread Count',\n description: '0 = auto (let FFmpeg decide)',\n min: 0,\n max: 16,\n step: 1,\n },\n ],\n },\n ],\n}\n\nconst DETECTION_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'detection-fps',\n title: 'Frame Rates',\n description: 'Default analysis frame rates for new cameras',\n columns: 2,\n fields: [\n {\n type: 'number',\n key: 'defaultMotionFps',\n label: 'Motion FPS',\n description: 'Frames per second for motion detection',\n min: 1,\n max: 30,\n step: 1,\n unit: 'fps',\n },\n {\n type: 'number',\n key: 'defaultDetectionFps',\n label: 'Detection FPS',\n description: 'Frames per second for object detection',\n min: 1,\n max: 30,\n step: 1,\n unit: 'fps',\n },\n ],\n },\n {\n id: 'detection-thresholds',\n title: 'Thresholds',\n description: 'Default confidence and cooldown for detections',\n columns: 2,\n fields: [\n {\n type: 'slider',\n key: 'defaultConfidenceThreshold',\n label: 'Confidence Threshold',\n description: 'Minimum confidence to trigger a detection event',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n showValue: true,\n },\n {\n type: 'number',\n key: 'defaultCooldownSeconds',\n label: 'Cooldown',\n description: 'Seconds between duplicate events',\n min: 0,\n max: 300,\n step: 1,\n unit: 'seconds',\n },\n ],\n },\n {\n id: 'detection-tracker',\n title: 'Tracker',\n description: 'SORT/IoU tracker parameters',\n columns: 3,\n fields: [\n {\n type: 'number',\n key: 'trackerMaxAgeFrames',\n label: 'Max Age',\n description: 'Frames before a lost track is removed',\n min: 1,\n max: 120,\n step: 1,\n unit: 'frames',\n },\n {\n type: 'number',\n key: 'trackerMinHits',\n label: 'Min Hits',\n description: 'Consecutive detections to confirm a track',\n min: 1,\n max: 20,\n step: 1,\n },\n {\n type: 'slider',\n key: 'trackerIouThreshold',\n label: 'IoU Threshold',\n description: 'Minimum IoU to associate detection with track',\n min: 0.1,\n max: 0.9,\n step: 0.05,\n showValue: true,\n },\n ],\n },\n ],\n}\n\n// Backup retention is addon-specific (local-backup owns its retention count).\n// No system-level backup schema needed.\n\nconst AUTH_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'auth-settings',\n title: 'Authentication',\n description: 'Token and session settings',\n columns: 1,\n fields: [\n {\n type: 'text',\n key: 'tokenExpiry',\n label: 'Token Expiry',\n description: 'JWT token lifetime (e.g. 24h, 7d, 1h)',\n placeholder: '24h',\n },\n ],\n },\n ],\n}\n\nconst RETENTION_SCHEMA: ConfigUISchema = {\n sections: [\n {\n id: 'retention-settings',\n title: 'Retention',\n description: 'Data retention periods for analytics data',\n columns: 1,\n fields: [\n {\n type: 'slider',\n key: 'detectionEventsDays',\n label: 'Detection Events Retention',\n min: 1,\n max: 365,\n unit: 'days',\n showValue: true,\n span: 1,\n },\n {\n type: 'slider',\n key: 'audioLevelsDays',\n label: 'Audio Levels Retention',\n min: 1,\n max: 90,\n unit: 'days',\n showValue: true,\n span: 1,\n },\n ],\n },\n ],\n}\n\n// ---------------------------------------------------------------------------\n// Registry: section → schema\n// ---------------------------------------------------------------------------\n\nexport const SYSTEM_SETTINGS_SCHEMAS: Readonly<Record<SystemSettingsSection, ConfigUISchema>> = {\n server: SERVER_SCHEMA,\n storage: STORAGE_SCHEMA,\n logging: LOGGING_SCHEMA,\n recording: RECORDING_SCHEMA,\n ffmpeg: FFMPEG_SCHEMA,\n detection: DETECTION_SCHEMA,\n auth: AUTH_SCHEMA,\n retention: RETENTION_SCHEMA,\n // These sections have no UI form — managed programmatically or addon-specific\n streaming: { sections: [] },\n backup: { sections: [] },\n features: { sections: [] },\n addons: { sections: [] },\n}\n\n/**\n * Get the UI schema for a settings section.\n * Returns undefined for unknown sections.\n */\nexport function getSystemSettingsSchema(section: string): ConfigUISchema | undefined {\n return (SYSTEM_SETTINGS_SCHEMAS as Record<string, ConfigUISchema>)[section]\n}\n","export const HF_REPO = 'camstack/camstack-models'\nexport const HF_BASE_URL = `https://huggingface.co/${HF_REPO}/resolve/main`\n","export function hfModelUrl(repo: string, path: string): string {\n return `https://huggingface.co/${repo}/resolve/main/${path}`\n}\n","/** Cosine similarity between two embedding vectors */\nexport function cosineSimilarity(a: Float32Array, b: Float32Array): number {\n if (a.length !== b.length) return 0\n let dotProduct = 0\n let normA = 0\n let normB = 0\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i]! * b[i]!\n normA += a[i]! * a[i]!\n normB += b[i]! * b[i]!\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB)\n return denom === 0 ? 0 : dotProduct / denom\n}\n","import type { LabelDefinition, ClassMapDefinition } from '../types/labels.js'\n\nexport const COCO_80_LABELS: readonly LabelDefinition[] = [\n { id: 'person', name: 'Person' },\n { id: 'bicycle', name: 'Bicycle' },\n { id: 'car', name: 'Car' },\n { id: 'motorcycle', name: 'Motorcycle' },\n { id: 'airplane', name: 'Airplane' },\n { id: 'bus', name: 'Bus' },\n { id: 'train', name: 'Train' },\n { id: 'truck', name: 'Truck' },\n { id: 'boat', name: 'Boat' },\n { id: 'traffic light', name: 'Traffic Light' },\n { id: 'fire hydrant', name: 'Fire Hydrant' },\n { id: 'stop sign', name: 'Stop Sign' },\n { id: 'parking meter', name: 'Parking Meter' },\n { id: 'bench', name: 'Bench' },\n { id: 'bird', name: 'Bird' },\n { id: 'cat', name: 'Cat' },\n { id: 'dog', name: 'Dog' },\n { id: 'horse', name: 'Horse' },\n { id: 'sheep', name: 'Sheep' },\n { id: 'cow', name: 'Cow' },\n { id: 'elephant', name: 'Elephant' },\n { id: 'bear', name: 'Bear' },\n { id: 'zebra', name: 'Zebra' },\n { id: 'giraffe', name: 'Giraffe' },\n { id: 'backpack', name: 'Backpack' },\n { id: 'umbrella', name: 'Umbrella' },\n { id: 'handbag', name: 'Handbag' },\n { id: 'tie', name: 'Tie' },\n { id: 'suitcase', name: 'Suitcase' },\n { id: 'frisbee', name: 'Frisbee' },\n { id: 'skis', name: 'Skis' },\n { id: 'snowboard', name: 'Snowboard' },\n { id: 'sports ball', name: 'Sports Ball' },\n { id: 'kite', name: 'Kite' },\n { id: 'baseball bat', name: 'Baseball Bat' },\n { id: 'baseball glove', name: 'Baseball Glove' },\n { id: 'skateboard', name: 'Skateboard' },\n { id: 'surfboard', name: 'Surfboard' },\n { id: 'tennis racket', name: 'Tennis Racket' },\n { id: 'bottle', name: 'Bottle' },\n { id: 'wine glass', name: 'Wine Glass' },\n { id: 'cup', name: 'Cup' },\n { id: 'fork', name: 'Fork' },\n { id: 'knife', name: 'Knife' },\n { id: 'spoon', name: 'Spoon' },\n { id: 'bowl', name: 'Bowl' },\n { id: 'banana', name: 'Banana' },\n { id: 'apple', name: 'Apple' },\n { id: 'sandwich', name: 'Sandwich' },\n { id: 'orange', name: 'Orange' },\n { id: 'broccoli', name: 'Broccoli' },\n { id: 'carrot', name: 'Carrot' },\n { id: 'hot dog', name: 'Hot Dog' },\n { id: 'pizza', name: 'Pizza' },\n { id: 'donut', name: 'Donut' },\n { id: 'cake', name: 'Cake' },\n { id: 'chair', name: 'Chair' },\n { id: 'couch', name: 'Couch' },\n { id: 'potted plant', name: 'Potted Plant' },\n { id: 'bed', name: 'Bed' },\n { id: 'dining table', name: 'Dining Table' },\n { id: 'toilet', name: 'Toilet' },\n { id: 'tv', name: 'TV' },\n { id: 'laptop', name: 'Laptop' },\n { id: 'mouse', name: 'Mouse' },\n { id: 'remote', name: 'Remote' },\n { id: 'keyboard', name: 'Keyboard' },\n { id: 'cell phone', name: 'Cell Phone' },\n { id: 'microwave', name: 'Microwave' },\n { id: 'oven', name: 'Oven' },\n { id: 'toaster', name: 'Toaster' },\n { id: 'sink', name: 'Sink' },\n { id: 'refrigerator', name: 'Refrigerator' },\n { id: 'book', name: 'Book' },\n { id: 'clock', name: 'Clock' },\n { id: 'vase', name: 'Vase' },\n { id: 'scissors', name: 'Scissors' },\n { id: 'teddy bear', name: 'Teddy Bear' },\n { id: 'hair drier', name: 'Hair Drier' },\n { id: 'toothbrush', name: 'Toothbrush' },\n] as const\n\nexport const MACRO_LABELS: readonly LabelDefinition[] = [\n { id: 'person', name: 'Person' },\n { id: 'vehicle', name: 'Vehicle' },\n { id: 'animal', name: 'Animal' },\n] as const\n\nexport const COCO_TO_MACRO: ClassMapDefinition = {\n mapping: {\n person: 'person',\n bicycle: 'vehicle',\n car: 'vehicle',\n motorcycle: 'vehicle',\n airplane: 'vehicle',\n bus: 'vehicle',\n train: 'vehicle',\n truck: 'vehicle',\n boat: 'vehicle',\n bird: 'animal',\n cat: 'animal',\n dog: 'animal',\n horse: 'animal',\n sheep: 'animal',\n cow: 'animal',\n elephant: 'animal',\n bear: 'animal',\n zebra: 'animal',\n giraffe: 'animal',\n },\n preserveOriginal: true,\n}\n","export enum DeviceType {\n Camera = 'camera',\n}\n\nexport interface DeviceTypeInfo {\n readonly type: DeviceType\n readonly label: string\n readonly icon: string // lucide icon name\n}\n\nexport const DEVICE_TYPE_INFO: Record<DeviceType, DeviceTypeInfo> = {\n [DeviceType.Camera]: { type: DeviceType.Camera, label: 'Camera', icon: 'camera' },\n}\n","export * from './types/io.js'\nexport * from './types/labels.js'\nexport * from './types/detection.js'\nexport * from './types/tracked.js'\nexport * from './types/events.js'\nexport * from './types/config.js'\nexport * from './types/entities.js'\nexport * from './types/zones.js'\nexport * from './types/models.js'\nexport * from './types/pipeline.js'\nexport * from './types/live-state.js'\nexport * from './types/analytics.js'\nexport type * from './types/benchmark.js'\nexport type {\n PipelineAddonSchema,\n PipelineModelOption,\n PipelineSlotSchema,\n PipelineSchema,\n PipelineDefaultStep,\n PipelineTemplateStep,\n PipelineTemplate,\n TemplateValidationResult,\n} from './types/pipeline-schema.js'\n\n// --- Core interfaces (used by addons and server) ---\nexport type * from './interfaces/addon.js'\nexport type * from './interfaces/capability.js'\nexport type * from './interfaces/config-ui.js'\nexport type * from './interfaces/pipeline-slot.js'\nexport type * from './interfaces/detector.js'\nexport type * from './interfaces/cropper.js'\nexport type * from './interfaces/classifier.js'\nexport type * from './interfaces/refiner.js'\nexport type * from './interfaces/detection-addon.js'\nexport type * from './interfaces/inference-engine.js'\nexport type * from './interfaces/inference-capabilities.js'\nexport type * from './interfaces/repositories.js'\nexport type * from './interfaces/analysis.js'\nexport type * from './interfaces/scene-intelligence.js'\nexport type * from './interfaces/advanced-notifier.js'\nexport type * from './interfaces/python-env.js'\nexport type * from './interfaces/network.js'\nexport type * from './interfaces/router.js'\nexport * from './interfaces/storage-backend.js'\nexport type * from './interfaces/logging.js'\nexport type * from './interfaces/event-bus.js'\nexport type * from './interfaces/pipeline-runner.js'\nexport type * from './interfaces/auth-provider.js'\nexport type * from './interfaces/notification.js'\nexport type * from './interfaces/addon-routes.js'\nexport type * from './interfaces/addon-i18n.js'\nexport { resolveTranslation } from './interfaces/addon-i18n.js'\nexport type * from './interfaces/scoped-token.js'\nexport type * from './interfaces/task-handler.js'\nexport type * from './interfaces/worker-protocol.js'\n\n// --- Server interfaces (consolidated from server/backend/src/interfaces/) ---\nexport type * from './interfaces/storage.js'\nexport type * from './interfaces/context.js'\nexport type * from './interfaces/device-capability.js'\nexport type * from './interfaces/device.js'\nexport type * from './interfaces/device-provider.js'\nexport type * from './interfaces/device-capabilities/index.js'\nexport type * from './interfaces/streaming.js'\nexport type * from './interfaces/auth.js'\nexport type * from './interfaces/lifecycle.js'\nexport type * from './interfaces/server-network.js'\nexport type * from './interfaces/process.js'\nexport * from './interfaces/feature-flags.js'\nexport type * from './interfaces/agent.js'\nexport type * from './interfaces/agent-protocol.js'\nexport * from './interfaces/agent-protocol.js'\nexport type * from './interfaces/camera-pipeline.js'\nexport type * from './interfaces/server-analysis.js'\nexport * from './interfaces/server-analysis.js'\nexport type * from './interfaces/stream-broker.js'\nexport * from './interfaces/analysis-persistence.js'\nexport type * from './interfaces/restreamer.js'\nexport type * from './interfaces/decoder.js'\nexport type * from './interfaces/ffmpeg.js'\nexport type {\n ModelType as ServerModelType,\n ServerModelCatalogEntry,\n IModelCatalogProvider,\n} from './interfaces/model-catalog.js'\nexport type * from './interfaces/network-quality.js'\nexport type * from './interfaces/webrtc-provider.js'\nexport type * from './interfaces/repl.js'\nexport type * from './interfaces/platform.js'\nexport type * from './interfaces/api-shared.js'\n\n// Schemas (runtime objects — system settings UI definitions)\nexport * from './schemas/system-settings-schemas.js'\n\n// Constants\nexport * from './constants.js'\n\n// Utils\nexport { hfModelUrl } from './utils/hf-url.js'\nexport { cosineSimilarity } from './utils/cosine-similarity.js'\n\n// Catalogs (coco-classmap stays in types — used by object-detection addon and other consumers)\nexport {\n COCO_80_LABELS,\n COCO_TO_MACRO,\n MACRO_LABELS,\n} from './catalogs/coco-classmap.js'\n\nexport type {\n CameraMotionConfig,\n CameraNativeDetectionConfig,\n CameraDetectionCapabilities,\n} from './types/camera-detection.js'\n\nexport { DeviceType, type DeviceTypeInfo, DEVICE_TYPE_INFO } from './types/device-type.js'\n\nexport type { AppRouter } from './generated/addon-api.js'\n"],"mappings":"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","names":["exports","exports","exports","exports","exports","exports","exports","exports","exports","exports","exports","exports","exports","exports","resolveTranslation","exports","exports","exports","exports","exports","exports","exports","hfModelUrl","exports","cosineSimilarity","exports","DeviceType","exports"]}