@camstack/server 0.1.6 → 0.1.8

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 (60) hide show
  1. package/package.json +3 -3
  2. package/src/__tests__/addon-upload.spec.ts +58 -0
  3. package/src/__tests__/bulk-update-coordinator.spec.ts +286 -0
  4. package/src/__tests__/cap-ownership-authority.spec.ts +400 -0
  5. package/src/__tests__/cap-providers/cap-providers-location-import.spec.ts +186 -0
  6. package/src/__tests__/cap-providers/integrations-delete-cascade.spec.ts +243 -0
  7. package/src/__tests__/cap-providers-bulk-update.spec.ts +388 -0
  8. package/src/__tests__/cap-route-adapter.spec.ts +289 -0
  9. package/src/__tests__/cap-routers/broker-routing.router.spec.ts +169 -0
  10. package/src/__tests__/cap-routers/cap-route-error-formatter.spec.ts +123 -0
  11. package/src/__tests__/cap-routers/capabilities-node.spec.ts +55 -0
  12. package/src/__tests__/cap-routers/device-link-overlay.spec.ts +132 -0
  13. package/src/__tests__/dev-bootstrap-shm-ring.spec.ts +30 -0
  14. package/src/__tests__/device-settings-contribution-dispatch.spec.ts +249 -0
  15. package/src/__tests__/framework-installer-defer-restart.spec.ts +165 -0
  16. package/src/__tests__/moleculer/uds-readiness.spec.ts +143 -0
  17. package/src/__tests__/moleculer/uds-topology.spec.ts +390 -0
  18. package/src/__tests__/moleculer/uds-unowned-call.spec.ts +329 -0
  19. package/src/__tests__/moleculer-register-node-idempotency.spec.ts +39 -4
  20. package/src/__tests__/native-cap-route.spec.ts +404 -0
  21. package/src/__tests__/oauth2-account-linking.spec.ts +85 -0
  22. package/src/__tests__/uds-addon-call-wiring.spec.ts +237 -0
  23. package/src/__tests__/uds-log-ingest.spec.ts +183 -0
  24. package/src/api/addon-upload.ts +27 -1
  25. package/src/api/capabilities.router.ts +1 -1
  26. package/src/api/core/__tests__/integration-markers.spec.ts +10 -0
  27. package/src/api/core/bulk-update-coordinator.ts +302 -0
  28. package/src/api/core/cap-providers.ts +211 -9
  29. package/src/api/core/capabilities.router.ts +26 -3
  30. package/src/api/core/logs.router.ts +4 -0
  31. package/src/api/oauth2/oauth2-routes.ts +5 -1
  32. package/src/api/trpc/__tests__/client-ip.spec.ts +146 -0
  33. package/src/api/trpc/__tests__/webrtc-session-ua-enrich.spec.ts +128 -0
  34. package/src/api/trpc/cap-mount-helpers.ts +12 -1
  35. package/src/api/trpc/cap-route-error-formatter.ts +163 -0
  36. package/src/api/trpc/client-ip.ts +147 -0
  37. package/src/api/trpc/generated-cap-mounts.ts +299 -8
  38. package/src/api/trpc/generated-cap-routers.ts +2384 -302
  39. package/src/api/trpc/trpc.middleware.ts +5 -1
  40. package/src/api/trpc/trpc.router.ts +84 -3
  41. package/src/boot/__tests__/integration-id-backfill.spec.ts +116 -0
  42. package/src/boot/integration-id-backfill.ts +109 -0
  43. package/src/core/addon/__tests__/addon-row-manifest.spec.ts +62 -0
  44. package/src/core/addon/addon-call-gateway.ts +157 -0
  45. package/src/core/addon/addon-package.service.ts +9 -0
  46. package/src/core/addon/addon-registry.service.ts +453 -107
  47. package/src/core/addon/addon-row-manifest.ts +29 -0
  48. package/src/core/addon/addon-settings-provider.ts +40 -116
  49. package/src/core/capability/capability.service.ts +9 -0
  50. package/src/core/logging/logging.service.ts +7 -2
  51. package/src/core/moleculer/cap-call-fn.spec.ts +166 -0
  52. package/src/core/moleculer/cap-call-fn.ts +103 -0
  53. package/src/core/moleculer/cap-route-authority.ts +182 -0
  54. package/src/core/moleculer/moleculer.service.ts +408 -36
  55. package/src/core/network/network-quality.service.spec.ts +2 -1
  56. package/src/main.ts +137 -12
  57. package/src/core/storage/settings-store.spec.ts +0 -213
  58. package/src/core/storage/settings-store.ts +0 -2
  59. package/src/core/storage/sql-schema.spec.ts +0 -140
  60. package/src/core/storage/sql-schema.ts +0 -3
@@ -1,9 +1,11 @@
1
1
  // AUTO-GENERATED by scripts/generate-cap-routers.ts — DO NOT EDIT
2
2
  // Re-run: npx tsx scripts/generate-cap-routers.ts
3
3
  //
4
- // Capabilities: 84
4
+ // Capabilities: 129
5
+ /* eslint-disable */
5
6
 
6
7
  import { TRPCError } from '@trpc/server'
8
+ import { CapRouteError } from '@camstack/kernel'
7
9
  import { z } from 'zod'
8
10
  import { adminProcedure, protectedProcedure, iterableSubscription, trpcRouter } from './trpc.middleware.js'
9
11
  import type { InferProvider } from '@camstack/types'
@@ -21,19 +23,36 @@ import { addonWidgetsSourceCapability } from '@camstack/types'
21
23
  import { addonsCapability } from '@camstack/types'
22
24
  import { adminUiCapability } from '@camstack/types'
23
25
  import { advancedNotifierCapability } from '@camstack/types'
26
+ import { airQualitySensorCapability } from '@camstack/types'
27
+ import { alarmPanelCapability } from '@camstack/types'
24
28
  import { alertsCapability } from '@camstack/types'
29
+ import { ambientLightSensorCapability } from '@camstack/types'
25
30
  import { audioAnalysisCapability } from '@camstack/types'
26
31
  import { audioAnalyzerCapability } from '@camstack/types'
27
32
  import { audioCodecCapability } from '@camstack/types'
28
33
  import { audioMetricsCapability } from '@camstack/types'
29
34
  import { authProviderCapability } from '@camstack/types'
35
+ import { automationControlCapability } from '@camstack/types'
30
36
  import { backupCapability } from '@camstack/types'
31
37
  import { batteryCapability } from '@camstack/types'
38
+ import { binaryCapability } from '@camstack/types'
32
39
  import { brightnessCapability } from '@camstack/types'
40
+ import { brokerCapability } from '@camstack/types'
41
+ import { buttonCapability } from '@camstack/types'
33
42
  import { cameraCredentialsCapability } from '@camstack/types'
43
+ import { cameraPipelineConfigCapability } from '@camstack/types'
34
44
  import { cameraStreamsCapability } from '@camstack/types'
45
+ import { carbonMonoxideCapability } from '@camstack/types'
46
+ import { climateControlCapability } from '@camstack/types'
47
+ import { colorCapability } from '@camstack/types'
48
+ import { connectivityCapability } from '@camstack/types'
49
+ import { consumablesCapability } from '@camstack/types'
50
+ import { contactCapability } from '@camstack/types'
51
+ import { controlCapability } from '@camstack/types'
52
+ import { coverCapability } from '@camstack/types'
35
53
  import { decoderCapability } from '@camstack/types'
36
54
  import { detectionPipelineCapability } from '@camstack/types'
55
+ import { deviceAdoptionCapability } from '@camstack/types'
37
56
  import { deviceDiscoveryCapability } from '@camstack/types'
38
57
  import { deviceExportCapability } from '@camstack/types'
39
58
  import { deviceManagerCapability } from '@camstack/types'
@@ -43,12 +62,23 @@ import { deviceStateCapability } from '@camstack/types'
43
62
  import { deviceStatusCapability } from '@camstack/types'
44
63
  import { doorbellCapability } from '@camstack/types'
45
64
  import { embeddingEncoderCapability } from '@camstack/types'
65
+ import { enumSensorCapability } from '@camstack/types'
66
+ import { eventEmitterCapability } from '@camstack/types'
46
67
  import { eventsCapability } from '@camstack/types'
68
+ import { fanControlCapability } from '@camstack/types'
47
69
  import { featureProbeCapability } from '@camstack/types'
70
+ import { floodCapability } from '@camstack/types'
71
+ import { gasCapability } from '@camstack/types'
72
+ import { humidifierCapability } from '@camstack/types'
73
+ import { humiditySensorCapability } from '@camstack/types'
74
+ import { imageCapability } from '@camstack/types'
48
75
  import { integrationsCapability } from '@camstack/types'
49
76
  import { intercomCapability } from '@camstack/types'
77
+ import { lawnMowerControlCapability } from '@camstack/types'
50
78
  import { localNetworkCapability } from '@camstack/types'
79
+ import { lockControlCapability } from '@camstack/types'
51
80
  import { logDestinationCapability } from '@camstack/types'
81
+ import { mediaPlayerCapability } from '@camstack/types'
52
82
  import { meshNetworkCapability } from '@camstack/types'
53
83
  import { metricsProviderCapability } from '@camstack/types'
54
84
  import { motionCapability } from '@camstack/types'
@@ -61,6 +91,8 @@ import { networkAccessCapability } from '@camstack/types'
61
91
  import { networkQualityCapability } from '@camstack/types'
62
92
  import { nodesCapability } from '@camstack/types'
63
93
  import { notificationOutputCapability } from '@camstack/types'
94
+ import { notifierCapability } from '@camstack/types'
95
+ import { numericSensorCapability } from '@camstack/types'
64
96
  import { oauthIntegrationCapability } from '@camstack/types'
65
97
  import { osdCapability } from '@camstack/types'
66
98
  import { pipelineAnalyticsCapability } from '@camstack/types'
@@ -68,28 +100,43 @@ import { pipelineExecutorCapability } from '@camstack/types'
68
100
  import { pipelineOrchestratorCapability } from '@camstack/types'
69
101
  import { pipelineRunnerCapability } from '@camstack/types'
70
102
  import { platformProbeCapability } from '@camstack/types'
103
+ import { powerMeterCapability } from '@camstack/types'
104
+ import { presenceCapability } from '@camstack/types'
105
+ import { pressureSensorCapability } from '@camstack/types'
106
+ import { privacyMaskCapability } from '@camstack/types'
71
107
  import { ptzCapability } from '@camstack/types'
72
108
  import { ptzAutotrackCapability } from '@camstack/types'
73
109
  import { rebootCapability } from '@camstack/types'
74
110
  import { recordingCapability } from '@camstack/types'
75
- import { recordingEngineCapability } from '@camstack/types'
76
111
  import { restreamerCapability } from '@camstack/types'
112
+ import { scriptRunnerCapability } from '@camstack/types'
77
113
  import { settingsStoreCapability } from '@camstack/types'
114
+ import { smokeCapability } from '@camstack/types'
78
115
  import { smtpProviderCapability } from '@camstack/types'
79
116
  import { snapshotCapability } from '@camstack/types'
80
117
  import { snapshotProviderCapability } from '@camstack/types'
81
118
  import { ssoBridgeCapability } from '@camstack/types'
82
119
  import { storageCapability } from '@camstack/types'
120
+ import { storageEvictableCapability } from '@camstack/types'
83
121
  import { storageProviderCapability } from '@camstack/types'
84
122
  import { streamBrokerCapability } from '@camstack/types'
123
+ import { streamCatalogCapability } from '@camstack/types'
85
124
  import { streamParamsCapability } from '@camstack/types'
86
125
  import { streamingEngineCapability } from '@camstack/types'
87
126
  import { switchCapability } from '@camstack/types'
88
127
  import { systemCapability } from '@camstack/types'
128
+ import { tamperCapability } from '@camstack/types'
129
+ import { temperatureSensorCapability } from '@camstack/types'
89
130
  import { toastCapability } from '@camstack/types'
90
131
  import { turnProviderCapability } from '@camstack/types'
132
+ import { updateCapability } from '@camstack/types'
91
133
  import { userManagementCapability } from '@camstack/types'
92
134
  import { userPasskeysCapability } from '@camstack/types'
135
+ import { vacuumControlCapability } from '@camstack/types'
136
+ import { valveCapability } from '@camstack/types'
137
+ import { vibrationCapability } from '@camstack/types'
138
+ import { waterHeaterCapability } from '@camstack/types'
139
+ import { weatherCapability } from '@camstack/types'
93
140
  import { webrtcCapability } from '@camstack/types'
94
141
  import { webrtcSessionCapability } from '@camstack/types'
95
142
  import { zoneAnalyticsCapability } from '@camstack/types'
@@ -104,6 +151,10 @@ export function requireCapProvider<T>(name: string, getProvider: () => T | null)
104
151
  throw new TRPCError({
105
152
  code: 'PRECONDITION_FAILED',
106
153
  message: `Capability "${name}" provider not available`,
154
+ cause: new CapRouteError(name, undefined, {
155
+ reason: 'no-provider',
156
+ rejected: [{ kind: 'hub-in-process', why: 'no provider bound for this cap' }],
157
+ }),
107
158
  })
108
159
  }
109
160
  return p
@@ -134,6 +185,10 @@ function resolveProvider<T>(
134
185
  throw new TRPCError({
135
186
  code: 'PRECONDITION_FAILED',
136
187
  message: `Capability "${capName}" provider not available`,
188
+ cause: new CapRouteError(capName, undefined, {
189
+ reason: 'no-provider',
190
+ rejected: [{ kind: 'hub-in-process', why: 'no provider bound for this cap/device' }],
191
+ }),
137
192
  })
138
193
  }
139
194
 
@@ -148,6 +203,11 @@ function resolveProvider<T>(
148
203
  throw new TRPCError({
149
204
  code: 'PRECONDITION_FAILED',
150
205
  message: `Capability "${capName}" not available on node "${nodeId}"`,
206
+ cause: new CapRouteError(capName, undefined, {
207
+ reason: 'no-provider',
208
+ nodeId,
209
+ rejected: [{ kind: 'remote-moleculer', why: `cap not available on node "${nodeId}"` }],
210
+ }),
151
211
  })
152
212
  }
153
213
  return proxy
@@ -173,6 +233,15 @@ export function createCapRouter_accessories(
173
233
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
174
234
  return p.getStatus(methodInput as any)
175
235
  }),
236
+ setChildHidden: adminProcedure
237
+ .input(accessoriesCapability.methods.setChildHidden.input.loose())
238
+ .output(accessoriesCapability.methods.setChildHidden.output)
239
+ .mutation(async ({ input, ctx }) => {
240
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
241
+ const p = resolveProvider('accessories', nodeId, () => getProvider(ctx), createRemoteProxy)
242
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
243
+ return p.setChildHidden(methodInput as any)
244
+ }),
176
245
  })
177
246
  }
178
247
 
@@ -493,6 +562,38 @@ export function createCapRouter_addons(
493
562
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
494
563
  return p.updateFrameworkPackage(input as any)
495
564
  }),
565
+ startBulkUpdate: adminProcedure
566
+ .input(addonsCapability.methods.startBulkUpdate.input.loose())
567
+ .output(addonsCapability.methods.startBulkUpdate.output)
568
+ .mutation(async ({ input, ctx }) => {
569
+ const p = requireCapProvider('addons', () => getProvider(ctx))
570
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
571
+ return p.startBulkUpdate(input as any)
572
+ }),
573
+ getBulkUpdateState: adminProcedure
574
+ .input(addonsCapability.methods.getBulkUpdateState.input.loose())
575
+ .output(addonsCapability.methods.getBulkUpdateState.output)
576
+ .query(async ({ input, ctx }) => {
577
+ const p = requireCapProvider('addons', () => getProvider(ctx))
578
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
579
+ return p.getBulkUpdateState(input as any)
580
+ }),
581
+ cancelBulkUpdate: adminProcedure
582
+ .input(addonsCapability.methods.cancelBulkUpdate.input.loose())
583
+ .output(addonsCapability.methods.cancelBulkUpdate.output)
584
+ .mutation(async ({ input, ctx }) => {
585
+ const p = requireCapProvider('addons', () => getProvider(ctx))
586
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
587
+ return p.cancelBulkUpdate(input as any)
588
+ }),
589
+ listActiveBulkUpdates: adminProcedure
590
+ .input(addonsCapability.methods.listActiveBulkUpdates.input.loose())
591
+ .output(addonsCapability.methods.listActiveBulkUpdates.output)
592
+ .query(async ({ input, ctx }) => {
593
+ const p = requireCapProvider('addons', () => getProvider(ctx))
594
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
595
+ return p.listActiveBulkUpdates(input as any)
596
+ }),
496
597
  getVersions: protectedProcedure
497
598
  .input(addonsCapability.methods.getVersions.input.loose())
498
599
  .output(addonsCapability.methods.getVersions.output)
@@ -657,6 +758,75 @@ export function createCapRouter_advancedNotifier(
657
758
  })
658
759
  }
659
760
 
761
+ // ── air-quality-sensor (singleton) ──────────────────────────────────
762
+
763
+ type AirQualitySensorProvider = InferProvider<typeof airQualitySensorCapability>
764
+
765
+ export function createCapRouter_airQualitySensor(
766
+ getProvider: (ctx: TrpcContext) => AirQualitySensorProvider | null,
767
+ createRemoteProxy?: (capName: string, nodeId: string) => AirQualitySensorProvider | null,
768
+ ) {
769
+ return trpcRouter({
770
+ getStatus: protectedProcedure
771
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
772
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
773
+ .query(async ({ input, ctx }) => {
774
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
775
+ const p = resolveProvider('air-quality-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
776
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
777
+ return p.getStatus(methodInput as any)
778
+ }),
779
+ })
780
+ }
781
+
782
+ // ── alarm-panel (singleton) ─────────────────────────────────────────
783
+
784
+ type AlarmPanelProvider = InferProvider<typeof alarmPanelCapability>
785
+
786
+ export function createCapRouter_alarmPanel(
787
+ getProvider: (ctx: TrpcContext) => AlarmPanelProvider | null,
788
+ createRemoteProxy?: (capName: string, nodeId: string) => AlarmPanelProvider | null,
789
+ ) {
790
+ return trpcRouter({
791
+ getStatus: protectedProcedure
792
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
793
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
794
+ .query(async ({ input, ctx }) => {
795
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
796
+ const p = resolveProvider('alarm-panel', nodeId, () => getProvider(ctx), createRemoteProxy)
797
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
798
+ return p.getStatus(methodInput as any)
799
+ }),
800
+ arm: adminProcedure
801
+ .input(alarmPanelCapability.methods.arm.input.loose())
802
+ .output(alarmPanelCapability.methods.arm.output)
803
+ .mutation(async ({ input, ctx }) => {
804
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
805
+ const p = resolveProvider('alarm-panel', nodeId, () => getProvider(ctx), createRemoteProxy)
806
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
807
+ return p.arm(methodInput as any)
808
+ }),
809
+ disarm: adminProcedure
810
+ .input(alarmPanelCapability.methods.disarm.input.loose())
811
+ .output(alarmPanelCapability.methods.disarm.output)
812
+ .mutation(async ({ input, ctx }) => {
813
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
814
+ const p = resolveProvider('alarm-panel', nodeId, () => getProvider(ctx), createRemoteProxy)
815
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
816
+ return p.disarm(methodInput as any)
817
+ }),
818
+ trigger: adminProcedure
819
+ .input(alarmPanelCapability.methods.trigger.input.loose())
820
+ .output(alarmPanelCapability.methods.trigger.output)
821
+ .mutation(async ({ input, ctx }) => {
822
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
823
+ const p = resolveProvider('alarm-panel', nodeId, () => getProvider(ctx), createRemoteProxy)
824
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
825
+ return p.trigger(methodInput as any)
826
+ }),
827
+ })
828
+ }
829
+
660
830
  // ── alerts (singleton) ──────────────────────────────────────────────
661
831
 
662
832
  type AlertsProvider = InferProvider<typeof alertsCapability>
@@ -726,6 +896,27 @@ export function createCapRouter_alerts(
726
896
  })
727
897
  }
728
898
 
899
+ // ── ambient-light-sensor (singleton) ────────────────────────────────
900
+
901
+ type AmbientLightSensorProvider = InferProvider<typeof ambientLightSensorCapability>
902
+
903
+ export function createCapRouter_ambientLightSensor(
904
+ getProvider: (ctx: TrpcContext) => AmbientLightSensorProvider | null,
905
+ createRemoteProxy?: (capName: string, nodeId: string) => AmbientLightSensorProvider | null,
906
+ ) {
907
+ return trpcRouter({
908
+ getStatus: protectedProcedure
909
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
910
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
911
+ .query(async ({ input, ctx }) => {
912
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
913
+ const p = resolveProvider('ambient-light-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
914
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
915
+ return p.getStatus(methodInput as any)
916
+ }),
917
+ })
918
+ }
919
+
729
920
  // ── audio-analysis (singleton) ──────────────────────────────────────
730
921
 
731
922
  type AudioAnalysisProvider = InferProvider<typeof audioAnalysisCapability>
@@ -1008,6 +1199,54 @@ export function createCapRouter_authProvider(
1008
1199
  })
1009
1200
  }
1010
1201
 
1202
+ // ── automation-control (singleton) ──────────────────────────────────
1203
+
1204
+ type AutomationControlProvider = InferProvider<typeof automationControlCapability>
1205
+
1206
+ export function createCapRouter_automationControl(
1207
+ getProvider: (ctx: TrpcContext) => AutomationControlProvider | null,
1208
+ createRemoteProxy?: (capName: string, nodeId: string) => AutomationControlProvider | null,
1209
+ ) {
1210
+ return trpcRouter({
1211
+ getStatus: protectedProcedure
1212
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1213
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1214
+ .query(async ({ input, ctx }) => {
1215
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1216
+ const p = resolveProvider('automation-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1218
+ return p.getStatus(methodInput as any)
1219
+ }),
1220
+ enable: adminProcedure
1221
+ .input(automationControlCapability.methods.enable.input.loose())
1222
+ .output(automationControlCapability.methods.enable.output)
1223
+ .mutation(async ({ input, ctx }) => {
1224
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1225
+ const p = resolveProvider('automation-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1226
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1227
+ return p.enable(methodInput as any)
1228
+ }),
1229
+ disable: adminProcedure
1230
+ .input(automationControlCapability.methods.disable.input.loose())
1231
+ .output(automationControlCapability.methods.disable.output)
1232
+ .mutation(async ({ input, ctx }) => {
1233
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1234
+ const p = resolveProvider('automation-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1235
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1236
+ return p.disable(methodInput as any)
1237
+ }),
1238
+ trigger: adminProcedure
1239
+ .input(automationControlCapability.methods.trigger.input.loose())
1240
+ .output(automationControlCapability.methods.trigger.output)
1241
+ .mutation(async ({ input, ctx }) => {
1242
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1243
+ const p = resolveProvider('automation-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1244
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1245
+ return p.trigger(methodInput as any)
1246
+ }),
1247
+ })
1248
+ }
1249
+
1011
1250
  // ── backup (singleton) ──────────────────────────────────────────────
1012
1251
 
1013
1252
  type BackupProvider = InferProvider<typeof backupCapability>
@@ -1120,6 +1359,36 @@ export function createCapRouter_battery(
1120
1359
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1121
1360
  return p.getStatus(methodInput as any)
1122
1361
  }),
1362
+ wakeForStream: protectedProcedure
1363
+ .input(batteryCapability.methods.wakeForStream.input.loose())
1364
+ .output(batteryCapability.methods.wakeForStream.output)
1365
+ .mutation(async ({ input, ctx }) => {
1366
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1367
+ const p = resolveProvider('battery', nodeId, () => getProvider(ctx), createRemoteProxy)
1368
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1369
+ return p.wakeForStream(methodInput as any)
1370
+ }),
1371
+ })
1372
+ }
1373
+
1374
+ // ── binary (singleton) ──────────────────────────────────────────────
1375
+
1376
+ type BinaryProvider = InferProvider<typeof binaryCapability>
1377
+
1378
+ export function createCapRouter_binary(
1379
+ getProvider: (ctx: TrpcContext) => BinaryProvider | null,
1380
+ createRemoteProxy?: (capName: string, nodeId: string) => BinaryProvider | null,
1381
+ ) {
1382
+ return trpcRouter({
1383
+ getStatus: protectedProcedure
1384
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1385
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1386
+ .query(async ({ input, ctx }) => {
1387
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1388
+ const p = resolveProvider('binary', nodeId, () => getProvider(ctx), createRemoteProxy)
1389
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1390
+ return p.getStatus(methodInput as any)
1391
+ }),
1123
1392
  })
1124
1393
  }
1125
1394
 
@@ -1153,6 +1422,179 @@ export function createCapRouter_brightness(
1153
1422
  })
1154
1423
  }
1155
1424
 
1425
+ // ── broker (collection) ──────────────────────────────────────────────
1426
+
1427
+ type BrokerProvider = InferProvider<typeof brokerCapability>
1428
+
1429
+ export function createCapRouter_broker(
1430
+ getProvider: (ctx: TrpcContext, addonId?: string) => BrokerProvider | null,
1431
+ createRemoteProxy?: (capName: string, nodeId: string) => BrokerProvider | null,
1432
+ ) {
1433
+ return trpcRouter({
1434
+ getStatus: protectedProcedure
1435
+ .input(z.object({ nodeId: z.string().optional(), addonId: z.string().optional() }).optional())
1436
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1437
+ .query(async ({ input, ctx }) => {
1438
+ const p = resolveProvider('broker', input?.nodeId, () => getProvider(ctx, input?.addonId), createRemoteProxy)
1439
+ return p.getStatus()
1440
+ }),
1441
+ list: protectedProcedure
1442
+ .input(brokerCapability.methods.list.input.loose())
1443
+ .output(brokerCapability.methods.list.output)
1444
+ .query(async ({ input, ctx }) => {
1445
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1446
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1447
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1448
+ return p.list(methodInput as any)
1449
+ }),
1450
+ get: protectedProcedure
1451
+ .input(brokerCapability.methods.get.input.loose())
1452
+ .output(brokerCapability.methods.get.output)
1453
+ .query(async ({ input, ctx }) => {
1454
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1455
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1456
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1457
+ return p.get(methodInput as any)
1458
+ }),
1459
+ listProviders: adminProcedure
1460
+ .input(z.object({ nodeId: z.string().optional(), addonId: z.string().optional() }).optional())
1461
+ .output(brokerCapability.methods.listProviders.output)
1462
+ .query(async ({ input, ctx }) => {
1463
+ const p = resolveProvider('broker', input?.nodeId, () => getProvider(ctx, input?.addonId), createRemoteProxy)
1464
+ return p.listProviders()
1465
+ }),
1466
+ add: adminProcedure
1467
+ .input(brokerCapability.methods.add.input.loose())
1468
+ .output(brokerCapability.methods.add.output)
1469
+ .mutation(async ({ input, ctx }) => {
1470
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1471
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1472
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1473
+ return p.add(methodInput as any)
1474
+ }),
1475
+ remove: adminProcedure
1476
+ .input(brokerCapability.methods.remove.input.loose())
1477
+ .output(brokerCapability.methods.remove.output)
1478
+ .mutation(async ({ input, ctx }) => {
1479
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1480
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1481
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1482
+ return p.remove(methodInput as any)
1483
+ }),
1484
+ testConnection: adminProcedure
1485
+ .input(brokerCapability.methods.testConnection.input.loose())
1486
+ .output(brokerCapability.methods.testConnection.output)
1487
+ .mutation(async ({ input, ctx }) => {
1488
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1489
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1490
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1491
+ return p.testConnection(methodInput as any)
1492
+ }),
1493
+ getSettings: adminProcedure
1494
+ .input(brokerCapability.methods.getSettings.input.loose())
1495
+ .output(brokerCapability.methods.getSettings.output)
1496
+ .query(async ({ input, ctx }) => {
1497
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1498
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1499
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1500
+ return p.getSettings(methodInput as any)
1501
+ }),
1502
+ setSettings: adminProcedure
1503
+ .input(brokerCapability.methods.setSettings.input.loose())
1504
+ .output(brokerCapability.methods.setSettings.output)
1505
+ .mutation(async ({ input, ctx }) => {
1506
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1507
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1508
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1509
+ return p.setSettings(methodInput as any)
1510
+ }),
1511
+ getBrokerConfig: adminProcedure
1512
+ .input(brokerCapability.methods.getBrokerConfig.input.loose())
1513
+ .output(brokerCapability.methods.getBrokerConfig.output)
1514
+ .query(async ({ input, ctx }) => {
1515
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1516
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1517
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1518
+ return p.getBrokerConfig(methodInput as any)
1519
+ }),
1520
+ getSettingsSchema: adminProcedure
1521
+ .input(brokerCapability.methods.getSettingsSchema.input.loose())
1522
+ .output(brokerCapability.methods.getSettingsSchema.output)
1523
+ .query(async ({ input, ctx }) => {
1524
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1525
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1526
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1527
+ return p.getSettingsSchema(methodInput as any)
1528
+ }),
1529
+ testSettings: adminProcedure
1530
+ .input(brokerCapability.methods.testSettings.input.loose())
1531
+ .output(brokerCapability.methods.testSettings.output)
1532
+ .mutation(async ({ input, ctx }) => {
1533
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1534
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1535
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1536
+ return p.testSettings(methodInput as any)
1537
+ }),
1538
+ publish: adminProcedure
1539
+ .input(brokerCapability.methods.publish.input.loose())
1540
+ .output(brokerCapability.methods.publish.output)
1541
+ .mutation(async ({ input, ctx }) => {
1542
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1543
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1545
+ return p.publish(methodInput as any)
1546
+ }),
1547
+ subscribe: adminProcedure
1548
+ .input(brokerCapability.methods.subscribe.input.loose())
1549
+ .output(brokerCapability.methods.subscribe.output)
1550
+ .mutation(async ({ input, ctx }) => {
1551
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1552
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1553
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1554
+ return p.subscribe(methodInput as any)
1555
+ }),
1556
+ unsubscribe: adminProcedure
1557
+ .input(brokerCapability.methods.unsubscribe.input.loose())
1558
+ .output(brokerCapability.methods.unsubscribe.output)
1559
+ .mutation(async ({ input, ctx }) => {
1560
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1561
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1562
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1563
+ return p.unsubscribe(methodInput as any)
1564
+ }),
1565
+ getState: protectedProcedure
1566
+ .input(brokerCapability.methods.getState.input.loose())
1567
+ .output(brokerCapability.methods.getState.output)
1568
+ .query(async ({ input, ctx }) => {
1569
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
1570
+ const p = resolveProvider('broker', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
1571
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1572
+ return p.getState(methodInput as any)
1573
+ }),
1574
+ })
1575
+ }
1576
+
1577
+ // ── button (singleton) ──────────────────────────────────────────────
1578
+
1579
+ type ButtonProvider = InferProvider<typeof buttonCapability>
1580
+
1581
+ export function createCapRouter_button(
1582
+ getProvider: (ctx: TrpcContext) => ButtonProvider | null,
1583
+ createRemoteProxy?: (capName: string, nodeId: string) => ButtonProvider | null,
1584
+ ) {
1585
+ return trpcRouter({
1586
+ press: adminProcedure
1587
+ .input(buttonCapability.methods.press.input.loose())
1588
+ .output(buttonCapability.methods.press.output)
1589
+ .mutation(async ({ input, ctx }) => {
1590
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1591
+ const p = resolveProvider('button', nodeId, () => getProvider(ctx), createRemoteProxy)
1592
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1593
+ return p.press(methodInput as any)
1594
+ }),
1595
+ })
1596
+ }
1597
+
1156
1598
  // ── camera-credentials (singleton) ──────────────────────────────────
1157
1599
 
1158
1600
  type CameraCredentialsProvider = InferProvider<typeof cameraCredentialsCapability>
@@ -1183,34 +1625,73 @@ export function createCapRouter_cameraCredentials(
1183
1625
  })
1184
1626
  }
1185
1627
 
1186
- // ── camera-streams (singleton) ──────────────────────────────────────
1628
+ // ── camera-pipeline-config (singleton) ──────────────────────────────
1187
1629
 
1188
- type CameraStreamsProvider = InferProvider<typeof cameraStreamsCapability>
1630
+ type CameraPipelineConfigProvider = InferProvider<typeof cameraPipelineConfigCapability>
1189
1631
 
1190
- export function createCapRouter_cameraStreams(
1191
- getProvider: (ctx: TrpcContext) => CameraStreamsProvider | null,
1192
- createRemoteProxy?: (capName: string, nodeId: string) => CameraStreamsProvider | null,
1632
+ export function createCapRouter_cameraPipelineConfig(
1633
+ getProvider: (ctx: TrpcContext) => CameraPipelineConfigProvider | null,
1634
+ createRemoteProxy?: (capName: string, nodeId: string) => CameraPipelineConfigProvider | null,
1193
1635
  ) {
1194
1636
  return trpcRouter({
1195
- getCameraStreams: protectedProcedure
1196
- .input(cameraStreamsCapability.methods.getCameraStreams.input.loose())
1197
- .output(cameraStreamsCapability.methods.getCameraStreams.output)
1637
+ getDeviceSettingsContribution: protectedProcedure
1638
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceSettingsContribution.input.loose())
1639
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceSettingsContribution.output)
1198
1640
  .query(async ({ input, ctx }) => {
1199
1641
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1200
- const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1642
+ const p = resolveProvider('camera-pipeline-config', nodeId, () => getProvider(ctx), createRemoteProxy)
1201
1643
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1202
- return p.getCameraStreams(methodInput as any)
1644
+ return p.getDeviceSettingsContribution(methodInput as any)
1203
1645
  }),
1204
- getBrokerStreams: protectedProcedure
1205
- .input(cameraStreamsCapability.methods.getBrokerStreams.input.loose())
1206
- .output(cameraStreamsCapability.methods.getBrokerStreams.output)
1646
+ getDeviceLiveContribution: protectedProcedure
1647
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceLiveContribution.input.loose())
1648
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceLiveContribution.output)
1207
1649
  .query(async ({ input, ctx }) => {
1208
1650
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1209
- const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1651
+ const p = resolveProvider('camera-pipeline-config', nodeId, () => getProvider(ctx), createRemoteProxy)
1210
1652
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1211
- return p.getBrokerStreams(methodInput as any)
1653
+ return p.getDeviceLiveContribution(methodInput as any)
1212
1654
  }),
1213
- getRtspEntries: protectedProcedure
1655
+ applyDeviceSettingsPatch: adminProcedure
1656
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.applyDeviceSettingsPatch.input.loose())
1657
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.applyDeviceSettingsPatch.output)
1658
+ .mutation(async ({ input, ctx }) => {
1659
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1660
+ const p = resolveProvider('camera-pipeline-config', nodeId, () => getProvider(ctx), createRemoteProxy)
1661
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1662
+ return p.applyDeviceSettingsPatch(methodInput as any)
1663
+ }),
1664
+ })
1665
+ }
1666
+
1667
+ // ── camera-streams (singleton) ──────────────────────────────────────
1668
+
1669
+ type CameraStreamsProvider = InferProvider<typeof cameraStreamsCapability>
1670
+
1671
+ export function createCapRouter_cameraStreams(
1672
+ getProvider: (ctx: TrpcContext) => CameraStreamsProvider | null,
1673
+ createRemoteProxy?: (capName: string, nodeId: string) => CameraStreamsProvider | null,
1674
+ ) {
1675
+ return trpcRouter({
1676
+ getCameraStreams: protectedProcedure
1677
+ .input(cameraStreamsCapability.methods.getCameraStreams.input.loose())
1678
+ .output(cameraStreamsCapability.methods.getCameraStreams.output)
1679
+ .query(async ({ input, ctx }) => {
1680
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1681
+ const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1682
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1683
+ return p.getCameraStreams(methodInput as any)
1684
+ }),
1685
+ getBrokerStreams: protectedProcedure
1686
+ .input(cameraStreamsCapability.methods.getBrokerStreams.input.loose())
1687
+ .output(cameraStreamsCapability.methods.getBrokerStreams.output)
1688
+ .query(async ({ input, ctx }) => {
1689
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1690
+ const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1691
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1692
+ return p.getBrokerStreams(methodInput as any)
1693
+ }),
1694
+ getRtspEntries: protectedProcedure
1214
1695
  .input(cameraStreamsCapability.methods.getRtspEntries.input.loose())
1215
1696
  .output(cameraStreamsCapability.methods.getRtspEntries.output)
1216
1697
  .query(async ({ input, ctx }) => {
@@ -1219,6 +1700,318 @@ export function createCapRouter_cameraStreams(
1219
1700
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1220
1701
  return p.getRtspEntries(methodInput as any)
1221
1702
  }),
1703
+ getProfileRtspEntries: protectedProcedure
1704
+ .input(cameraStreamsCapability.methods.getProfileRtspEntries.input.loose())
1705
+ .output(cameraStreamsCapability.methods.getProfileRtspEntries.output)
1706
+ .query(async ({ input, ctx }) => {
1707
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1708
+ const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1709
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1710
+ return p.getProfileRtspEntries(methodInput as any)
1711
+ }),
1712
+ pickStream: protectedProcedure
1713
+ .input(cameraStreamsCapability.methods.pickStream.input.loose())
1714
+ .output(cameraStreamsCapability.methods.pickStream.output)
1715
+ .query(async ({ input, ctx }) => {
1716
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1717
+ const p = resolveProvider('camera-streams', nodeId, () => getProvider(ctx), createRemoteProxy)
1718
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1719
+ return p.pickStream(methodInput as any)
1720
+ }),
1721
+ })
1722
+ }
1723
+
1724
+ // ── carbon-monoxide (singleton) ─────────────────────────────────────
1725
+
1726
+ type CarbonMonoxideProvider = InferProvider<typeof carbonMonoxideCapability>
1727
+
1728
+ export function createCapRouter_carbonMonoxide(
1729
+ getProvider: (ctx: TrpcContext) => CarbonMonoxideProvider | null,
1730
+ createRemoteProxy?: (capName: string, nodeId: string) => CarbonMonoxideProvider | null,
1731
+ ) {
1732
+ return trpcRouter({
1733
+ getStatus: protectedProcedure
1734
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1735
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1736
+ .query(async ({ input, ctx }) => {
1737
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1738
+ const p = resolveProvider('carbon-monoxide', nodeId, () => getProvider(ctx), createRemoteProxy)
1739
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1740
+ return p.getStatus(methodInput as any)
1741
+ }),
1742
+ })
1743
+ }
1744
+
1745
+ // ── climate-control (singleton) ─────────────────────────────────────
1746
+
1747
+ type ClimateControlProvider = InferProvider<typeof climateControlCapability>
1748
+
1749
+ export function createCapRouter_climateControl(
1750
+ getProvider: (ctx: TrpcContext) => ClimateControlProvider | null,
1751
+ createRemoteProxy?: (capName: string, nodeId: string) => ClimateControlProvider | null,
1752
+ ) {
1753
+ return trpcRouter({
1754
+ getStatus: protectedProcedure
1755
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1756
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1757
+ .query(async ({ input, ctx }) => {
1758
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1759
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1760
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1761
+ return p.getStatus(methodInput as any)
1762
+ }),
1763
+ setMode: adminProcedure
1764
+ .input(climateControlCapability.methods.setMode.input.loose())
1765
+ .output(climateControlCapability.methods.setMode.output)
1766
+ .mutation(async ({ input, ctx }) => {
1767
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1768
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1769
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1770
+ return p.setMode(methodInput as any)
1771
+ }),
1772
+ setFanMode: adminProcedure
1773
+ .input(climateControlCapability.methods.setFanMode.input.loose())
1774
+ .output(climateControlCapability.methods.setFanMode.output)
1775
+ .mutation(async ({ input, ctx }) => {
1776
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1777
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1778
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1779
+ return p.setFanMode(methodInput as any)
1780
+ }),
1781
+ setPreset: adminProcedure
1782
+ .input(climateControlCapability.methods.setPreset.input.loose())
1783
+ .output(climateControlCapability.methods.setPreset.output)
1784
+ .mutation(async ({ input, ctx }) => {
1785
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1786
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1787
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1788
+ return p.setPreset(methodInput as any)
1789
+ }),
1790
+ setTarget: adminProcedure
1791
+ .input(climateControlCapability.methods.setTarget.input.loose())
1792
+ .output(climateControlCapability.methods.setTarget.output)
1793
+ .mutation(async ({ input, ctx }) => {
1794
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1795
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1796
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1797
+ return p.setTarget(methodInput as any)
1798
+ }),
1799
+ setTargetRange: adminProcedure
1800
+ .input(climateControlCapability.methods.setTargetRange.input.loose())
1801
+ .output(climateControlCapability.methods.setTargetRange.output)
1802
+ .mutation(async ({ input, ctx }) => {
1803
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1804
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1805
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1806
+ return p.setTargetRange(methodInput as any)
1807
+ }),
1808
+ setTargetHumidity: adminProcedure
1809
+ .input(climateControlCapability.methods.setTargetHumidity.input.loose())
1810
+ .output(climateControlCapability.methods.setTargetHumidity.output)
1811
+ .mutation(async ({ input, ctx }) => {
1812
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1813
+ const p = resolveProvider('climate-control', nodeId, () => getProvider(ctx), createRemoteProxy)
1814
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1815
+ return p.setTargetHumidity(methodInput as any)
1816
+ }),
1817
+ })
1818
+ }
1819
+
1820
+ // ── color (singleton) ───────────────────────────────────────────────
1821
+
1822
+ type ColorProvider = InferProvider<typeof colorCapability>
1823
+
1824
+ export function createCapRouter_color(
1825
+ getProvider: (ctx: TrpcContext) => ColorProvider | null,
1826
+ createRemoteProxy?: (capName: string, nodeId: string) => ColorProvider | null,
1827
+ ) {
1828
+ return trpcRouter({
1829
+ getStatus: protectedProcedure
1830
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1831
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1832
+ .query(async ({ input, ctx }) => {
1833
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1834
+ const p = resolveProvider('color', nodeId, () => getProvider(ctx), createRemoteProxy)
1835
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1836
+ return p.getStatus(methodInput as any)
1837
+ }),
1838
+ setColor: adminProcedure
1839
+ .input(colorCapability.methods.setColor.input.loose())
1840
+ .output(colorCapability.methods.setColor.output)
1841
+ .mutation(async ({ input, ctx }) => {
1842
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1843
+ const p = resolveProvider('color', nodeId, () => getProvider(ctx), createRemoteProxy)
1844
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1845
+ return p.setColor(methodInput as any)
1846
+ }),
1847
+ })
1848
+ }
1849
+
1850
+ // ── connectivity (singleton) ────────────────────────────────────────
1851
+
1852
+ type ConnectivityProvider = InferProvider<typeof connectivityCapability>
1853
+
1854
+ export function createCapRouter_connectivity(
1855
+ getProvider: (ctx: TrpcContext) => ConnectivityProvider | null,
1856
+ createRemoteProxy?: (capName: string, nodeId: string) => ConnectivityProvider | null,
1857
+ ) {
1858
+ return trpcRouter({
1859
+ getStatus: protectedProcedure
1860
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1861
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1862
+ .query(async ({ input, ctx }) => {
1863
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1864
+ const p = resolveProvider('connectivity', nodeId, () => getProvider(ctx), createRemoteProxy)
1865
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1866
+ return p.getStatus(methodInput as any)
1867
+ }),
1868
+ })
1869
+ }
1870
+
1871
+ // ── consumables (singleton) ─────────────────────────────────────────
1872
+
1873
+ type ConsumablesProvider = InferProvider<typeof consumablesCapability>
1874
+
1875
+ export function createCapRouter_consumables(
1876
+ getProvider: (ctx: TrpcContext) => ConsumablesProvider | null,
1877
+ createRemoteProxy?: (capName: string, nodeId: string) => ConsumablesProvider | null,
1878
+ ) {
1879
+ return trpcRouter({
1880
+ getStatus: protectedProcedure
1881
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1882
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1883
+ .query(async ({ input, ctx }) => {
1884
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1885
+ const p = resolveProvider('consumables', nodeId, () => getProvider(ctx), createRemoteProxy)
1886
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1887
+ return p.getStatus(methodInput as any)
1888
+ }),
1889
+ reset: adminProcedure
1890
+ .input(consumablesCapability.methods.reset.input.loose())
1891
+ .output(consumablesCapability.methods.reset.output)
1892
+ .mutation(async ({ input, ctx }) => {
1893
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1894
+ const p = resolveProvider('consumables', nodeId, () => getProvider(ctx), createRemoteProxy)
1895
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1896
+ return p.reset(methodInput as any)
1897
+ }),
1898
+ })
1899
+ }
1900
+
1901
+ // ── contact (singleton) ─────────────────────────────────────────────
1902
+
1903
+ type ContactProvider = InferProvider<typeof contactCapability>
1904
+
1905
+ export function createCapRouter_contact(
1906
+ getProvider: (ctx: TrpcContext) => ContactProvider | null,
1907
+ createRemoteProxy?: (capName: string, nodeId: string) => ContactProvider | null,
1908
+ ) {
1909
+ return trpcRouter({
1910
+ getStatus: protectedProcedure
1911
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1912
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1913
+ .query(async ({ input, ctx }) => {
1914
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1915
+ const p = resolveProvider('contact', nodeId, () => getProvider(ctx), createRemoteProxy)
1916
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1917
+ return p.getStatus(methodInput as any)
1918
+ }),
1919
+ })
1920
+ }
1921
+
1922
+ // ── control (singleton) ─────────────────────────────────────────────
1923
+
1924
+ type ControlProvider = InferProvider<typeof controlCapability>
1925
+
1926
+ export function createCapRouter_control(
1927
+ getProvider: (ctx: TrpcContext) => ControlProvider | null,
1928
+ createRemoteProxy?: (capName: string, nodeId: string) => ControlProvider | null,
1929
+ ) {
1930
+ return trpcRouter({
1931
+ getStatus: protectedProcedure
1932
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1933
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1934
+ .query(async ({ input, ctx }) => {
1935
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1936
+ const p = resolveProvider('control', nodeId, () => getProvider(ctx), createRemoteProxy)
1937
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1938
+ return p.getStatus(methodInput as any)
1939
+ }),
1940
+ setValue: adminProcedure
1941
+ .input(controlCapability.methods.setValue.input.loose())
1942
+ .output(controlCapability.methods.setValue.output)
1943
+ .mutation(async ({ input, ctx }) => {
1944
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1945
+ const p = resolveProvider('control', nodeId, () => getProvider(ctx), createRemoteProxy)
1946
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1947
+ return p.setValue(methodInput as any)
1948
+ }),
1949
+ })
1950
+ }
1951
+
1952
+ // ── cover (singleton) ───────────────────────────────────────────────
1953
+
1954
+ type CoverProvider = InferProvider<typeof coverCapability>
1955
+
1956
+ export function createCapRouter_cover(
1957
+ getProvider: (ctx: TrpcContext) => CoverProvider | null,
1958
+ createRemoteProxy?: (capName: string, nodeId: string) => CoverProvider | null,
1959
+ ) {
1960
+ return trpcRouter({
1961
+ getStatus: protectedProcedure
1962
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
1963
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
1964
+ .query(async ({ input, ctx }) => {
1965
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1966
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
1967
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1968
+ return p.getStatus(methodInput as any)
1969
+ }),
1970
+ open: adminProcedure
1971
+ .input(coverCapability.methods.open.input.loose())
1972
+ .output(coverCapability.methods.open.output)
1973
+ .mutation(async ({ input, ctx }) => {
1974
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1975
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
1976
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1977
+ return p.open(methodInput as any)
1978
+ }),
1979
+ close: adminProcedure
1980
+ .input(coverCapability.methods.close.input.loose())
1981
+ .output(coverCapability.methods.close.output)
1982
+ .mutation(async ({ input, ctx }) => {
1983
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1984
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
1985
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1986
+ return p.close(methodInput as any)
1987
+ }),
1988
+ stop: adminProcedure
1989
+ .input(coverCapability.methods.stop.input.loose())
1990
+ .output(coverCapability.methods.stop.output)
1991
+ .mutation(async ({ input, ctx }) => {
1992
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1993
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
1994
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1995
+ return p.stop(methodInput as any)
1996
+ }),
1997
+ setPosition: adminProcedure
1998
+ .input(coverCapability.methods.setPosition.input.loose())
1999
+ .output(coverCapability.methods.setPosition.output)
2000
+ .mutation(async ({ input, ctx }) => {
2001
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2002
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
2003
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2004
+ return p.setPosition(methodInput as any)
2005
+ }),
2006
+ setTiltPosition: adminProcedure
2007
+ .input(coverCapability.methods.setTiltPosition.input.loose())
2008
+ .output(coverCapability.methods.setTiltPosition.output)
2009
+ .mutation(async ({ input, ctx }) => {
2010
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2011
+ const p = resolveProvider('cover', nodeId, () => getProvider(ctx), createRemoteProxy)
2012
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2013
+ return p.setTiltPosition(methodInput as any)
2014
+ }),
1222
2015
  })
1223
2016
  }
1224
2017
 
@@ -1393,6 +2186,90 @@ export function createCapRouter_detectionPipeline(
1393
2186
  })
1394
2187
  }
1395
2188
 
2189
+ // ── device-adoption (singleton) ─────────────────────────────────────
2190
+
2191
+ type DeviceAdoptionProvider = InferProvider<typeof deviceAdoptionCapability>
2192
+
2193
+ export function createCapRouter_deviceAdoption(
2194
+ getProvider: (ctx: TrpcContext) => DeviceAdoptionProvider | null,
2195
+ createRemoteProxy?: (capName: string, nodeId: string) => DeviceAdoptionProvider | null,
2196
+ ) {
2197
+ return trpcRouter({
2198
+ getStatus: protectedProcedure
2199
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
2200
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
2201
+ .query(async ({ input, ctx }) => {
2202
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2203
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2205
+ return p.getStatus(methodInput as any)
2206
+ }),
2207
+ listCandidateFilters: adminProcedure
2208
+ .input(deviceAdoptionCapability.methods.listCandidateFilters.input.loose())
2209
+ .output(deviceAdoptionCapability.methods.listCandidateFilters.output)
2210
+ .query(async ({ input, ctx }) => {
2211
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2212
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2213
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2214
+ return p.listCandidateFilters(methodInput as any)
2215
+ }),
2216
+ listCandidates: adminProcedure
2217
+ .input(deviceAdoptionCapability.methods.listCandidates.input.loose())
2218
+ .output(deviceAdoptionCapability.methods.listCandidates.output)
2219
+ .query(async ({ input, ctx }) => {
2220
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2221
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2222
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2223
+ return p.listCandidates(methodInput as any)
2224
+ }),
2225
+ getCandidate: adminProcedure
2226
+ .input(deviceAdoptionCapability.methods.getCandidate.input.loose())
2227
+ .output(deviceAdoptionCapability.methods.getCandidate.output)
2228
+ .query(async ({ input, ctx }) => {
2229
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2230
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2232
+ return p.getCandidate(methodInput as any)
2233
+ }),
2234
+ refresh: adminProcedure
2235
+ .input(deviceAdoptionCapability.methods.refresh.input.loose())
2236
+ .output(deviceAdoptionCapability.methods.refresh.output)
2237
+ .mutation(async ({ input, ctx }) => {
2238
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2239
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2240
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2241
+ return p.refresh(methodInput as any)
2242
+ }),
2243
+ adopt: adminProcedure
2244
+ .input(deviceAdoptionCapability.methods.adopt.input.loose())
2245
+ .output(deviceAdoptionCapability.methods.adopt.output)
2246
+ .mutation(async ({ input, ctx }) => {
2247
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2248
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2249
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2250
+ return p.adopt(methodInput as any)
2251
+ }),
2252
+ release: adminProcedure
2253
+ .input(deviceAdoptionCapability.methods.release.input.loose())
2254
+ .output(deviceAdoptionCapability.methods.release.output)
2255
+ .mutation(async ({ input, ctx }) => {
2256
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2257
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2258
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2259
+ return p.release(methodInput as any)
2260
+ }),
2261
+ resync: adminProcedure
2262
+ .input(deviceAdoptionCapability.methods.resync.input.loose())
2263
+ .output(deviceAdoptionCapability.methods.resync.output)
2264
+ .mutation(async ({ input, ctx }) => {
2265
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2266
+ const p = resolveProvider('device-adoption', nodeId, () => getProvider(ctx), createRemoteProxy)
2267
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2268
+ return p.resync(methodInput as any)
2269
+ }),
2270
+ })
2271
+ }
2272
+
1396
2273
  // ── device-discovery (singleton) ────────────────────────────────────
1397
2274
 
1398
2275
  type DeviceDiscoveryProvider = InferProvider<typeof deviceDiscoveryCapability>
@@ -1571,52 +2448,133 @@ export function createCapRouter_deviceManager(
1571
2448
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1572
2449
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1573
2450
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1574
- return p.persistConfig(methodInput as any)
2451
+ return p.persistConfig(methodInput as any)
2452
+ }),
2453
+ loadConfig: protectedProcedure
2454
+ .input(deviceManagerCapability.methods.loadConfig.input.loose())
2455
+ .output(deviceManagerCapability.methods.loadConfig.output)
2456
+ .query(async ({ input, ctx }) => {
2457
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2458
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2459
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2460
+ return p.loadConfig(methodInput as any)
2461
+ }),
2462
+ loadRuntimeState: protectedProcedure
2463
+ .input(deviceManagerCapability.methods.loadRuntimeState.input.loose())
2464
+ .output(deviceManagerCapability.methods.loadRuntimeState.output)
2465
+ .query(async ({ input, ctx }) => {
2466
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2467
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2468
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2469
+ return p.loadRuntimeState(methodInput as any)
2470
+ }),
2471
+ loadMeta: protectedProcedure
2472
+ .input(deviceManagerCapability.methods.loadMeta.input.loose())
2473
+ .output(deviceManagerCapability.methods.loadMeta.output)
2474
+ .query(async ({ input, ctx }) => {
2475
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2476
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2477
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2478
+ return p.loadMeta(methodInput as any)
2479
+ }),
2480
+ setName: adminProcedure
2481
+ .input(deviceManagerCapability.methods.setName.input.loose())
2482
+ .output(deviceManagerCapability.methods.setName.output)
2483
+ .mutation(async ({ input, ctx }) => {
2484
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2485
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2486
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2487
+ return p.setName(methodInput as any)
2488
+ }),
2489
+ setLocation: adminProcedure
2490
+ .input(deviceManagerCapability.methods.setLocation.input.loose())
2491
+ .output(deviceManagerCapability.methods.setLocation.output)
2492
+ .mutation(async ({ input, ctx }) => {
2493
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2494
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2495
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2496
+ return p.setLocation(methodInput as any)
2497
+ }),
2498
+ setType: adminProcedure
2499
+ .input(deviceManagerCapability.methods.setType.input.loose())
2500
+ .output(deviceManagerCapability.methods.setType.output)
2501
+ .mutation(async ({ input, ctx }) => {
2502
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2503
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2504
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2505
+ return p.setType(methodInput as any)
2506
+ }),
2507
+ setIntegrationId: adminProcedure
2508
+ .input(deviceManagerCapability.methods.setIntegrationId.input.loose())
2509
+ .output(deviceManagerCapability.methods.setIntegrationId.output)
2510
+ .mutation(async ({ input, ctx }) => {
2511
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2512
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2513
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2514
+ return p.setIntegrationId(methodInput as any)
2515
+ }),
2516
+ setLinkDeviceId: adminProcedure
2517
+ .input(deviceManagerCapability.methods.setLinkDeviceId.input.loose())
2518
+ .output(deviceManagerCapability.methods.setLinkDeviceId.output)
2519
+ .mutation(async ({ input, ctx }) => {
2520
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2521
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2522
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2523
+ return p.setLinkDeviceId(methodInput as any)
2524
+ }),
2525
+ setPrimaryChildEntityId: adminProcedure
2526
+ .input(deviceManagerCapability.methods.setPrimaryChildEntityId.input.loose())
2527
+ .output(deviceManagerCapability.methods.setPrimaryChildEntityId.output)
2528
+ .mutation(async ({ input, ctx }) => {
2529
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2530
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2531
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2532
+ return p.setPrimaryChildEntityId(methodInput as any)
1575
2533
  }),
1576
- loadConfig: protectedProcedure
1577
- .input(deviceManagerCapability.methods.loadConfig.input.loose())
1578
- .output(deviceManagerCapability.methods.loadConfig.output)
1579
- .query(async ({ input, ctx }) => {
2534
+ setChildLayout: adminProcedure
2535
+ .input(deviceManagerCapability.methods.setChildLayout.input.loose())
2536
+ .output(deviceManagerCapability.methods.setChildLayout.output)
2537
+ .mutation(async ({ input, ctx }) => {
1580
2538
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1581
2539
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1582
2540
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1583
- return p.loadConfig(methodInput as any)
2541
+ return p.setChildLayout(methodInput as any)
1584
2542
  }),
1585
- loadRuntimeState: protectedProcedure
1586
- .input(deviceManagerCapability.methods.loadRuntimeState.input.loose())
1587
- .output(deviceManagerCapability.methods.loadRuntimeState.output)
1588
- .query(async ({ input, ctx }) => {
2543
+ setDeviceLinks: adminProcedure
2544
+ .input(deviceManagerCapability.methods.setDeviceLinks.input.loose())
2545
+ .output(deviceManagerCapability.methods.setDeviceLinks.output)
2546
+ .mutation(async ({ input, ctx }) => {
1589
2547
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1590
2548
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1591
2549
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1592
- return p.loadRuntimeState(methodInput as any)
2550
+ return p.setDeviceLinks(methodInput as any)
1593
2551
  }),
1594
- loadMeta: protectedProcedure
1595
- .input(deviceManagerCapability.methods.loadMeta.input.loose())
1596
- .output(deviceManagerCapability.methods.loadMeta.output)
2552
+ getWireableFields: protectedProcedure
2553
+ .input(deviceManagerCapability.methods.getWireableFields.input.loose())
2554
+ .output(deviceManagerCapability.methods.getWireableFields.output)
1597
2555
  .query(async ({ input, ctx }) => {
1598
2556
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1599
2557
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1600
2558
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1601
- return p.loadMeta(methodInput as any)
2559
+ return p.getWireableFields(methodInput as any)
1602
2560
  }),
1603
- setName: adminProcedure
1604
- .input(deviceManagerCapability.methods.setName.input.loose())
1605
- .output(deviceManagerCapability.methods.setName.output)
2561
+ setRole: adminProcedure
2562
+ .input(deviceManagerCapability.methods.setRole.input.loose())
2563
+ .output(deviceManagerCapability.methods.setRole.output)
1606
2564
  .mutation(async ({ input, ctx }) => {
1607
2565
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1608
2566
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1609
2567
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1610
- return p.setName(methodInput as any)
2568
+ return p.setRole(methodInput as any)
1611
2569
  }),
1612
- setLocation: adminProcedure
1613
- .input(deviceManagerCapability.methods.setLocation.input.loose())
1614
- .output(deviceManagerCapability.methods.setLocation.output)
2570
+ applyInitialMeta: adminProcedure
2571
+ .input(deviceManagerCapability.methods.applyInitialMeta.input.loose())
2572
+ .output(deviceManagerCapability.methods.applyInitialMeta.output)
1615
2573
  .mutation(async ({ input, ctx }) => {
1616
2574
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
1617
2575
  const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
1618
2576
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1619
- return p.setLocation(methodInput as any)
2577
+ return p.applyInitialMeta(methodInput as any)
1620
2578
  }),
1621
2579
  setMetadata: adminProcedure
1622
2580
  .input(deviceManagerCapability.methods.setMetadata.input.loose())
@@ -1760,6 +2718,15 @@ export function createCapRouter_deviceManager(
1760
2718
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1761
2719
  return p.remove(methodInput as any)
1762
2720
  }),
2721
+ removeByIntegration: adminProcedure
2722
+ .input(deviceManagerCapability.methods.removeByIntegration.input.loose())
2723
+ .output(deviceManagerCapability.methods.removeByIntegration.output)
2724
+ .mutation(async ({ input, ctx }) => {
2725
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2726
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2727
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2728
+ return p.removeByIntegration(methodInput as any)
2729
+ }),
1763
2730
  getStreamProfileMap: protectedProcedure
1764
2731
  .input(deviceManagerCapability.methods.getStreamProfileMap.input.loose())
1765
2732
  .output(deviceManagerCapability.methods.getStreamProfileMap.output)
@@ -1859,6 +2826,15 @@ export function createCapRouter_deviceManager(
1859
2826
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1860
2827
  return p.getDeviceAggregate(methodInput as any)
1861
2828
  }),
2829
+ runDeviceAction: protectedProcedure
2830
+ .input(deviceManagerCapability.methods.runDeviceAction.input.loose())
2831
+ .output(deviceManagerCapability.methods.runDeviceAction.output)
2832
+ .mutation(async ({ input, ctx }) => {
2833
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2834
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2835
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2836
+ return p.runDeviceAction(methodInput as any)
2837
+ }),
1862
2838
  updateDeviceField: adminProcedure
1863
2839
  .input(deviceManagerCapability.methods.updateDeviceField.input.loose())
1864
2840
  .output(deviceManagerCapability.methods.updateDeviceField.output)
@@ -1922,6 +2898,42 @@ export function createCapRouter_deviceManager(
1922
2898
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1923
2899
  return p.testCreationField(methodInput as any)
1924
2900
  }),
2901
+ adoptionListCandidates: adminProcedure
2902
+ .input(deviceManagerCapability.methods.adoptionListCandidates.input.loose())
2903
+ .output(deviceManagerCapability.methods.adoptionListCandidates.output)
2904
+ .query(async ({ input, ctx }) => {
2905
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2906
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2907
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2908
+ return p.adoptionListCandidates(methodInput as any)
2909
+ }),
2910
+ adoptionRefresh: adminProcedure
2911
+ .input(deviceManagerCapability.methods.adoptionRefresh.input.loose())
2912
+ .output(deviceManagerCapability.methods.adoptionRefresh.output)
2913
+ .mutation(async ({ input, ctx }) => {
2914
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2915
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2916
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2917
+ return p.adoptionRefresh(methodInput as any)
2918
+ }),
2919
+ adoptionAdopt: adminProcedure
2920
+ .input(deviceManagerCapability.methods.adoptionAdopt.input.loose())
2921
+ .output(deviceManagerCapability.methods.adoptionAdopt.output)
2922
+ .mutation(async ({ input, ctx }) => {
2923
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2924
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2925
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2926
+ return p.adoptionAdopt(methodInput as any)
2927
+ }),
2928
+ adoptionRelease: adminProcedure
2929
+ .input(deviceManagerCapability.methods.adoptionRelease.input.loose())
2930
+ .output(deviceManagerCapability.methods.adoptionRelease.output)
2931
+ .mutation(async ({ input, ctx }) => {
2932
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2933
+ const p = resolveProvider('device-manager', nodeId, () => getProvider(ctx), createRemoteProxy)
2934
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2935
+ return p.adoptionRelease(methodInput as any)
2936
+ }),
1925
2937
  testField: adminProcedure
1926
2938
  .input(deviceManagerCapability.methods.testField.input.loose())
1927
2939
  .output(deviceManagerCapability.methods.testField.output)
@@ -1979,6 +2991,15 @@ export function createCapRouter_deviceOps(
1979
2991
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1980
2992
  return p.setConfig(methodInput as any)
1981
2993
  }),
2994
+ runAction: protectedProcedure
2995
+ .input(deviceOpsCapability.methods.runAction.input.loose())
2996
+ .output(deviceOpsCapability.methods.runAction.output)
2997
+ .mutation(async ({ input, ctx }) => {
2998
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2999
+ const p = resolveProvider('device-ops', nodeId, () => getProvider(ctx), createRemoteProxy)
3000
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3001
+ return p.runAction(methodInput as any)
3002
+ }),
1982
3003
  removeDevice: protectedProcedure
1983
3004
  .input(deviceOpsCapability.methods.removeDevice.input.loose())
1984
3005
  .output(deviceOpsCapability.methods.removeDevice.output)
@@ -1997,6 +3018,15 @@ export function createCapRouter_deviceOps(
1997
3018
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
1998
3019
  return p.getSettingsSchema(methodInput as any)
1999
3020
  }),
3021
+ getRawState: protectedProcedure
3022
+ .input(deviceOpsCapability.methods.getRawState.input.loose())
3023
+ .output(deviceOpsCapability.methods.getRawState.output)
3024
+ .query(async ({ input, ctx }) => {
3025
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3026
+ const p = resolveProvider('device-ops', nodeId, () => getProvider(ctx), createRemoteProxy)
3027
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3028
+ return p.getRawState(methodInput as any)
3029
+ }),
2000
3030
  })
2001
3031
  }
2002
3032
 
@@ -2112,52 +3142,269 @@ export function createCapRouter_deviceState(
2112
3142
  createRemoteProxy?: (capName: string, nodeId: string) => DeviceStateProvider | null,
2113
3143
  ) {
2114
3144
  return trpcRouter({
2115
- getSnapshot: protectedProcedure
2116
- .input(deviceStateCapability.methods.getSnapshot.input.loose())
2117
- .output(deviceStateCapability.methods.getSnapshot.output)
3145
+ getSnapshot: protectedProcedure
3146
+ .input(deviceStateCapability.methods.getSnapshot.input.loose())
3147
+ .output(deviceStateCapability.methods.getSnapshot.output)
3148
+ .query(async ({ input, ctx }) => {
3149
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3150
+ const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3151
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3152
+ return p.getSnapshot(methodInput as any)
3153
+ }),
3154
+ getCapSlice: protectedProcedure
3155
+ .input(deviceStateCapability.methods.getCapSlice.input.loose())
3156
+ .output(deviceStateCapability.methods.getCapSlice.output)
3157
+ .query(async ({ input, ctx }) => {
3158
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3159
+ const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3160
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3161
+ return p.getCapSlice(methodInput as any)
3162
+ }),
3163
+ getAllSnapshots: protectedProcedure
3164
+ .input(deviceStateCapability.methods.getAllSnapshots.input.loose())
3165
+ .output(deviceStateCapability.methods.getAllSnapshots.output)
3166
+ .query(async ({ input, ctx }) => {
3167
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3168
+ const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3169
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3170
+ return p.getAllSnapshots(methodInput as any)
3171
+ }),
3172
+ setCapSlice: protectedProcedure
3173
+ .input(deviceStateCapability.methods.setCapSlice.input.loose())
3174
+ .output(deviceStateCapability.methods.setCapSlice.output)
3175
+ .mutation(async ({ input, ctx }) => {
3176
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3177
+ const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3178
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3179
+ return p.setCapSlice(methodInput as any)
3180
+ }),
3181
+ })
3182
+ }
3183
+
3184
+ // ── device-status (singleton) ───────────────────────────────────────
3185
+
3186
+ type DeviceStatusProvider = InferProvider<typeof deviceStatusCapability>
3187
+
3188
+ export function createCapRouter_deviceStatus(
3189
+ getProvider: (ctx: TrpcContext) => DeviceStatusProvider | null,
3190
+ createRemoteProxy?: (capName: string, nodeId: string) => DeviceStatusProvider | null,
3191
+ ) {
3192
+ return trpcRouter({
3193
+ getStatus: protectedProcedure
3194
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3195
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3196
+ .query(async ({ input, ctx }) => {
3197
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3198
+ const p = resolveProvider('device-status', nodeId, () => getProvider(ctx), createRemoteProxy)
3199
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3200
+ return p.getStatus(methodInput as any)
3201
+ }),
3202
+ })
3203
+ }
3204
+
3205
+ // ── doorbell (singleton) ────────────────────────────────────────────
3206
+
3207
+ type DoorbellProvider = InferProvider<typeof doorbellCapability>
3208
+
3209
+ export function createCapRouter_doorbell(
3210
+ getProvider: (ctx: TrpcContext) => DoorbellProvider | null,
3211
+ createRemoteProxy?: (capName: string, nodeId: string) => DoorbellProvider | null,
3212
+ ) {
3213
+ return trpcRouter({
3214
+ getStatus: protectedProcedure
3215
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3216
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3217
+ .query(async ({ input, ctx }) => {
3218
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3219
+ const p = resolveProvider('doorbell', nodeId, () => getProvider(ctx), createRemoteProxy)
3220
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3221
+ return p.getStatus(methodInput as any)
3222
+ }),
3223
+ })
3224
+ }
3225
+
3226
+ // ── embedding-encoder (collection) ───────────────────────────────────
3227
+
3228
+ type EmbeddingEncoderProvider = InferProvider<typeof embeddingEncoderCapability>
3229
+
3230
+ export function createCapRouter_embeddingEncoder(
3231
+ getProvider: (ctx: TrpcContext, addonId?: string) => EmbeddingEncoderProvider | null,
3232
+ createRemoteProxy?: (capName: string, nodeId: string) => EmbeddingEncoderProvider | null,
3233
+ ) {
3234
+ return trpcRouter({
3235
+ encode: protectedProcedure
3236
+ .input(embeddingEncoderCapability.methods.encode.input.loose())
3237
+ .output(embeddingEncoderCapability.methods.encode.output)
3238
+ .query(async ({ input, ctx }) => {
3239
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
3240
+ const p = resolveProvider('embedding-encoder', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
3241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3242
+ return p.encode(methodInput as any)
3243
+ }),
3244
+ encodeText: protectedProcedure
3245
+ .input(embeddingEncoderCapability.methods.encodeText.input.loose())
3246
+ .output(embeddingEncoderCapability.methods.encodeText.output)
3247
+ .query(async ({ input, ctx }) => {
3248
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
3249
+ const p = resolveProvider('embedding-encoder', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
3250
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3251
+ return p.encodeText(methodInput as any)
3252
+ }),
3253
+ getInfo: protectedProcedure
3254
+ .input(z.object({ nodeId: z.string().optional(), addonId: z.string().optional() }).optional())
3255
+ .output(embeddingEncoderCapability.methods.getInfo.output)
3256
+ .query(async ({ input, ctx }) => {
3257
+ const p = resolveProvider('embedding-encoder', input?.nodeId, () => getProvider(ctx, input?.addonId), createRemoteProxy)
3258
+ return p.getInfo()
3259
+ }),
3260
+ })
3261
+ }
3262
+
3263
+ // ── enum-sensor (singleton) ─────────────────────────────────────────
3264
+
3265
+ type EnumSensorProvider = InferProvider<typeof enumSensorCapability>
3266
+
3267
+ export function createCapRouter_enumSensor(
3268
+ getProvider: (ctx: TrpcContext) => EnumSensorProvider | null,
3269
+ createRemoteProxy?: (capName: string, nodeId: string) => EnumSensorProvider | null,
3270
+ ) {
3271
+ return trpcRouter({
3272
+ getStatus: protectedProcedure
3273
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3274
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3275
+ .query(async ({ input, ctx }) => {
3276
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3277
+ const p = resolveProvider('enum-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
3278
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3279
+ return p.getStatus(methodInput as any)
3280
+ }),
3281
+ })
3282
+ }
3283
+
3284
+ // ── event-emitter (singleton) ───────────────────────────────────────
3285
+
3286
+ type EventEmitterProvider = InferProvider<typeof eventEmitterCapability>
3287
+
3288
+ export function createCapRouter_eventEmitter(
3289
+ getProvider: (ctx: TrpcContext) => EventEmitterProvider | null,
3290
+ createRemoteProxy?: (capName: string, nodeId: string) => EventEmitterProvider | null,
3291
+ ) {
3292
+ return trpcRouter({
3293
+ getStatus: protectedProcedure
3294
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3295
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3296
+ .query(async ({ input, ctx }) => {
3297
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3298
+ const p = resolveProvider('event-emitter', nodeId, () => getProvider(ctx), createRemoteProxy)
3299
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3300
+ return p.getStatus(methodInput as any)
3301
+ }),
3302
+ })
3303
+ }
3304
+
3305
+ // ── events (singleton) ──────────────────────────────────────────────
3306
+
3307
+ type EventsProvider = InferProvider<typeof eventsCapability>
3308
+
3309
+ export function createCapRouter_events(
3310
+ getProvider: (ctx: TrpcContext) => EventsProvider | null,
3311
+ createRemoteProxy?: (capName: string, nodeId: string) => EventsProvider | null,
3312
+ ) {
3313
+ return trpcRouter({
3314
+ getEvents: protectedProcedure
3315
+ .input(eventsCapability.methods.getEvents.input.loose())
3316
+ .output(eventsCapability.methods.getEvents.output)
3317
+ .query(async ({ input, ctx }) => {
3318
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3319
+ const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3320
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3321
+ return p.getEvents(methodInput as any)
3322
+ }),
3323
+ getEventThumbnail: protectedProcedure
3324
+ .input(eventsCapability.methods.getEventThumbnail.input.loose())
3325
+ .output(eventsCapability.methods.getEventThumbnail.output)
3326
+ .query(async ({ input, ctx }) => {
3327
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3328
+ const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3329
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3330
+ return p.getEventThumbnail(methodInput as any)
3331
+ }),
3332
+ getEventClipUrl: protectedProcedure
3333
+ .input(eventsCapability.methods.getEventClipUrl.input.loose())
3334
+ .output(eventsCapability.methods.getEventClipUrl.output)
3335
+ .query(async ({ input, ctx }) => {
3336
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3337
+ const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3338
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3339
+ return p.getEventClipUrl(methodInput as any)
3340
+ }),
3341
+ })
3342
+ }
3343
+
3344
+ // ── fan-control (singleton) ─────────────────────────────────────────
3345
+
3346
+ type FanControlProvider = InferProvider<typeof fanControlCapability>
3347
+
3348
+ export function createCapRouter_fanControl(
3349
+ getProvider: (ctx: TrpcContext) => FanControlProvider | null,
3350
+ createRemoteProxy?: (capName: string, nodeId: string) => FanControlProvider | null,
3351
+ ) {
3352
+ return trpcRouter({
3353
+ getStatus: protectedProcedure
3354
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3355
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
2118
3356
  .query(async ({ input, ctx }) => {
2119
3357
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2120
- const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3358
+ const p = resolveProvider('fan-control', nodeId, () => getProvider(ctx), createRemoteProxy)
2121
3359
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2122
- return p.getSnapshot(methodInput as any)
3360
+ return p.getStatus(methodInput as any)
2123
3361
  }),
2124
- getCapSlice: protectedProcedure
2125
- .input(deviceStateCapability.methods.getCapSlice.input.loose())
2126
- .output(deviceStateCapability.methods.getCapSlice.output)
2127
- .query(async ({ input, ctx }) => {
3362
+ setPercentage: adminProcedure
3363
+ .input(fanControlCapability.methods.setPercentage.input.loose())
3364
+ .output(fanControlCapability.methods.setPercentage.output)
3365
+ .mutation(async ({ input, ctx }) => {
2128
3366
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2129
- const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3367
+ const p = resolveProvider('fan-control', nodeId, () => getProvider(ctx), createRemoteProxy)
2130
3368
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2131
- return p.getCapSlice(methodInput as any)
3369
+ return p.setPercentage(methodInput as any)
2132
3370
  }),
2133
- getAllSnapshots: protectedProcedure
2134
- .input(deviceStateCapability.methods.getAllSnapshots.input.loose())
2135
- .output(deviceStateCapability.methods.getAllSnapshots.output)
2136
- .query(async ({ input, ctx }) => {
3371
+ setPreset: adminProcedure
3372
+ .input(fanControlCapability.methods.setPreset.input.loose())
3373
+ .output(fanControlCapability.methods.setPreset.output)
3374
+ .mutation(async ({ input, ctx }) => {
2137
3375
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2138
- const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3376
+ const p = resolveProvider('fan-control', nodeId, () => getProvider(ctx), createRemoteProxy)
2139
3377
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2140
- return p.getAllSnapshots(methodInput as any)
3378
+ return p.setPreset(methodInput as any)
2141
3379
  }),
2142
- setCapSlice: protectedProcedure
2143
- .input(deviceStateCapability.methods.setCapSlice.input.loose())
2144
- .output(deviceStateCapability.methods.setCapSlice.output)
3380
+ setDirection: adminProcedure
3381
+ .input(fanControlCapability.methods.setDirection.input.loose())
3382
+ .output(fanControlCapability.methods.setDirection.output)
2145
3383
  .mutation(async ({ input, ctx }) => {
2146
3384
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2147
- const p = resolveProvider('device-state', nodeId, () => getProvider(ctx), createRemoteProxy)
3385
+ const p = resolveProvider('fan-control', nodeId, () => getProvider(ctx), createRemoteProxy)
2148
3386
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2149
- return p.setCapSlice(methodInput as any)
3387
+ return p.setDirection(methodInput as any)
3388
+ }),
3389
+ setOscillating: adminProcedure
3390
+ .input(fanControlCapability.methods.setOscillating.input.loose())
3391
+ .output(fanControlCapability.methods.setOscillating.output)
3392
+ .mutation(async ({ input, ctx }) => {
3393
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3394
+ const p = resolveProvider('fan-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3395
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3396
+ return p.setOscillating(methodInput as any)
2150
3397
  }),
2151
3398
  })
2152
3399
  }
2153
3400
 
2154
- // ── device-status (singleton) ───────────────────────────────────────
3401
+ // ── feature-probe (singleton) ───────────────────────────────────────
2155
3402
 
2156
- type DeviceStatusProvider = InferProvider<typeof deviceStatusCapability>
3403
+ type FeatureProbeProvider = InferProvider<typeof featureProbeCapability>
2157
3404
 
2158
- export function createCapRouter_deviceStatus(
2159
- getProvider: (ctx: TrpcContext) => DeviceStatusProvider | null,
2160
- createRemoteProxy?: (capName: string, nodeId: string) => DeviceStatusProvider | null,
3405
+ export function createCapRouter_featureProbe(
3406
+ getProvider: (ctx: TrpcContext) => FeatureProbeProvider | null,
3407
+ createRemoteProxy?: (capName: string, nodeId: string) => FeatureProbeProvider | null,
2161
3408
  ) {
2162
3409
  return trpcRouter({
2163
3410
  getStatus: protectedProcedure
@@ -2165,20 +3412,20 @@ export function createCapRouter_deviceStatus(
2165
3412
  .output(DEVICE_STATUS_METHOD.getStatus.output)
2166
3413
  .query(async ({ input, ctx }) => {
2167
3414
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2168
- const p = resolveProvider('device-status', nodeId, () => getProvider(ctx), createRemoteProxy)
3415
+ const p = resolveProvider('feature-probe', nodeId, () => getProvider(ctx), createRemoteProxy)
2169
3416
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2170
3417
  return p.getStatus(methodInput as any)
2171
3418
  }),
2172
3419
  })
2173
3420
  }
2174
3421
 
2175
- // ── doorbell (singleton) ────────────────────────────────────────────
3422
+ // ── flood (singleton) ───────────────────────────────────────────────
2176
3423
 
2177
- type DoorbellProvider = InferProvider<typeof doorbellCapability>
3424
+ type FloodProvider = InferProvider<typeof floodCapability>
2178
3425
 
2179
- export function createCapRouter_doorbell(
2180
- getProvider: (ctx: TrpcContext) => DoorbellProvider | null,
2181
- createRemoteProxy?: (capName: string, nodeId: string) => DoorbellProvider | null,
3426
+ export function createCapRouter_flood(
3427
+ getProvider: (ctx: TrpcContext) => FloodProvider | null,
3428
+ createRemoteProxy?: (capName: string, nodeId: string) => FloodProvider | null,
2182
3429
  ) {
2183
3430
  return trpcRouter({
2184
3431
  getStatus: protectedProcedure
@@ -2186,96 +3433,110 @@ export function createCapRouter_doorbell(
2186
3433
  .output(DEVICE_STATUS_METHOD.getStatus.output)
2187
3434
  .query(async ({ input, ctx }) => {
2188
3435
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2189
- const p = resolveProvider('doorbell', nodeId, () => getProvider(ctx), createRemoteProxy)
3436
+ const p = resolveProvider('flood', nodeId, () => getProvider(ctx), createRemoteProxy)
2190
3437
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2191
3438
  return p.getStatus(methodInput as any)
2192
3439
  }),
2193
3440
  })
2194
3441
  }
2195
3442
 
2196
- // ── embedding-encoder (collection) ───────────────────────────────────
3443
+ // ── gas (singleton) ─────────────────────────────────────────────────
2197
3444
 
2198
- type EmbeddingEncoderProvider = InferProvider<typeof embeddingEncoderCapability>
3445
+ type GasProvider = InferProvider<typeof gasCapability>
2199
3446
 
2200
- export function createCapRouter_embeddingEncoder(
2201
- getProvider: (ctx: TrpcContext, addonId?: string) => EmbeddingEncoderProvider | null,
2202
- createRemoteProxy?: (capName: string, nodeId: string) => EmbeddingEncoderProvider | null,
3447
+ export function createCapRouter_gas(
3448
+ getProvider: (ctx: TrpcContext) => GasProvider | null,
3449
+ createRemoteProxy?: (capName: string, nodeId: string) => GasProvider | null,
2203
3450
  ) {
2204
3451
  return trpcRouter({
2205
- encode: protectedProcedure
2206
- .input(embeddingEncoderCapability.methods.encode.input.loose())
2207
- .output(embeddingEncoderCapability.methods.encode.output)
2208
- .query(async ({ input, ctx }) => {
2209
- const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
2210
- const p = resolveProvider('embedding-encoder', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
2211
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2212
- return p.encode(methodInput as any)
2213
- }),
2214
- encodeText: protectedProcedure
2215
- .input(embeddingEncoderCapability.methods.encodeText.input.loose())
2216
- .output(embeddingEncoderCapability.methods.encodeText.output)
3452
+ getStatus: protectedProcedure
3453
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3454
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
2217
3455
  .query(async ({ input, ctx }) => {
2218
- const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
2219
- const p = resolveProvider('embedding-encoder', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
3456
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3457
+ const p = resolveProvider('gas', nodeId, () => getProvider(ctx), createRemoteProxy)
2220
3458
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2221
- return p.encodeText(methodInput as any)
2222
- }),
2223
- getInfo: protectedProcedure
2224
- .input(z.object({ nodeId: z.string().optional(), addonId: z.string().optional() }).optional())
2225
- .output(embeddingEncoderCapability.methods.getInfo.output)
2226
- .query(async ({ input, ctx }) => {
2227
- const p = resolveProvider('embedding-encoder', input?.nodeId, () => getProvider(ctx, input?.addonId), createRemoteProxy)
2228
- return p.getInfo()
3459
+ return p.getStatus(methodInput as any)
2229
3460
  }),
2230
3461
  })
2231
3462
  }
2232
3463
 
2233
- // ── events (singleton) ──────────────────────────────────────────────
3464
+ // ── humidifier (singleton) ──────────────────────────────────────────
2234
3465
 
2235
- type EventsProvider = InferProvider<typeof eventsCapability>
3466
+ type HumidifierProvider = InferProvider<typeof humidifierCapability>
2236
3467
 
2237
- export function createCapRouter_events(
2238
- getProvider: (ctx: TrpcContext) => EventsProvider | null,
2239
- createRemoteProxy?: (capName: string, nodeId: string) => EventsProvider | null,
3468
+ export function createCapRouter_humidifier(
3469
+ getProvider: (ctx: TrpcContext) => HumidifierProvider | null,
3470
+ createRemoteProxy?: (capName: string, nodeId: string) => HumidifierProvider | null,
2240
3471
  ) {
2241
3472
  return trpcRouter({
2242
- getEvents: protectedProcedure
2243
- .input(eventsCapability.methods.getEvents.input.loose())
2244
- .output(eventsCapability.methods.getEvents.output)
3473
+ getStatus: protectedProcedure
3474
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3475
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
2245
3476
  .query(async ({ input, ctx }) => {
2246
3477
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2247
- const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3478
+ const p = resolveProvider('humidifier', nodeId, () => getProvider(ctx), createRemoteProxy)
2248
3479
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2249
- return p.getEvents(methodInput as any)
3480
+ return p.getStatus(methodInput as any)
2250
3481
  }),
2251
- getEventThumbnail: protectedProcedure
2252
- .input(eventsCapability.methods.getEventThumbnail.input.loose())
2253
- .output(eventsCapability.methods.getEventThumbnail.output)
2254
- .query(async ({ input, ctx }) => {
3482
+ setOn: adminProcedure
3483
+ .input(humidifierCapability.methods.setOn.input.loose())
3484
+ .output(humidifierCapability.methods.setOn.output)
3485
+ .mutation(async ({ input, ctx }) => {
2255
3486
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2256
- const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3487
+ const p = resolveProvider('humidifier', nodeId, () => getProvider(ctx), createRemoteProxy)
2257
3488
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2258
- return p.getEventThumbnail(methodInput as any)
3489
+ return p.setOn(methodInput as any)
2259
3490
  }),
2260
- getEventClipUrl: protectedProcedure
2261
- .input(eventsCapability.methods.getEventClipUrl.input.loose())
2262
- .output(eventsCapability.methods.getEventClipUrl.output)
3491
+ setTargetHumidity: adminProcedure
3492
+ .input(humidifierCapability.methods.setTargetHumidity.input.loose())
3493
+ .output(humidifierCapability.methods.setTargetHumidity.output)
3494
+ .mutation(async ({ input, ctx }) => {
3495
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3496
+ const p = resolveProvider('humidifier', nodeId, () => getProvider(ctx), createRemoteProxy)
3497
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3498
+ return p.setTargetHumidity(methodInput as any)
3499
+ }),
3500
+ setMode: adminProcedure
3501
+ .input(humidifierCapability.methods.setMode.input.loose())
3502
+ .output(humidifierCapability.methods.setMode.output)
3503
+ .mutation(async ({ input, ctx }) => {
3504
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3505
+ const p = resolveProvider('humidifier', nodeId, () => getProvider(ctx), createRemoteProxy)
3506
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3507
+ return p.setMode(methodInput as any)
3508
+ }),
3509
+ })
3510
+ }
3511
+
3512
+ // ── humidity-sensor (singleton) ─────────────────────────────────────
3513
+
3514
+ type HumiditySensorProvider = InferProvider<typeof humiditySensorCapability>
3515
+
3516
+ export function createCapRouter_humiditySensor(
3517
+ getProvider: (ctx: TrpcContext) => HumiditySensorProvider | null,
3518
+ createRemoteProxy?: (capName: string, nodeId: string) => HumiditySensorProvider | null,
3519
+ ) {
3520
+ return trpcRouter({
3521
+ getStatus: protectedProcedure
3522
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3523
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
2263
3524
  .query(async ({ input, ctx }) => {
2264
3525
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2265
- const p = resolveProvider('events', nodeId, () => getProvider(ctx), createRemoteProxy)
3526
+ const p = resolveProvider('humidity-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
2266
3527
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2267
- return p.getEventClipUrl(methodInput as any)
3528
+ return p.getStatus(methodInput as any)
2268
3529
  }),
2269
3530
  })
2270
3531
  }
2271
3532
 
2272
- // ── feature-probe (singleton) ───────────────────────────────────────
3533
+ // ── image (singleton) ───────────────────────────────────────────────
2273
3534
 
2274
- type FeatureProbeProvider = InferProvider<typeof featureProbeCapability>
3535
+ type ImageProvider = InferProvider<typeof imageCapability>
2275
3536
 
2276
- export function createCapRouter_featureProbe(
2277
- getProvider: (ctx: TrpcContext) => FeatureProbeProvider | null,
2278
- createRemoteProxy?: (capName: string, nodeId: string) => FeatureProbeProvider | null,
3537
+ export function createCapRouter_image(
3538
+ getProvider: (ctx: TrpcContext) => ImageProvider | null,
3539
+ createRemoteProxy?: (capName: string, nodeId: string) => ImageProvider | null,
2279
3540
  ) {
2280
3541
  return trpcRouter({
2281
3542
  getStatus: protectedProcedure
@@ -2283,7 +3544,7 @@ export function createCapRouter_featureProbe(
2283
3544
  .output(DEVICE_STATUS_METHOD.getStatus.output)
2284
3545
  .query(async ({ input, ctx }) => {
2285
3546
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2286
- const p = resolveProvider('feature-probe', nodeId, () => getProvider(ctx), createRemoteProxy)
3547
+ const p = resolveProvider('image', nodeId, () => getProvider(ctx), createRemoteProxy)
2287
3548
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2288
3549
  return p.getStatus(methodInput as any)
2289
3550
  }),
@@ -2442,14 +3703,14 @@ export function createCapRouter_intercom(
2442
3703
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2443
3704
  return p.startTalkSession(methodInput as any)
2444
3705
  }),
2445
- pushTalkPcm: adminProcedure
2446
- .input(intercomCapability.methods.pushTalkPcm.input.loose())
2447
- .output(intercomCapability.methods.pushTalkPcm.output)
3706
+ pushTalkAudio: adminProcedure
3707
+ .input(intercomCapability.methods.pushTalkAudio.input.loose())
3708
+ .output(intercomCapability.methods.pushTalkAudio.output)
2448
3709
  .mutation(async ({ input, ctx }) => {
2449
3710
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
2450
3711
  const p = resolveProvider('intercom', nodeId, () => getProvider(ctx), createRemoteProxy)
2451
3712
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2452
- return p.pushTalkPcm(methodInput as any)
3713
+ return p.pushTalkAudio(methodInput as any)
2453
3714
  }),
2454
3715
  endTalkSession: adminProcedure
2455
3716
  .input(intercomCapability.methods.endTalkSession.input.loose())
@@ -2463,6 +3724,54 @@ export function createCapRouter_intercom(
2463
3724
  })
2464
3725
  }
2465
3726
 
3727
+ // ── lawn-mower-control (singleton) ──────────────────────────────────
3728
+
3729
+ type LawnMowerControlProvider = InferProvider<typeof lawnMowerControlCapability>
3730
+
3731
+ export function createCapRouter_lawnMowerControl(
3732
+ getProvider: (ctx: TrpcContext) => LawnMowerControlProvider | null,
3733
+ createRemoteProxy?: (capName: string, nodeId: string) => LawnMowerControlProvider | null,
3734
+ ) {
3735
+ return trpcRouter({
3736
+ getStatus: protectedProcedure
3737
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3738
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3739
+ .query(async ({ input, ctx }) => {
3740
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3741
+ const p = resolveProvider('lawn-mower-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3742
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3743
+ return p.getStatus(methodInput as any)
3744
+ }),
3745
+ startMowing: adminProcedure
3746
+ .input(lawnMowerControlCapability.methods.startMowing.input.loose())
3747
+ .output(lawnMowerControlCapability.methods.startMowing.output)
3748
+ .mutation(async ({ input, ctx }) => {
3749
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3750
+ const p = resolveProvider('lawn-mower-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3751
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3752
+ return p.startMowing(methodInput as any)
3753
+ }),
3754
+ pause: adminProcedure
3755
+ .input(lawnMowerControlCapability.methods.pause.input.loose())
3756
+ .output(lawnMowerControlCapability.methods.pause.output)
3757
+ .mutation(async ({ input, ctx }) => {
3758
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3759
+ const p = resolveProvider('lawn-mower-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3760
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3761
+ return p.pause(methodInput as any)
3762
+ }),
3763
+ dock: adminProcedure
3764
+ .input(lawnMowerControlCapability.methods.dock.input.loose())
3765
+ .output(lawnMowerControlCapability.methods.dock.output)
3766
+ .mutation(async ({ input, ctx }) => {
3767
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3768
+ const p = resolveProvider('lawn-mower-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3769
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3770
+ return p.dock(methodInput as any)
3771
+ }),
3772
+ })
3773
+ }
3774
+
2466
3775
  // ── local-network (singleton) ───────────────────────────────────────
2467
3776
 
2468
3777
  type LocalNetworkProvider = InferProvider<typeof localNetworkCapability>
@@ -2521,6 +3830,54 @@ export function createCapRouter_localNetwork(
2521
3830
  })
2522
3831
  }
2523
3832
 
3833
+ // ── lock-control (singleton) ────────────────────────────────────────
3834
+
3835
+ type LockControlProvider = InferProvider<typeof lockControlCapability>
3836
+
3837
+ export function createCapRouter_lockControl(
3838
+ getProvider: (ctx: TrpcContext) => LockControlProvider | null,
3839
+ createRemoteProxy?: (capName: string, nodeId: string) => LockControlProvider | null,
3840
+ ) {
3841
+ return trpcRouter({
3842
+ getStatus: protectedProcedure
3843
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3844
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3845
+ .query(async ({ input, ctx }) => {
3846
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3847
+ const p = resolveProvider('lock-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3848
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3849
+ return p.getStatus(methodInput as any)
3850
+ }),
3851
+ lock: adminProcedure
3852
+ .input(lockControlCapability.methods.lock.input.loose())
3853
+ .output(lockControlCapability.methods.lock.output)
3854
+ .mutation(async ({ input, ctx }) => {
3855
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3856
+ const p = resolveProvider('lock-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3857
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3858
+ return p.lock(methodInput as any)
3859
+ }),
3860
+ unlock: adminProcedure
3861
+ .input(lockControlCapability.methods.unlock.input.loose())
3862
+ .output(lockControlCapability.methods.unlock.output)
3863
+ .mutation(async ({ input, ctx }) => {
3864
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3865
+ const p = resolveProvider('lock-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3866
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3867
+ return p.unlock(methodInput as any)
3868
+ }),
3869
+ open: adminProcedure
3870
+ .input(lockControlCapability.methods.open.input.loose())
3871
+ .output(lockControlCapability.methods.open.output)
3872
+ .mutation(async ({ input, ctx }) => {
3873
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3874
+ const p = resolveProvider('lock-control', nodeId, () => getProvider(ctx), createRemoteProxy)
3875
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3876
+ return p.open(methodInput as any)
3877
+ }),
3878
+ })
3879
+ }
3880
+
2524
3881
  // ── log-destination (collection) ─────────────────────────────────────
2525
3882
 
2526
3883
  type LogDestinationProvider = InferProvider<typeof logDestinationCapability>
@@ -2537,16 +3894,145 @@ export function createCapRouter_logDestination(
2537
3894
  const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
2538
3895
  const p = resolveProvider('log-destination', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
2539
3896
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2540
- return p.write(methodInput as any)
3897
+ return p.write(methodInput as any)
3898
+ }),
3899
+ query: protectedProcedure
3900
+ .input(logDestinationCapability.methods.query.input.loose())
3901
+ .output(logDestinationCapability.methods.query.output)
3902
+ .query(async ({ input, ctx }) => {
3903
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
3904
+ const p = resolveProvider('log-destination', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
3905
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3906
+ return p.query(methodInput as any)
3907
+ }),
3908
+ })
3909
+ }
3910
+
3911
+ // ── media-player (singleton) ────────────────────────────────────────
3912
+
3913
+ type MediaPlayerProvider = InferProvider<typeof mediaPlayerCapability>
3914
+
3915
+ export function createCapRouter_mediaPlayer(
3916
+ getProvider: (ctx: TrpcContext) => MediaPlayerProvider | null,
3917
+ createRemoteProxy?: (capName: string, nodeId: string) => MediaPlayerProvider | null,
3918
+ ) {
3919
+ return trpcRouter({
3920
+ getStatus: protectedProcedure
3921
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
3922
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
3923
+ .query(async ({ input, ctx }) => {
3924
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3925
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3926
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3927
+ return p.getStatus(methodInput as any)
3928
+ }),
3929
+ play: adminProcedure
3930
+ .input(mediaPlayerCapability.methods.play.input.loose())
3931
+ .output(mediaPlayerCapability.methods.play.output)
3932
+ .mutation(async ({ input, ctx }) => {
3933
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3934
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3935
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3936
+ return p.play(methodInput as any)
3937
+ }),
3938
+ pause: adminProcedure
3939
+ .input(mediaPlayerCapability.methods.pause.input.loose())
3940
+ .output(mediaPlayerCapability.methods.pause.output)
3941
+ .mutation(async ({ input, ctx }) => {
3942
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3943
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3944
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3945
+ return p.pause(methodInput as any)
3946
+ }),
3947
+ stop: adminProcedure
3948
+ .input(mediaPlayerCapability.methods.stop.input.loose())
3949
+ .output(mediaPlayerCapability.methods.stop.output)
3950
+ .mutation(async ({ input, ctx }) => {
3951
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3952
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3953
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3954
+ return p.stop(methodInput as any)
3955
+ }),
3956
+ next: adminProcedure
3957
+ .input(mediaPlayerCapability.methods.next.input.loose())
3958
+ .output(mediaPlayerCapability.methods.next.output)
3959
+ .mutation(async ({ input, ctx }) => {
3960
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3961
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3962
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3963
+ return p.next(methodInput as any)
3964
+ }),
3965
+ previous: adminProcedure
3966
+ .input(mediaPlayerCapability.methods.previous.input.loose())
3967
+ .output(mediaPlayerCapability.methods.previous.output)
3968
+ .mutation(async ({ input, ctx }) => {
3969
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3970
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3971
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3972
+ return p.previous(methodInput as any)
3973
+ }),
3974
+ seek: adminProcedure
3975
+ .input(mediaPlayerCapability.methods.seek.input.loose())
3976
+ .output(mediaPlayerCapability.methods.seek.output)
3977
+ .mutation(async ({ input, ctx }) => {
3978
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3979
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3980
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3981
+ return p.seek(methodInput as any)
3982
+ }),
3983
+ setVolume: adminProcedure
3984
+ .input(mediaPlayerCapability.methods.setVolume.input.loose())
3985
+ .output(mediaPlayerCapability.methods.setVolume.output)
3986
+ .mutation(async ({ input, ctx }) => {
3987
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3988
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3989
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3990
+ return p.setVolume(methodInput as any)
3991
+ }),
3992
+ setMute: adminProcedure
3993
+ .input(mediaPlayerCapability.methods.setMute.input.loose())
3994
+ .output(mediaPlayerCapability.methods.setMute.output)
3995
+ .mutation(async ({ input, ctx }) => {
3996
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
3997
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
3998
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3999
+ return p.setMute(methodInput as any)
4000
+ }),
4001
+ setShuffle: adminProcedure
4002
+ .input(mediaPlayerCapability.methods.setShuffle.input.loose())
4003
+ .output(mediaPlayerCapability.methods.setShuffle.output)
4004
+ .mutation(async ({ input, ctx }) => {
4005
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4006
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
4007
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4008
+ return p.setShuffle(methodInput as any)
4009
+ }),
4010
+ setRepeat: adminProcedure
4011
+ .input(mediaPlayerCapability.methods.setRepeat.input.loose())
4012
+ .output(mediaPlayerCapability.methods.setRepeat.output)
4013
+ .mutation(async ({ input, ctx }) => {
4014
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4015
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
4016
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4017
+ return p.setRepeat(methodInput as any)
4018
+ }),
4019
+ selectSource: adminProcedure
4020
+ .input(mediaPlayerCapability.methods.selectSource.input.loose())
4021
+ .output(mediaPlayerCapability.methods.selectSource.output)
4022
+ .mutation(async ({ input, ctx }) => {
4023
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4024
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
4025
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4026
+ return p.selectSource(methodInput as any)
2541
4027
  }),
2542
- query: protectedProcedure
2543
- .input(logDestinationCapability.methods.query.input.loose())
2544
- .output(logDestinationCapability.methods.query.output)
2545
- .query(async ({ input, ctx }) => {
2546
- const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
2547
- const p = resolveProvider('log-destination', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
4028
+ playMedia: adminProcedure
4029
+ .input(mediaPlayerCapability.methods.playMedia.input.loose())
4030
+ .output(mediaPlayerCapability.methods.playMedia.output)
4031
+ .mutation(async ({ input, ctx }) => {
4032
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4033
+ const p = resolveProvider('media-player', nodeId, () => getProvider(ctx), createRemoteProxy)
2548
4034
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2549
- return p.query(methodInput as any)
4035
+ return p.playMedia(methodInput as any)
2550
4036
  }),
2551
4037
  })
2552
4038
  }
@@ -2976,6 +4462,15 @@ export function createCapRouter_nativeObjectDetection(
2976
4462
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
2977
4463
  return p.getStatus(methodInput as any)
2978
4464
  }),
4465
+ setEnabled: adminProcedure
4466
+ .input(nativeObjectDetectionCapability.methods.setEnabled.input.loose())
4467
+ .output(nativeObjectDetectionCapability.methods.setEnabled.output)
4468
+ .mutation(async ({ input, ctx }) => {
4469
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4470
+ const p = resolveProvider('native-object-detection', nodeId, () => getProvider(ctx), createRemoteProxy)
4471
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4472
+ return p.setEnabled(methodInput as any)
4473
+ }),
2979
4474
  })
2980
4475
  }
2981
4476
 
@@ -3207,6 +4702,66 @@ export function createCapRouter_notificationOutput(
3207
4702
  })
3208
4703
  }
3209
4704
 
4705
+ // ── notifier (singleton) ────────────────────────────────────────────
4706
+
4707
+ type NotifierProvider = InferProvider<typeof notifierCapability>
4708
+
4709
+ export function createCapRouter_notifier(
4710
+ getProvider: (ctx: TrpcContext) => NotifierProvider | null,
4711
+ createRemoteProxy?: (capName: string, nodeId: string) => NotifierProvider | null,
4712
+ ) {
4713
+ return trpcRouter({
4714
+ getStatus: protectedProcedure
4715
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
4716
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
4717
+ .query(async ({ input, ctx }) => {
4718
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4719
+ const p = resolveProvider('notifier', nodeId, () => getProvider(ctx), createRemoteProxy)
4720
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4721
+ return p.getStatus(methodInput as any)
4722
+ }),
4723
+ send: adminProcedure
4724
+ .input(notifierCapability.methods.send.input.loose())
4725
+ .output(notifierCapability.methods.send.output)
4726
+ .mutation(async ({ input, ctx }) => {
4727
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4728
+ const p = resolveProvider('notifier', nodeId, () => getProvider(ctx), createRemoteProxy)
4729
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4730
+ return p.send(methodInput as any)
4731
+ }),
4732
+ cancel: adminProcedure
4733
+ .input(notifierCapability.methods.cancel.input.loose())
4734
+ .output(notifierCapability.methods.cancel.output)
4735
+ .mutation(async ({ input, ctx }) => {
4736
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4737
+ const p = resolveProvider('notifier', nodeId, () => getProvider(ctx), createRemoteProxy)
4738
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4739
+ return p.cancel(methodInput as any)
4740
+ }),
4741
+ })
4742
+ }
4743
+
4744
+ // ── numeric-sensor (singleton) ──────────────────────────────────────
4745
+
4746
+ type NumericSensorProvider = InferProvider<typeof numericSensorCapability>
4747
+
4748
+ export function createCapRouter_numericSensor(
4749
+ getProvider: (ctx: TrpcContext) => NumericSensorProvider | null,
4750
+ createRemoteProxy?: (capName: string, nodeId: string) => NumericSensorProvider | null,
4751
+ ) {
4752
+ return trpcRouter({
4753
+ getStatus: protectedProcedure
4754
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
4755
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
4756
+ .query(async ({ input, ctx }) => {
4757
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4758
+ const p = resolveProvider('numeric-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
4759
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4760
+ return p.getStatus(methodInput as any)
4761
+ }),
4762
+ })
4763
+ }
4764
+
3210
4765
  // ── oauth-integration (collection) ───────────────────────────────────
3211
4766
 
3212
4767
  type OauthIntegrationProvider = InferProvider<typeof oauthIntegrationCapability>
@@ -3355,6 +4910,24 @@ export function createCapRouter_pipelineAnalytics(
3355
4910
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
3356
4911
  return p.getAudioEvents(methodInput as any)
3357
4912
  }),
4913
+ getEventDensity: protectedProcedure
4914
+ .input(pipelineAnalyticsCapability.methods.getEventDensity.input.loose())
4915
+ .output(pipelineAnalyticsCapability.methods.getEventDensity.output)
4916
+ .query(async ({ input, ctx }) => {
4917
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4918
+ const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy)
4919
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4920
+ return p.getEventDensity(methodInput as any)
4921
+ }),
4922
+ pruneEventsBefore: adminProcedure
4923
+ .input(pipelineAnalyticsCapability.methods.pruneEventsBefore.input.loose())
4924
+ .output(pipelineAnalyticsCapability.methods.pruneEventsBefore.output)
4925
+ .mutation(async ({ input, ctx }) => {
4926
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4927
+ const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy)
4928
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4929
+ return p.pruneEventsBefore(methodInput as any)
4930
+ }),
3358
4931
  getEventMedia: protectedProcedure
3359
4932
  .input(pipelineAnalyticsCapability.methods.getEventMedia.input.loose())
3360
4933
  .output(pipelineAnalyticsCapability.methods.getEventMedia.output)
@@ -4120,6 +5693,122 @@ export function createCapRouter_platformProbe(
4120
5693
  const p = resolveProvider('platform-probe', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
4121
5694
  return p.refreshHardwareEncoders()
4122
5695
  }),
5696
+ getHardwareDecodeAccels: protectedProcedure
5697
+ .input(z.object({ nodeId: z.string().optional() }).optional())
5698
+ .output(platformProbeCapability.methods.getHardwareDecodeAccels.output)
5699
+ .query(async ({ input, ctx }) => {
5700
+ const p = resolveProvider('platform-probe', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
5701
+ return p.getHardwareDecodeAccels()
5702
+ }),
5703
+ refreshHardwareDecodeAccels: adminProcedure
5704
+ .input(z.object({ nodeId: z.string().optional() }).optional())
5705
+ .output(platformProbeCapability.methods.refreshHardwareDecodeAccels.output)
5706
+ .mutation(async ({ input, ctx }) => {
5707
+ const p = resolveProvider('platform-probe', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
5708
+ return p.refreshHardwareDecodeAccels()
5709
+ }),
5710
+ })
5711
+ }
5712
+
5713
+ // ── power-meter (singleton) ─────────────────────────────────────────
5714
+
5715
+ type PowerMeterProvider = InferProvider<typeof powerMeterCapability>
5716
+
5717
+ export function createCapRouter_powerMeter(
5718
+ getProvider: (ctx: TrpcContext) => PowerMeterProvider | null,
5719
+ createRemoteProxy?: (capName: string, nodeId: string) => PowerMeterProvider | null,
5720
+ ) {
5721
+ return trpcRouter({
5722
+ getStatus: protectedProcedure
5723
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
5724
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
5725
+ .query(async ({ input, ctx }) => {
5726
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5727
+ const p = resolveProvider('power-meter', nodeId, () => getProvider(ctx), createRemoteProxy)
5728
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5729
+ return p.getStatus(methodInput as any)
5730
+ }),
5731
+ })
5732
+ }
5733
+
5734
+ // ── presence (singleton) ────────────────────────────────────────────
5735
+
5736
+ type PresenceProvider = InferProvider<typeof presenceCapability>
5737
+
5738
+ export function createCapRouter_presence(
5739
+ getProvider: (ctx: TrpcContext) => PresenceProvider | null,
5740
+ createRemoteProxy?: (capName: string, nodeId: string) => PresenceProvider | null,
5741
+ ) {
5742
+ return trpcRouter({
5743
+ getStatus: protectedProcedure
5744
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
5745
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
5746
+ .query(async ({ input, ctx }) => {
5747
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5748
+ const p = resolveProvider('presence', nodeId, () => getProvider(ctx), createRemoteProxy)
5749
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5750
+ return p.getStatus(methodInput as any)
5751
+ }),
5752
+ })
5753
+ }
5754
+
5755
+ // ── pressure-sensor (singleton) ─────────────────────────────────────
5756
+
5757
+ type PressureSensorProvider = InferProvider<typeof pressureSensorCapability>
5758
+
5759
+ export function createCapRouter_pressureSensor(
5760
+ getProvider: (ctx: TrpcContext) => PressureSensorProvider | null,
5761
+ createRemoteProxy?: (capName: string, nodeId: string) => PressureSensorProvider | null,
5762
+ ) {
5763
+ return trpcRouter({
5764
+ getStatus: protectedProcedure
5765
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
5766
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
5767
+ .query(async ({ input, ctx }) => {
5768
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5769
+ const p = resolveProvider('pressure-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
5770
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5771
+ return p.getStatus(methodInput as any)
5772
+ }),
5773
+ })
5774
+ }
5775
+
5776
+ // ── privacy-mask (singleton) ────────────────────────────────────────
5777
+
5778
+ type PrivacyMaskProvider = InferProvider<typeof privacyMaskCapability>
5779
+
5780
+ export function createCapRouter_privacyMask(
5781
+ getProvider: (ctx: TrpcContext) => PrivacyMaskProvider | null,
5782
+ createRemoteProxy?: (capName: string, nodeId: string) => PrivacyMaskProvider | null,
5783
+ ) {
5784
+ return trpcRouter({
5785
+ getStatus: protectedProcedure
5786
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
5787
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
5788
+ .query(async ({ input, ctx }) => {
5789
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5790
+ const p = resolveProvider('privacy-mask', nodeId, () => getProvider(ctx), createRemoteProxy)
5791
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5792
+ return p.getStatus(methodInput as any)
5793
+ }),
5794
+ getOptions: protectedProcedure
5795
+ .input(privacyMaskCapability.methods.getOptions.input.loose())
5796
+ .output(privacyMaskCapability.methods.getOptions.output)
5797
+ .query(async ({ input, ctx }) => {
5798
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5799
+ const p = resolveProvider('privacy-mask', nodeId, () => getProvider(ctx), createRemoteProxy)
5800
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5801
+ return p.getOptions(methodInput as any)
5802
+ }),
5803
+ setMask: adminProcedure
5804
+ .input(privacyMaskCapability.methods.setMask.input.loose())
5805
+ .output(privacyMaskCapability.methods.setMask.output)
5806
+ .mutation(async ({ input, ctx }) => {
5807
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
5808
+ const p = resolveProvider('privacy-mask', nodeId, () => getProvider(ctx), createRemoteProxy)
5809
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
5810
+ return p.setMask(methodInput as any)
5811
+ }),
4123
5812
  })
4124
5813
  }
4125
5814
 
@@ -4321,202 +6010,104 @@ export function createCapRouter_recording(
4321
6010
  createRemoteProxy?: (capName: string, nodeId: string) => RecordingProvider | null,
4322
6011
  ) {
4323
6012
  return trpcRouter({
4324
- getSegments: protectedProcedure
4325
- .input(recordingCapability.methods.getSegments.input.loose())
4326
- .output(recordingCapability.methods.getSegments.output)
6013
+ getStatus: protectedProcedure
6014
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
6015
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
4327
6016
  .query(async ({ input, ctx }) => {
4328
6017
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4329
6018
  const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4330
6019
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4331
- return p.getSegments(methodInput as any)
6020
+ return p.getStatus(methodInput as any)
4332
6021
  }),
4333
- getPlaybackUrl: protectedProcedure
4334
- .input(recordingCapability.methods.getPlaybackUrl.input.loose())
4335
- .output(recordingCapability.methods.getPlaybackUrl.output)
6022
+ getDeviceSettingsContribution: protectedProcedure
6023
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceSettingsContribution.input.loose())
6024
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceSettingsContribution.output)
4336
6025
  .query(async ({ input, ctx }) => {
4337
6026
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4338
6027
  const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4339
6028
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4340
- return p.getPlaybackUrl(methodInput as any)
6029
+ return p.getDeviceSettingsContribution(methodInput as any)
4341
6030
  }),
4342
- getThumbnailAt: protectedProcedure
4343
- .input(recordingCapability.methods.getThumbnailAt.input.loose())
4344
- .output(recordingCapability.methods.getThumbnailAt.output)
6031
+ getDeviceLiveContribution: protectedProcedure
6032
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceLiveContribution.input.loose())
6033
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.getDeviceLiveContribution.output)
4345
6034
  .query(async ({ input, ctx }) => {
4346
6035
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4347
6036
  const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4348
6037
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4349
- return p.getThumbnailAt(methodInput as any)
4350
- }),
4351
- })
4352
- }
4353
-
4354
- // ── recording-engine (singleton) ────────────────────────────────────
4355
-
4356
- type RecordingEngineProvider = InferProvider<typeof recordingEngineCapability>
4357
-
4358
- export function createCapRouter_recordingEngine(
4359
- getProvider: (ctx: TrpcContext) => RecordingEngineProvider | null,
4360
- createRemoteProxy?: (capName: string, nodeId: string) => RecordingEngineProvider | null,
4361
- ) {
4362
- return trpcRouter({
4363
- getStatus: protectedProcedure
4364
- .input(z.object({ nodeId: z.string().optional() }).optional())
4365
- .output(DEVICE_STATUS_METHOD.getStatus.output)
4366
- .query(async ({ input, ctx }) => {
4367
- const p = resolveProvider('recording-engine', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
4368
- return p.getStatus()
4369
- }),
4370
- enable: adminProcedure
4371
- .input(recordingEngineCapability.methods.enable.input.loose())
4372
- .output(recordingEngineCapability.methods.enable.output)
4373
- .mutation(async ({ input, ctx }) => {
4374
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4375
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4376
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4377
- return p.enable(methodInput as any)
4378
- }),
4379
- disable: adminProcedure
4380
- .input(recordingEngineCapability.methods.disable.input.loose())
4381
- .output(recordingEngineCapability.methods.disable.output)
4382
- .mutation(async ({ input, ctx }) => {
4383
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4384
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4385
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4386
- return p.disable(methodInput as any)
4387
- }),
4388
- getConfig: protectedProcedure
4389
- .input(recordingEngineCapability.methods.getConfig.input.loose())
4390
- .output(recordingEngineCapability.methods.getConfig.output)
4391
- .query(async ({ input, ctx }) => {
4392
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4393
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4394
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4395
- return p.getConfig(methodInput as any)
6038
+ return p.getDeviceLiveContribution(methodInput as any)
4396
6039
  }),
4397
- updateConfig: adminProcedure
4398
- .input(recordingEngineCapability.methods.updateConfig.input.loose())
4399
- .output(recordingEngineCapability.methods.updateConfig.output)
6040
+ applyDeviceSettingsPatch: adminProcedure
6041
+ .input(DEVICE_SETTINGS_CONTRIBUTION_METHODS.applyDeviceSettingsPatch.input.loose())
6042
+ .output(DEVICE_SETTINGS_CONTRIBUTION_METHODS.applyDeviceSettingsPatch.output)
4400
6043
  .mutation(async ({ input, ctx }) => {
4401
6044
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4402
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4403
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4404
- return p.updateConfig(methodInput as any)
4405
- }),
4406
- getPlaylist: protectedProcedure
4407
- .input(recordingEngineCapability.methods.getPlaylist.input.loose())
4408
- .output(recordingEngineCapability.methods.getPlaylist.output)
4409
- .query(async ({ input, ctx }) => {
4410
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4411
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4412
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4413
- return p.getPlaylist(methodInput as any)
4414
- }),
4415
- getThumbnail: protectedProcedure
4416
- .input(recordingEngineCapability.methods.getThumbnail.input.loose())
4417
- .output(recordingEngineCapability.methods.getThumbnail.output)
4418
- .query(async ({ input, ctx }) => {
4419
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4420
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4421
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4422
- return p.getThumbnail(methodInput as any)
4423
- }),
4424
- getSegments: protectedProcedure
4425
- .input(recordingEngineCapability.methods.getSegments.input.loose())
4426
- .output(recordingEngineCapability.methods.getSegments.output)
4427
- .query(async ({ input, ctx }) => {
4428
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4429
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6045
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4430
6046
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4431
- return p.getSegments(methodInput as any)
6047
+ return p.applyDeviceSettingsPatch(methodInput as any)
4432
6048
  }),
4433
- getAvailability: protectedProcedure
4434
- .input(recordingEngineCapability.methods.getAvailability.input.loose())
4435
- .output(recordingEngineCapability.methods.getAvailability.output)
6049
+ getAvailability: adminProcedure
6050
+ .input(recordingCapability.methods.getAvailability.input.loose())
6051
+ .output(recordingCapability.methods.getAvailability.output)
4436
6052
  .query(async ({ input, ctx }) => {
4437
6053
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4438
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6054
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4439
6055
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4440
6056
  return p.getAvailability(methodInput as any)
4441
6057
  }),
4442
- estimateStorage: protectedProcedure
4443
- .input(recordingEngineCapability.methods.estimateStorage.input.loose())
4444
- .output(recordingEngineCapability.methods.estimateStorage.output)
6058
+ getPlaybackManifest: adminProcedure
6059
+ .input(recordingCapability.methods.getPlaybackManifest.input.loose())
6060
+ .output(recordingCapability.methods.getPlaybackManifest.output)
4445
6061
  .query(async ({ input, ctx }) => {
4446
6062
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4447
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6063
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4448
6064
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4449
- return p.estimateStorage(methodInput as any)
4450
- }),
4451
- estimateGlobalStorage: protectedProcedure
4452
- .input(z.object({ nodeId: z.string().optional() }).optional())
4453
- .output(recordingEngineCapability.methods.estimateGlobalStorage.output)
4454
- .query(async ({ input, ctx }) => {
4455
- const p = resolveProvider('recording-engine', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
4456
- return p.estimateGlobalStorage()
6065
+ return p.getPlaybackManifest(methodInput as any)
4457
6066
  }),
4458
- getStorageUsage: protectedProcedure
4459
- .input(recordingEngineCapability.methods.getStorageUsage.input.loose())
4460
- .output(recordingEngineCapability.methods.getStorageUsage.output)
6067
+ getStorageUsage: adminProcedure
6068
+ .input(recordingCapability.methods.getStorageUsage.input.loose())
6069
+ .output(recordingCapability.methods.getStorageUsage.output)
4461
6070
  .query(async ({ input, ctx }) => {
4462
6071
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4463
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6072
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4464
6073
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4465
6074
  return p.getStorageUsage(methodInput as any)
4466
6075
  }),
4467
- setPolicy: adminProcedure
4468
- .input(recordingEngineCapability.methods.setPolicy.input.loose())
4469
- .output(recordingEngineCapability.methods.setPolicy.output)
4470
- .mutation(async ({ input, ctx }) => {
4471
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4472
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4473
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4474
- return p.setPolicy(methodInput as any)
4475
- }),
4476
- getPolicy: protectedProcedure
4477
- .input(recordingEngineCapability.methods.getPolicy.input.loose())
4478
- .output(recordingEngineCapability.methods.getPolicy.output)
4479
- .query(async ({ input, ctx }) => {
4480
- const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4481
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
4482
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4483
- return p.getPolicy(methodInput as any)
4484
- }),
4485
- getPolicyStatus: protectedProcedure
4486
- .input(recordingEngineCapability.methods.getPolicyStatus.input.loose())
4487
- .output(recordingEngineCapability.methods.getPolicyStatus.output)
6076
+ getDeviceConfig: adminProcedure
6077
+ .input(recordingCapability.methods.getDeviceConfig.input.loose())
6078
+ .output(recordingCapability.methods.getDeviceConfig.output)
4488
6079
  .query(async ({ input, ctx }) => {
4489
6080
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4490
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6081
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4491
6082
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4492
- return p.getPolicyStatus(methodInput as any)
6083
+ return p.getDeviceConfig(methodInput as any)
4493
6084
  }),
4494
- getRetentionConfig: protectedProcedure
4495
- .input(recordingEngineCapability.methods.getRetentionConfig.input.loose())
4496
- .output(recordingEngineCapability.methods.getRetentionConfig.output)
4497
- .query(async ({ input, ctx }) => {
6085
+ setDeviceConfig: adminProcedure
6086
+ .input(recordingCapability.methods.setDeviceConfig.input.loose())
6087
+ .output(recordingCapability.methods.setDeviceConfig.output)
6088
+ .mutation(async ({ input, ctx }) => {
4498
6089
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4499
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6090
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4500
6091
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4501
- return p.getRetentionConfig(methodInput as any)
6092
+ return p.setDeviceConfig(methodInput as any)
4502
6093
  }),
4503
- updateRetentionConfig: adminProcedure
4504
- .input(recordingEngineCapability.methods.updateRetentionConfig.input.loose())
4505
- .output(recordingEngineCapability.methods.updateRetentionConfig.output)
6094
+ rescanStorage: adminProcedure
6095
+ .input(recordingCapability.methods.rescanStorage.input.loose())
6096
+ .output(recordingCapability.methods.rescanStorage.output)
4506
6097
  .mutation(async ({ input, ctx }) => {
4507
6098
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4508
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6099
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4509
6100
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4510
- return p.updateRetentionConfig(methodInput as any)
6101
+ return p.rescanStorage(methodInput as any)
4511
6102
  }),
4512
- getMotionStats: protectedProcedure
4513
- .input(recordingEngineCapability.methods.getMotionStats.input.loose())
4514
- .output(recordingEngineCapability.methods.getMotionStats.output)
4515
- .query(async ({ input, ctx }) => {
6103
+ pruneFootage: adminProcedure
6104
+ .input(recordingCapability.methods.pruneFootage.input.loose())
6105
+ .output(recordingCapability.methods.pruneFootage.output)
6106
+ .mutation(async ({ input, ctx }) => {
4516
6107
  const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
4517
- const p = resolveProvider('recording-engine', nodeId, () => getProvider(ctx), createRemoteProxy)
6108
+ const p = resolveProvider('recording', nodeId, () => getProvider(ctx), createRemoteProxy)
4518
6109
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4519
- return p.getMotionStats(methodInput as any)
6110
+ return p.pruneFootage(methodInput as any)
4520
6111
  }),
4521
6112
  })
4522
6113
  }
@@ -4543,19 +6134,58 @@ export function createCapRouter_restreamer(
4543
6134
  .input(restreamerCapability.methods.unregisterDevice.input.loose())
4544
6135
  .output(restreamerCapability.methods.unregisterDevice.output)
4545
6136
  .mutation(async ({ input, ctx }) => {
4546
- const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
4547
- const p = resolveProvider('restreamer', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6137
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
6138
+ const p = resolveProvider('restreamer', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6140
+ return p.unregisterDevice(methodInput as any)
6141
+ }),
6142
+ getExposedResources: protectedProcedure
6143
+ .input(restreamerCapability.methods.getExposedResources.input.loose())
6144
+ .output(restreamerCapability.methods.getExposedResources.output)
6145
+ .query(async ({ input, ctx }) => {
6146
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
6147
+ const p = resolveProvider('restreamer', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6148
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6149
+ return p.getExposedResources(methodInput as any)
6150
+ }),
6151
+ })
6152
+ }
6153
+
6154
+ // ── script-runner (singleton) ───────────────────────────────────────
6155
+
6156
+ type ScriptRunnerProvider = InferProvider<typeof scriptRunnerCapability>
6157
+
6158
+ export function createCapRouter_scriptRunner(
6159
+ getProvider: (ctx: TrpcContext) => ScriptRunnerProvider | null,
6160
+ createRemoteProxy?: (capName: string, nodeId: string) => ScriptRunnerProvider | null,
6161
+ ) {
6162
+ return trpcRouter({
6163
+ getStatus: protectedProcedure
6164
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
6165
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
6166
+ .query(async ({ input, ctx }) => {
6167
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
6168
+ const p = resolveProvider('script-runner', nodeId, () => getProvider(ctx), createRemoteProxy)
6169
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6170
+ return p.getStatus(methodInput as any)
6171
+ }),
6172
+ run: adminProcedure
6173
+ .input(scriptRunnerCapability.methods.run.input.loose())
6174
+ .output(scriptRunnerCapability.methods.run.output)
6175
+ .mutation(async ({ input, ctx }) => {
6176
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
6177
+ const p = resolveProvider('script-runner', nodeId, () => getProvider(ctx), createRemoteProxy)
4548
6178
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4549
- return p.unregisterDevice(methodInput as any)
6179
+ return p.run(methodInput as any)
4550
6180
  }),
4551
- getExposedResources: protectedProcedure
4552
- .input(restreamerCapability.methods.getExposedResources.input.loose())
4553
- .output(restreamerCapability.methods.getExposedResources.output)
4554
- .query(async ({ input, ctx }) => {
4555
- const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
4556
- const p = resolveProvider('restreamer', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6181
+ stop: adminProcedure
6182
+ .input(scriptRunnerCapability.methods.stop.input.loose())
6183
+ .output(scriptRunnerCapability.methods.stop.output)
6184
+ .mutation(async ({ input, ctx }) => {
6185
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
6186
+ const p = resolveProvider('script-runner', nodeId, () => getProvider(ctx), createRemoteProxy)
4557
6187
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4558
- return p.getExposedResources(methodInput as any)
6188
+ return p.stop(methodInput as any)
4559
6189
  }),
4560
6190
  })
4561
6191
  }
@@ -4632,6 +6262,15 @@ export function createCapRouter_settingsStore(
4632
6262
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4633
6263
  return p.count(methodInput as any)
4634
6264
  }),
6265
+ histogram: protectedProcedure
6266
+ .input(settingsStoreCapability.methods.histogram.input.loose())
6267
+ .output(settingsStoreCapability.methods.histogram.output)
6268
+ .query(async ({ input, ctx }) => {
6269
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
6270
+ const p = resolveProvider('settings-store', nodeId, () => getProvider(ctx), createRemoteProxy)
6271
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6272
+ return p.histogram(methodInput as any)
6273
+ }),
4635
6274
  isEmpty: protectedProcedure
4636
6275
  .input(settingsStoreCapability.methods.isEmpty.input.loose())
4637
6276
  .output(settingsStoreCapability.methods.isEmpty.output)
@@ -4653,6 +6292,27 @@ export function createCapRouter_settingsStore(
4653
6292
  })
4654
6293
  }
4655
6294
 
6295
+ // ── smoke (singleton) ───────────────────────────────────────────────
6296
+
6297
+ type SmokeProvider = InferProvider<typeof smokeCapability>
6298
+
6299
+ export function createCapRouter_smoke(
6300
+ getProvider: (ctx: TrpcContext) => SmokeProvider | null,
6301
+ createRemoteProxy?: (capName: string, nodeId: string) => SmokeProvider | null,
6302
+ ) {
6303
+ return trpcRouter({
6304
+ getStatus: protectedProcedure
6305
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
6306
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
6307
+ .query(async ({ input, ctx }) => {
6308
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
6309
+ const p = resolveProvider('smoke', nodeId, () => getProvider(ctx), createRemoteProxy)
6310
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6311
+ return p.getStatus(methodInput as any)
6312
+ }),
6313
+ })
6314
+ }
6315
+
4656
6316
  // ── smtp-provider (collection) ───────────────────────────────────────
4657
6317
 
4658
6318
  type SmtpProviderProvider = InferProvider<typeof smtpProviderCapability>
@@ -4967,6 +6627,13 @@ export function createCapRouter_storage(
4967
6627
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
4968
6628
  return p.getDefaultLocation(methodInput as any)
4969
6629
  }),
6630
+ listLocationDeclarations: protectedProcedure
6631
+ .input(z.object({ nodeId: z.string().optional() }).optional())
6632
+ .output(storageCapability.methods.listLocationDeclarations.output)
6633
+ .query(async ({ input, ctx }) => {
6634
+ const p = resolveProvider('storage', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
6635
+ return p.listLocationDeclarations()
6636
+ }),
4970
6637
  upsertLocation: adminProcedure
4971
6638
  .input(storageCapability.methods.upsertLocation.input.loose())
4972
6639
  .output(storageCapability.methods.upsertLocation.output)
@@ -5013,6 +6680,36 @@ export function createCapRouter_storage(
5013
6680
  })
5014
6681
  }
5015
6682
 
6683
+ // ── storage-evictable (collection) ───────────────────────────────────
6684
+
6685
+ type StorageEvictableProvider = InferProvider<typeof storageEvictableCapability>
6686
+
6687
+ export function createCapRouter_storageEvictable(
6688
+ getProvider: (ctx: TrpcContext, addonId?: string) => StorageEvictableProvider | null,
6689
+ createRemoteProxy?: (capName: string, nodeId: string) => StorageEvictableProvider | null,
6690
+ ) {
6691
+ return trpcRouter({
6692
+ getEvictableUsage: protectedProcedure
6693
+ .input(storageEvictableCapability.methods.getEvictableUsage.input.loose())
6694
+ .output(storageEvictableCapability.methods.getEvictableUsage.output)
6695
+ .query(async ({ input, ctx }) => {
6696
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
6697
+ const p = resolveProvider('storage-evictable', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6698
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6699
+ return p.getEvictableUsage(methodInput as any)
6700
+ }),
6701
+ evict: protectedProcedure
6702
+ .input(storageEvictableCapability.methods.evict.input.loose())
6703
+ .output(storageEvictableCapability.methods.evict.output)
6704
+ .mutation(async ({ input, ctx }) => {
6705
+ const { nodeId, addonId, ...methodInput } = input as { nodeId?: string; addonId?: string } & Record<string, unknown>
6706
+ const p = resolveProvider('storage-evictable', nodeId, () => getProvider(ctx, addonId), createRemoteProxy)
6707
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6708
+ return p.evict(methodInput as any)
6709
+ }),
6710
+ })
6711
+ }
6712
+
5016
6713
  // ── storage-provider (collection) ────────────────────────────────────
5017
6714
 
5018
6715
  type StorageProviderProvider = InferProvider<typeof storageProviderCapability>
@@ -5443,6 +7140,27 @@ export function createCapRouter_streamBroker(
5443
7140
  })
5444
7141
  }
5445
7142
 
7143
+ // ── stream-catalog (singleton) ──────────────────────────────────────
7144
+
7145
+ type StreamCatalogProvider = InferProvider<typeof streamCatalogCapability>
7146
+
7147
+ export function createCapRouter_streamCatalog(
7148
+ getProvider: (ctx: TrpcContext) => StreamCatalogProvider | null,
7149
+ createRemoteProxy?: (capName: string, nodeId: string) => StreamCatalogProvider | null,
7150
+ ) {
7151
+ return trpcRouter({
7152
+ getCatalog: protectedProcedure
7153
+ .input(streamCatalogCapability.methods.getCatalog.input.loose())
7154
+ .output(streamCatalogCapability.methods.getCatalog.output)
7155
+ .query(async ({ input, ctx }) => {
7156
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7157
+ const p = resolveProvider('stream-catalog', nodeId, () => getProvider(ctx), createRemoteProxy)
7158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7159
+ return p.getCatalog(methodInput as any)
7160
+ }),
7161
+ })
7162
+ }
7163
+
5446
7164
  // ── stream-params (singleton) ───────────────────────────────────────
5447
7165
 
5448
7166
  type StreamParamsProvider = InferProvider<typeof streamParamsCapability>
@@ -5628,6 +7346,48 @@ export function createCapRouter_system(
5628
7346
  })
5629
7347
  }
5630
7348
 
7349
+ // ── tamper (singleton) ──────────────────────────────────────────────
7350
+
7351
+ type TamperProvider = InferProvider<typeof tamperCapability>
7352
+
7353
+ export function createCapRouter_tamper(
7354
+ getProvider: (ctx: TrpcContext) => TamperProvider | null,
7355
+ createRemoteProxy?: (capName: string, nodeId: string) => TamperProvider | null,
7356
+ ) {
7357
+ return trpcRouter({
7358
+ getStatus: protectedProcedure
7359
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7360
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7361
+ .query(async ({ input, ctx }) => {
7362
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7363
+ const p = resolveProvider('tamper', nodeId, () => getProvider(ctx), createRemoteProxy)
7364
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7365
+ return p.getStatus(methodInput as any)
7366
+ }),
7367
+ })
7368
+ }
7369
+
7370
+ // ── temperature-sensor (singleton) ──────────────────────────────────
7371
+
7372
+ type TemperatureSensorProvider = InferProvider<typeof temperatureSensorCapability>
7373
+
7374
+ export function createCapRouter_temperatureSensor(
7375
+ getProvider: (ctx: TrpcContext) => TemperatureSensorProvider | null,
7376
+ createRemoteProxy?: (capName: string, nodeId: string) => TemperatureSensorProvider | null,
7377
+ ) {
7378
+ return trpcRouter({
7379
+ getStatus: protectedProcedure
7380
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7381
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7382
+ .query(async ({ input, ctx }) => {
7383
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7384
+ const p = resolveProvider('temperature-sensor', nodeId, () => getProvider(ctx), createRemoteProxy)
7385
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7386
+ return p.getStatus(methodInput as any)
7387
+ }),
7388
+ })
7389
+ }
7390
+
5631
7391
  // ── toast (singleton) ───────────────────────────────────────────────
5632
7392
 
5633
7393
  type ToastProvider = InferProvider<typeof toastCapability>
@@ -5667,6 +7427,34 @@ export function createCapRouter_turnProvider(
5667
7427
  })
5668
7428
  }
5669
7429
 
7430
+ // ── update (singleton) ──────────────────────────────────────────────
7431
+
7432
+ type UpdateProvider = InferProvider<typeof updateCapability>
7433
+
7434
+ export function createCapRouter_update(
7435
+ getProvider: (ctx: TrpcContext) => UpdateProvider | null,
7436
+ createRemoteProxy?: (capName: string, nodeId: string) => UpdateProvider | null,
7437
+ ) {
7438
+ return trpcRouter({
7439
+ getStatus: protectedProcedure
7440
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7441
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7442
+ .query(async ({ input, ctx }) => {
7443
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7444
+ const p = resolveProvider('update', nodeId, () => getProvider(ctx), createRemoteProxy)
7445
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7446
+ return p.getStatus(methodInput as any)
7447
+ }),
7448
+ installUpdate: adminProcedure
7449
+ .input(z.object({ nodeId: z.string().optional() }).optional())
7450
+ .output(updateCapability.methods.installUpdate.output)
7451
+ .mutation(async ({ input, ctx }) => {
7452
+ const p = resolveProvider('update', input?.nodeId, () => getProvider(ctx), createRemoteProxy)
7453
+ return p.installUpdate()
7454
+ }),
7455
+ })
7456
+ }
7457
+
5670
7458
  // ── user-management (singleton) ─────────────────────────────────────
5671
7459
 
5672
7460
  type UserManagementProvider = InferProvider<typeof userManagementCapability>
@@ -5973,6 +7761,228 @@ export function createCapRouter_userPasskeys(
5973
7761
  })
5974
7762
  }
5975
7763
 
7764
+ // ── vacuum-control (singleton) ──────────────────────────────────────
7765
+
7766
+ type VacuumControlProvider = InferProvider<typeof vacuumControlCapability>
7767
+
7768
+ export function createCapRouter_vacuumControl(
7769
+ getProvider: (ctx: TrpcContext) => VacuumControlProvider | null,
7770
+ createRemoteProxy?: (capName: string, nodeId: string) => VacuumControlProvider | null,
7771
+ ) {
7772
+ return trpcRouter({
7773
+ getStatus: protectedProcedure
7774
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7775
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7776
+ .query(async ({ input, ctx }) => {
7777
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7778
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7779
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7780
+ return p.getStatus(methodInput as any)
7781
+ }),
7782
+ start: adminProcedure
7783
+ .input(vacuumControlCapability.methods.start.input.loose())
7784
+ .output(vacuumControlCapability.methods.start.output)
7785
+ .mutation(async ({ input, ctx }) => {
7786
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7787
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7788
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7789
+ return p.start(methodInput as any)
7790
+ }),
7791
+ pause: adminProcedure
7792
+ .input(vacuumControlCapability.methods.pause.input.loose())
7793
+ .output(vacuumControlCapability.methods.pause.output)
7794
+ .mutation(async ({ input, ctx }) => {
7795
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7796
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7797
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7798
+ return p.pause(methodInput as any)
7799
+ }),
7800
+ stop: adminProcedure
7801
+ .input(vacuumControlCapability.methods.stop.input.loose())
7802
+ .output(vacuumControlCapability.methods.stop.output)
7803
+ .mutation(async ({ input, ctx }) => {
7804
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7805
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7806
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7807
+ return p.stop(methodInput as any)
7808
+ }),
7809
+ returnToBase: adminProcedure
7810
+ .input(vacuumControlCapability.methods.returnToBase.input.loose())
7811
+ .output(vacuumControlCapability.methods.returnToBase.output)
7812
+ .mutation(async ({ input, ctx }) => {
7813
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7814
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7815
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7816
+ return p.returnToBase(methodInput as any)
7817
+ }),
7818
+ locate: adminProcedure
7819
+ .input(vacuumControlCapability.methods.locate.input.loose())
7820
+ .output(vacuumControlCapability.methods.locate.output)
7821
+ .mutation(async ({ input, ctx }) => {
7822
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7823
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7824
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7825
+ return p.locate(methodInput as any)
7826
+ }),
7827
+ setFanSpeed: adminProcedure
7828
+ .input(vacuumControlCapability.methods.setFanSpeed.input.loose())
7829
+ .output(vacuumControlCapability.methods.setFanSpeed.output)
7830
+ .mutation(async ({ input, ctx }) => {
7831
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7832
+ const p = resolveProvider('vacuum-control', nodeId, () => getProvider(ctx), createRemoteProxy)
7833
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7834
+ return p.setFanSpeed(methodInput as any)
7835
+ }),
7836
+ })
7837
+ }
7838
+
7839
+ // ── valve (singleton) ───────────────────────────────────────────────
7840
+
7841
+ type ValveProvider = InferProvider<typeof valveCapability>
7842
+
7843
+ export function createCapRouter_valve(
7844
+ getProvider: (ctx: TrpcContext) => ValveProvider | null,
7845
+ createRemoteProxy?: (capName: string, nodeId: string) => ValveProvider | null,
7846
+ ) {
7847
+ return trpcRouter({
7848
+ getStatus: protectedProcedure
7849
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7850
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7851
+ .query(async ({ input, ctx }) => {
7852
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7853
+ const p = resolveProvider('valve', nodeId, () => getProvider(ctx), createRemoteProxy)
7854
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7855
+ return p.getStatus(methodInput as any)
7856
+ }),
7857
+ open: adminProcedure
7858
+ .input(valveCapability.methods.open.input.loose())
7859
+ .output(valveCapability.methods.open.output)
7860
+ .mutation(async ({ input, ctx }) => {
7861
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7862
+ const p = resolveProvider('valve', nodeId, () => getProvider(ctx), createRemoteProxy)
7863
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7864
+ return p.open(methodInput as any)
7865
+ }),
7866
+ close: adminProcedure
7867
+ .input(valveCapability.methods.close.input.loose())
7868
+ .output(valveCapability.methods.close.output)
7869
+ .mutation(async ({ input, ctx }) => {
7870
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7871
+ const p = resolveProvider('valve', nodeId, () => getProvider(ctx), createRemoteProxy)
7872
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7873
+ return p.close(methodInput as any)
7874
+ }),
7875
+ stop: adminProcedure
7876
+ .input(valveCapability.methods.stop.input.loose())
7877
+ .output(valveCapability.methods.stop.output)
7878
+ .mutation(async ({ input, ctx }) => {
7879
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7880
+ const p = resolveProvider('valve', nodeId, () => getProvider(ctx), createRemoteProxy)
7881
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7882
+ return p.stop(methodInput as any)
7883
+ }),
7884
+ setPosition: adminProcedure
7885
+ .input(valveCapability.methods.setPosition.input.loose())
7886
+ .output(valveCapability.methods.setPosition.output)
7887
+ .mutation(async ({ input, ctx }) => {
7888
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7889
+ const p = resolveProvider('valve', nodeId, () => getProvider(ctx), createRemoteProxy)
7890
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7891
+ return p.setPosition(methodInput as any)
7892
+ }),
7893
+ })
7894
+ }
7895
+
7896
+ // ── vibration (singleton) ───────────────────────────────────────────
7897
+
7898
+ type VibrationProvider = InferProvider<typeof vibrationCapability>
7899
+
7900
+ export function createCapRouter_vibration(
7901
+ getProvider: (ctx: TrpcContext) => VibrationProvider | null,
7902
+ createRemoteProxy?: (capName: string, nodeId: string) => VibrationProvider | null,
7903
+ ) {
7904
+ return trpcRouter({
7905
+ getStatus: protectedProcedure
7906
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7907
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7908
+ .query(async ({ input, ctx }) => {
7909
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7910
+ const p = resolveProvider('vibration', nodeId, () => getProvider(ctx), createRemoteProxy)
7911
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7912
+ return p.getStatus(methodInput as any)
7913
+ }),
7914
+ })
7915
+ }
7916
+
7917
+ // ── water-heater (singleton) ────────────────────────────────────────
7918
+
7919
+ type WaterHeaterProvider = InferProvider<typeof waterHeaterCapability>
7920
+
7921
+ export function createCapRouter_waterHeater(
7922
+ getProvider: (ctx: TrpcContext) => WaterHeaterProvider | null,
7923
+ createRemoteProxy?: (capName: string, nodeId: string) => WaterHeaterProvider | null,
7924
+ ) {
7925
+ return trpcRouter({
7926
+ getStatus: protectedProcedure
7927
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7928
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7929
+ .query(async ({ input, ctx }) => {
7930
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7931
+ const p = resolveProvider('water-heater', nodeId, () => getProvider(ctx), createRemoteProxy)
7932
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7933
+ return p.getStatus(methodInput as any)
7934
+ }),
7935
+ setTargetTemp: adminProcedure
7936
+ .input(waterHeaterCapability.methods.setTargetTemp.input.loose())
7937
+ .output(waterHeaterCapability.methods.setTargetTemp.output)
7938
+ .mutation(async ({ input, ctx }) => {
7939
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7940
+ const p = resolveProvider('water-heater', nodeId, () => getProvider(ctx), createRemoteProxy)
7941
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7942
+ return p.setTargetTemp(methodInput as any)
7943
+ }),
7944
+ setOperationMode: adminProcedure
7945
+ .input(waterHeaterCapability.methods.setOperationMode.input.loose())
7946
+ .output(waterHeaterCapability.methods.setOperationMode.output)
7947
+ .mutation(async ({ input, ctx }) => {
7948
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7949
+ const p = resolveProvider('water-heater', nodeId, () => getProvider(ctx), createRemoteProxy)
7950
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7951
+ return p.setOperationMode(methodInput as any)
7952
+ }),
7953
+ setAway: adminProcedure
7954
+ .input(waterHeaterCapability.methods.setAway.input.loose())
7955
+ .output(waterHeaterCapability.methods.setAway.output)
7956
+ .mutation(async ({ input, ctx }) => {
7957
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7958
+ const p = resolveProvider('water-heater', nodeId, () => getProvider(ctx), createRemoteProxy)
7959
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7960
+ return p.setAway(methodInput as any)
7961
+ }),
7962
+ })
7963
+ }
7964
+
7965
+ // ── weather (singleton) ─────────────────────────────────────────────
7966
+
7967
+ type WeatherProvider = InferProvider<typeof weatherCapability>
7968
+
7969
+ export function createCapRouter_weather(
7970
+ getProvider: (ctx: TrpcContext) => WeatherProvider | null,
7971
+ createRemoteProxy?: (capName: string, nodeId: string) => WeatherProvider | null,
7972
+ ) {
7973
+ return trpcRouter({
7974
+ getStatus: protectedProcedure
7975
+ .input(DEVICE_STATUS_METHOD.getStatus.input.loose())
7976
+ .output(DEVICE_STATUS_METHOD.getStatus.output)
7977
+ .query(async ({ input, ctx }) => {
7978
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
7979
+ const p = resolveProvider('weather', nodeId, () => getProvider(ctx), createRemoteProxy)
7980
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
7981
+ return p.getStatus(methodInput as any)
7982
+ }),
7983
+ })
7984
+ }
7985
+
5976
7986
  // ── webrtc (collection) ──────────────────────────────────────────────
5977
7987
 
5978
7988
  type WebrtcProvider = InferProvider<typeof webrtcCapability>
@@ -6102,6 +8112,24 @@ export function createCapRouter_webrtcSession(
6102
8112
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6103
8113
  return p.handleAnswer(methodInput as any)
6104
8114
  }),
8115
+ addIceCandidate: protectedProcedure
8116
+ .input(webrtcSessionCapability.methods.addIceCandidate.input.loose())
8117
+ .output(webrtcSessionCapability.methods.addIceCandidate.output)
8118
+ .mutation(async ({ input, ctx }) => {
8119
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
8120
+ const p = resolveProvider('webrtc-session', nodeId, () => getProvider(ctx), createRemoteProxy)
8121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
8122
+ return p.addIceCandidate(methodInput as any)
8123
+ }),
8124
+ getIceCandidates: protectedProcedure
8125
+ .input(webrtcSessionCapability.methods.getIceCandidates.input.loose())
8126
+ .output(webrtcSessionCapability.methods.getIceCandidates.output)
8127
+ .query(async ({ input, ctx }) => {
8128
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
8129
+ const p = resolveProvider('webrtc-session', nodeId, () => getProvider(ctx), createRemoteProxy)
8130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
8131
+ return p.getIceCandidates(methodInput as any)
8132
+ }),
6105
8133
  closeSession: protectedProcedure
6106
8134
  .input(webrtcSessionCapability.methods.closeSession.input.loose())
6107
8135
  .output(webrtcSessionCapability.methods.closeSession.output)
@@ -6120,6 +8148,15 @@ export function createCapRouter_webrtcSession(
6120
8148
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
6121
8149
  return p.hasAdaptiveBitrate(methodInput as any)
6122
8150
  }),
8151
+ getSessionState: protectedProcedure
8152
+ .input(webrtcSessionCapability.methods.getSessionState.input.loose())
8153
+ .output(webrtcSessionCapability.methods.getSessionState.output)
8154
+ .query(async ({ input, ctx }) => {
8155
+ const { nodeId, ...methodInput } = input as { nodeId?: string } & Record<string, unknown>
8156
+ const p = resolveProvider('webrtc-session', nodeId, () => getProvider(ctx), createRemoteProxy)
8157
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
8158
+ return p.getSessionState(methodInput as any)
8159
+ }),
6123
8160
  })
6124
8161
  }
6125
8162
 
@@ -6263,19 +8300,36 @@ export interface GeneratedCapabilityRouterMap {
6263
8300
  readonly addons: ReturnType<typeof createCapRouter_addons>
6264
8301
  readonly adminUi: ReturnType<typeof createCapRouter_adminUi>
6265
8302
  readonly advancedNotifier: ReturnType<typeof createCapRouter_advancedNotifier>
8303
+ readonly airQualitySensor: ReturnType<typeof createCapRouter_airQualitySensor>
8304
+ readonly alarmPanel: ReturnType<typeof createCapRouter_alarmPanel>
6266
8305
  readonly alerts: ReturnType<typeof createCapRouter_alerts>
8306
+ readonly ambientLightSensor: ReturnType<typeof createCapRouter_ambientLightSensor>
6267
8307
  readonly audioAnalysis: ReturnType<typeof createCapRouter_audioAnalysis>
6268
8308
  readonly audioAnalyzer: ReturnType<typeof createCapRouter_audioAnalyzer>
6269
8309
  readonly audioCodec: ReturnType<typeof createCapRouter_audioCodec>
6270
8310
  readonly audioMetrics: ReturnType<typeof createCapRouter_audioMetrics>
6271
8311
  readonly authProvider: ReturnType<typeof createCapRouter_authProvider>
8312
+ readonly automationControl: ReturnType<typeof createCapRouter_automationControl>
6272
8313
  readonly backup: ReturnType<typeof createCapRouter_backup>
6273
8314
  readonly battery: ReturnType<typeof createCapRouter_battery>
8315
+ readonly binary: ReturnType<typeof createCapRouter_binary>
6274
8316
  readonly brightness: ReturnType<typeof createCapRouter_brightness>
8317
+ readonly broker: ReturnType<typeof createCapRouter_broker>
8318
+ readonly button: ReturnType<typeof createCapRouter_button>
6275
8319
  readonly cameraCredentials: ReturnType<typeof createCapRouter_cameraCredentials>
8320
+ readonly cameraPipelineConfig: ReturnType<typeof createCapRouter_cameraPipelineConfig>
6276
8321
  readonly cameraStreams: ReturnType<typeof createCapRouter_cameraStreams>
8322
+ readonly carbonMonoxide: ReturnType<typeof createCapRouter_carbonMonoxide>
8323
+ readonly climateControl: ReturnType<typeof createCapRouter_climateControl>
8324
+ readonly color: ReturnType<typeof createCapRouter_color>
8325
+ readonly connectivity: ReturnType<typeof createCapRouter_connectivity>
8326
+ readonly consumables: ReturnType<typeof createCapRouter_consumables>
8327
+ readonly contact: ReturnType<typeof createCapRouter_contact>
8328
+ readonly control: ReturnType<typeof createCapRouter_control>
8329
+ readonly cover: ReturnType<typeof createCapRouter_cover>
6277
8330
  readonly decoder: ReturnType<typeof createCapRouter_decoder>
6278
8331
  readonly detectionPipeline: ReturnType<typeof createCapRouter_detectionPipeline>
8332
+ readonly deviceAdoption: ReturnType<typeof createCapRouter_deviceAdoption>
6279
8333
  readonly deviceDiscovery: ReturnType<typeof createCapRouter_deviceDiscovery>
6280
8334
  readonly deviceExport: ReturnType<typeof createCapRouter_deviceExport>
6281
8335
  readonly deviceManager: ReturnType<typeof createCapRouter_deviceManager>
@@ -6285,12 +8339,23 @@ export interface GeneratedCapabilityRouterMap {
6285
8339
  readonly deviceStatus: ReturnType<typeof createCapRouter_deviceStatus>
6286
8340
  readonly doorbell: ReturnType<typeof createCapRouter_doorbell>
6287
8341
  readonly embeddingEncoder: ReturnType<typeof createCapRouter_embeddingEncoder>
8342
+ readonly enumSensor: ReturnType<typeof createCapRouter_enumSensor>
8343
+ readonly eventEmitter: ReturnType<typeof createCapRouter_eventEmitter>
6288
8344
  readonly events: ReturnType<typeof createCapRouter_events>
8345
+ readonly fanControl: ReturnType<typeof createCapRouter_fanControl>
6289
8346
  readonly featureProbe: ReturnType<typeof createCapRouter_featureProbe>
8347
+ readonly flood: ReturnType<typeof createCapRouter_flood>
8348
+ readonly gas: ReturnType<typeof createCapRouter_gas>
8349
+ readonly humidifier: ReturnType<typeof createCapRouter_humidifier>
8350
+ readonly humiditySensor: ReturnType<typeof createCapRouter_humiditySensor>
8351
+ readonly image: ReturnType<typeof createCapRouter_image>
6290
8352
  readonly integrations: ReturnType<typeof createCapRouter_integrations>
6291
8353
  readonly intercom: ReturnType<typeof createCapRouter_intercom>
8354
+ readonly lawnMowerControl: ReturnType<typeof createCapRouter_lawnMowerControl>
6292
8355
  readonly localNetwork: ReturnType<typeof createCapRouter_localNetwork>
8356
+ readonly lockControl: ReturnType<typeof createCapRouter_lockControl>
6293
8357
  readonly logDestination: ReturnType<typeof createCapRouter_logDestination>
8358
+ readonly mediaPlayer: ReturnType<typeof createCapRouter_mediaPlayer>
6294
8359
  readonly meshNetwork: ReturnType<typeof createCapRouter_meshNetwork>
6295
8360
  readonly metricsProvider: ReturnType<typeof createCapRouter_metricsProvider>
6296
8361
  readonly motion: ReturnType<typeof createCapRouter_motion>
@@ -6303,6 +8368,8 @@ export interface GeneratedCapabilityRouterMap {
6303
8368
  readonly networkQuality: ReturnType<typeof createCapRouter_networkQuality>
6304
8369
  readonly nodes: ReturnType<typeof createCapRouter_nodes>
6305
8370
  readonly notificationOutput: ReturnType<typeof createCapRouter_notificationOutput>
8371
+ readonly notifier: ReturnType<typeof createCapRouter_notifier>
8372
+ readonly numericSensor: ReturnType<typeof createCapRouter_numericSensor>
6306
8373
  readonly oauthIntegration: ReturnType<typeof createCapRouter_oauthIntegration>
6307
8374
  readonly osd: ReturnType<typeof createCapRouter_osd>
6308
8375
  readonly pipelineAnalytics: ReturnType<typeof createCapRouter_pipelineAnalytics>
@@ -6310,28 +8377,43 @@ export interface GeneratedCapabilityRouterMap {
6310
8377
  readonly pipelineOrchestrator: ReturnType<typeof createCapRouter_pipelineOrchestrator>
6311
8378
  readonly pipelineRunner: ReturnType<typeof createCapRouter_pipelineRunner>
6312
8379
  readonly platformProbe: ReturnType<typeof createCapRouter_platformProbe>
8380
+ readonly powerMeter: ReturnType<typeof createCapRouter_powerMeter>
8381
+ readonly presence: ReturnType<typeof createCapRouter_presence>
8382
+ readonly pressureSensor: ReturnType<typeof createCapRouter_pressureSensor>
8383
+ readonly privacyMask: ReturnType<typeof createCapRouter_privacyMask>
6313
8384
  readonly ptz: ReturnType<typeof createCapRouter_ptz>
6314
8385
  readonly ptzAutotrack: ReturnType<typeof createCapRouter_ptzAutotrack>
6315
8386
  readonly reboot: ReturnType<typeof createCapRouter_reboot>
6316
8387
  readonly recording: ReturnType<typeof createCapRouter_recording>
6317
- readonly recordingEngine: ReturnType<typeof createCapRouter_recordingEngine>
6318
8388
  readonly restreamer: ReturnType<typeof createCapRouter_restreamer>
8389
+ readonly scriptRunner: ReturnType<typeof createCapRouter_scriptRunner>
6319
8390
  readonly settingsStore: ReturnType<typeof createCapRouter_settingsStore>
8391
+ readonly smoke: ReturnType<typeof createCapRouter_smoke>
6320
8392
  readonly smtpProvider: ReturnType<typeof createCapRouter_smtpProvider>
6321
8393
  readonly snapshot: ReturnType<typeof createCapRouter_snapshot>
6322
8394
  readonly snapshotProvider: ReturnType<typeof createCapRouter_snapshotProvider>
6323
8395
  readonly ssoBridge: ReturnType<typeof createCapRouter_ssoBridge>
6324
8396
  readonly storage: ReturnType<typeof createCapRouter_storage>
8397
+ readonly storageEvictable: ReturnType<typeof createCapRouter_storageEvictable>
6325
8398
  readonly storageProvider: ReturnType<typeof createCapRouter_storageProvider>
6326
8399
  readonly streamBroker: ReturnType<typeof createCapRouter_streamBroker>
8400
+ readonly streamCatalog: ReturnType<typeof createCapRouter_streamCatalog>
6327
8401
  readonly streamParams: ReturnType<typeof createCapRouter_streamParams>
6328
8402
  readonly streamingEngine: ReturnType<typeof createCapRouter_streamingEngine>
6329
8403
  readonly switch: ReturnType<typeof createCapRouter_switch>
6330
8404
  readonly system: ReturnType<typeof createCapRouter_system>
8405
+ readonly tamper: ReturnType<typeof createCapRouter_tamper>
8406
+ readonly temperatureSensor: ReturnType<typeof createCapRouter_temperatureSensor>
6331
8407
  readonly toast: ReturnType<typeof createCapRouter_toast>
6332
8408
  readonly turnProvider: ReturnType<typeof createCapRouter_turnProvider>
8409
+ readonly update: ReturnType<typeof createCapRouter_update>
6333
8410
  readonly userManagement: ReturnType<typeof createCapRouter_userManagement>
6334
8411
  readonly userPasskeys: ReturnType<typeof createCapRouter_userPasskeys>
8412
+ readonly vacuumControl: ReturnType<typeof createCapRouter_vacuumControl>
8413
+ readonly valve: ReturnType<typeof createCapRouter_valve>
8414
+ readonly vibration: ReturnType<typeof createCapRouter_vibration>
8415
+ readonly waterHeater: ReturnType<typeof createCapRouter_waterHeater>
8416
+ readonly weather: ReturnType<typeof createCapRouter_weather>
6335
8417
  readonly webrtc: ReturnType<typeof createCapRouter_webrtc>
6336
8418
  readonly webrtcSession: ReturnType<typeof createCapRouter_webrtcSession>
6337
8419
  readonly zoneAnalytics: ReturnType<typeof createCapRouter_zoneAnalytics>