@camstack/types 1.2.260 → 1.2.261

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 (48) hide show
  1. package/dist/addon/base-addon.d.ts +9 -1
  2. package/dist/addon.js +4 -6
  3. package/dist/addon.mjs +4 -6
  4. package/dist/capabilities/capability-definition.d.ts +9 -0
  5. package/dist/capabilities/custom-model-registry.cap.d.ts +18 -0
  6. package/dist/capabilities/device-extension.cap.d.ts +370 -0
  7. package/dist/capabilities/device-manager.cap.d.ts +45 -5
  8. package/dist/capabilities/doorbell.cap.d.ts +41 -0
  9. package/dist/capabilities/embedding-encoder.cap.d.ts +175 -0
  10. package/dist/capabilities/index.d.ts +15 -12
  11. package/dist/capabilities/llm-runtime.cap.d.ts +4 -4
  12. package/dist/capabilities/llm-shared.d.ts +6 -6
  13. package/dist/capabilities/llm.cap.d.ts +6 -6
  14. package/dist/capabilities/model-convert.cap.d.ts +9 -0
  15. package/dist/capabilities/model-distributor.cap.d.ts +18 -0
  16. package/dist/capabilities/notification-rules.cap.d.ts +32 -14
  17. package/dist/capabilities/osd-manager.cap.d.ts +6 -6
  18. package/dist/capabilities/pipeline-analytics.cap.d.ts +80 -2
  19. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +62 -1
  20. package/dist/capabilities/pipeline-runner.cap.d.ts +24 -0
  21. package/dist/capabilities/vector-store.cap.d.ts +14 -0
  22. package/dist/device-extension/index.d.ts +3 -0
  23. package/dist/device-extension/slot-descriptor.d.ts +62 -0
  24. package/dist/device-extension/slot-provider.d.ts +68 -0
  25. package/dist/generated/addon-api.d.ts +50 -0
  26. package/dist/generated/capability-router-map.d.ts +5 -2
  27. package/dist/generated/collection-array-methods.d.ts +1 -1
  28. package/dist/generated/device-proxy.d.ts +7 -7
  29. package/dist/generated/device-scoped-caps.d.ts +1 -1
  30. package/dist/generated/extension-slots.d.ts +39 -0
  31. package/dist/generated/method-access-map.d.ts +1 -1
  32. package/dist/generated/method-device-selectors.d.ts +1 -1
  33. package/dist/generated/system-proxy.d.ts +4 -2
  34. package/dist/index.d.ts +4 -1
  35. package/dist/index.js +1439 -475
  36. package/dist/index.mjs +1379 -476
  37. package/dist/interfaces/addon.d.ts +41 -0
  38. package/dist/interfaces/event-bus.d.ts +10 -0
  39. package/dist/node.d.ts +1 -0
  40. package/dist/node.js +73 -7
  41. package/dist/node.mjs +73 -8
  42. package/dist/pipeline/cluster-model-scope.d.ts +59 -3
  43. package/dist/{sleep-BaRu0bS5.mjs → sleep-BXv0ZcRa.mjs} +49 -33
  44. package/dist/{sleep-BDYxE1ax.js → sleep-QxyLiUId.js} +54 -32
  45. package/dist/storage/atomic-write.d.ts +25 -0
  46. package/dist/types/clip-model.d.ts +64 -0
  47. package/dist/types/models.d.ts +18 -0
  48. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import type { ZodType } from 'zod';
2
- import type { AddonContext, AddonInitResult, CapabilitiesAccess, ProviderRegistration } from '../interfaces/addon.js';
2
+ import type { AddonContext, AddonInitResult, CapabilitiesAccess, ProviderRegistration, StoredKeyRead } from '../interfaces/addon.js';
3
3
  import type { ConfigField, ConfigSection, ConfigUISchema, ConfigUISchemaWithValues } from '../interfaces/config-ui.js';
4
4
  import { type DurableState } from './durable-state.js';
5
5
  export type { CapabilitiesAccess };
@@ -261,6 +261,14 @@ export declare abstract class BaseAddon<TConfig extends object = Record<string,
261
261
  * `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
262
262
  */
263
263
  protected resolveGlobalStore(nodeId?: string, cap?: string): Promise<Record<string, unknown>>;
264
+ /**
265
+ * Whether ONE global key of this addon's store was written, read three-way
266
+ * (D651). For a question a hydrated view cannot answer: `getGlobalSettings`
267
+ * reports `value ?? default`, so "the operator chose the default" and "nobody
268
+ * chose" look the same, and a failed read looks like both. A `perNode` key is
269
+ * not supported here: its stored name is scoped.
270
+ */
271
+ protected readStoredGlobalKey(key: string): Promise<StoredKeyRead>;
264
272
  updateGlobalSettings(patch: Partial<TConfig>, nodeId?: string): Promise<void>;
265
273
  /**
266
274
  * The set of field keys the global settings schema declares `perNode: true`
package/dist/addon.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-BDYxE1ax.js");
2
+ const require_sleep = require("./sleep-QxyLiUId.js");
3
3
  const require_event_category = require("./event-category-BVfsrBYA.js");
4
4
  const require_err_msg = require("./err-msg-COpsHMw2.js");
5
5
  //#region src/generated/cap-input-defaults.ts
@@ -150,10 +150,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
150
150
  "listRecentTracks": { "limit": 200 },
151
151
  "listSummaries": { "limit": 50 },
152
152
  "reclaimDebugMedia": { "mode": "report" },
153
- "searchObjectEvents": {
154
- "limit": 50,
155
- "minScore": .2
156
- }
153
+ "searchObjectEvents": { "limit": 50 }
157
154
  },
158
155
  "pipeline-runner": {
159
156
  "attachCamera": {
@@ -307,7 +304,7 @@ function materialise(defaults) {
307
304
  * barrel (`ALL_CAPABILITY_DEFINITIONS`), which would cost ~144MB RSS per
308
305
  * forked runner. See docs/decisions/adr-0028.md.
309
306
  *
310
- * Coverage: 23 collection caps, 37 array methods.
307
+ * Coverage: 24 collection caps, 39 array methods.
311
308
  */
312
309
  var COLLECTION_ARRAY_METHODS = Object.freeze({
313
310
  "addon-pages-source": ["listPages"],
@@ -317,6 +314,7 @@ var COLLECTION_ARRAY_METHODS = Object.freeze({
317
314
  "custom-model-registry": ["listModels"],
318
315
  "data-store-provider": ["histogram", "query"],
319
316
  "device-export": ["listExposedDevices", "listSupportedDeviceKinds"],
317
+ "device-extension": ["listSlots", "listSources"],
320
318
  "device-provider": ["discoverDevices", "getDevices"],
321
319
  "failure-contribution": ["list"],
322
320
  "llm": [
package/dist/addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as DeviceType, At as DATAPLANE_SECRET_HEADER, Dt as PEER_BYTES_STALL_MS, Et as PEER_BYTES_MAX_OUTSTANDING, G as readNodePin, J as ReadinessTimeoutError, L as expandCapMethods, Lt as emitReadiness, Mt as DisposerChain, Nt as BaseAddon, Ot as PEER_BYTES_TICKET_TTL_MS, Pt as normalizeAddonInitResult, S as DEVICE_CHILDREN_BATCH_MAX, T as describeCustomActions, Tt as PEER_BYTES_CHUNK_BYTES, W as nodePin, Z as scopeKey, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, j as adminUiCapability, m as createDeviceProxy, p as isDeviceScopedCap, q as ReadinessRegistry, s as asString, t as sleep, u as parseJsonUnknown, x as viewerUiCapability } from "./sleep-BaRu0bS5.mjs";
1
+ import { A as DeviceType, At as DATAPLANE_SECRET_HEADER, Dt as PEER_BYTES_STALL_MS, Et as PEER_BYTES_MAX_OUTSTANDING, G as readNodePin, J as ReadinessTimeoutError, L as expandCapMethods, Mt as DisposerChain, Nt as BaseAddon, Ot as PEER_BYTES_TICKET_TTL_MS, Pt as normalizeAddonInitResult, Rt as emitReadiness, S as DEVICE_CHILDREN_BATCH_MAX, T as describeCustomActions, Tt as PEER_BYTES_CHUNK_BYTES, W as nodePin, Z as scopeKey, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, j as adminUiCapability, m as createDeviceProxy, p as isDeviceScopedCap, q as ReadinessRegistry, s as asString, t as sleep, u as parseJsonUnknown, x as viewerUiCapability } from "./sleep-BXv0ZcRa.mjs";
2
2
  import { t as EventCategory } from "./event-category-BVDXG4tB.mjs";
3
3
  import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
4
4
  //#region src/generated/cap-input-defaults.ts
@@ -149,10 +149,7 @@ var CAP_INPUT_DEFAULTS = Object.freeze({
149
149
  "listRecentTracks": { "limit": 200 },
150
150
  "listSummaries": { "limit": 50 },
151
151
  "reclaimDebugMedia": { "mode": "report" },
152
- "searchObjectEvents": {
153
- "limit": 50,
154
- "minScore": .2
155
- }
152
+ "searchObjectEvents": { "limit": 50 }
156
153
  },
157
154
  "pipeline-runner": {
158
155
  "attachCamera": {
@@ -306,7 +303,7 @@ function materialise(defaults) {
306
303
  * barrel (`ALL_CAPABILITY_DEFINITIONS`), which would cost ~144MB RSS per
307
304
  * forked runner. See docs/decisions/adr-0028.md.
308
305
  *
309
- * Coverage: 23 collection caps, 37 array methods.
306
+ * Coverage: 24 collection caps, 39 array methods.
310
307
  */
311
308
  var COLLECTION_ARRAY_METHODS = Object.freeze({
312
309
  "addon-pages-source": ["listPages"],
@@ -316,6 +313,7 @@ var COLLECTION_ARRAY_METHODS = Object.freeze({
316
313
  "custom-model-registry": ["listModels"],
317
314
  "data-store-provider": ["histogram", "query"],
318
315
  "device-export": ["listExposedDevices", "listSupportedDeviceKinds"],
316
+ "device-extension": ["listSlots", "listSources"],
319
317
  "device-provider": ["discoverDevices", "getDevices"],
320
318
  "failure-contribution": ["list"],
321
319
  "llm": [
@@ -14,6 +14,7 @@
14
14
  import { z } from 'zod';
15
15
  import { DeviceType } from '../device/device-type.js';
16
16
  import type { ConfigUISchemaWithValues } from '../interfaces/config-ui.js';
17
+ import type { ExtensionSlotDescriptor } from '../device-extension/slot-descriptor.js';
17
18
  /**
18
19
  * tRPC procedure kind.
19
20
  * - 'query': read-only, no side effects
@@ -503,6 +504,14 @@ export interface CapabilityDefinition<TName extends string = string, TMethods ex
503
504
  readonly deviceConfig?: DeviceConfigSpec;
504
505
  /** For `scope: 'device'` caps — allowed device types. Omit → applies to every type. */
505
506
  readonly deviceTypes?: readonly DeviceType[];
507
+ /**
508
+ * Extension slots this capability OWNS (D648): the ways a device of this
509
+ * kind can be extended by other devices, served by this cap's owner over
510
+ * the store it already has. Folded by `npm run codegen` into
511
+ * `generated/extension-slots.ts` and listed by `device-extension`.
512
+ * Behavioural metadata, so it lives here and only here (D4).
513
+ */
514
+ readonly extensionSlots?: readonly ExtensionSlotDescriptor[];
506
515
  /**
507
516
  * When `true`, every provider of this capability MUST implement the
508
517
  * device-settings contribution surface — three extra methods appearing
@@ -147,6 +147,15 @@ export declare const CustomModelDescriptorSchema: z.ZodObject<{
147
147
  }>>;
148
148
  preserveOriginal: z.ZodBoolean;
149
149
  }, z.core.$strip>>;
150
+ clip: z.ZodOptional<z.ZodObject<{
151
+ textModelId: z.ZodString;
152
+ embeddingDim: z.ZodNumber;
153
+ vectorIndex: z.ZodString;
154
+ tokenizerFile: z.ZodString;
155
+ contextLength: z.ZodNumber;
156
+ padId: z.ZodNumber;
157
+ searchMinScore: z.ZodNumber;
158
+ }, z.core.$strip>>;
150
159
  }, z.core.$strip>;
151
160
  }, z.core.$strip>;
152
161
  export type CustomModelDescriptor = z.infer<typeof CustomModelDescriptorSchema>;
@@ -295,6 +304,15 @@ export declare const customModelRegistryCapability: {
295
304
  }>>;
296
305
  preserveOriginal: z.ZodBoolean;
297
306
  }, z.core.$strip>>;
307
+ clip: z.ZodOptional<z.ZodObject<{
308
+ textModelId: z.ZodString;
309
+ embeddingDim: z.ZodNumber;
310
+ vectorIndex: z.ZodString;
311
+ tokenizerFile: z.ZodString;
312
+ contextLength: z.ZodNumber;
313
+ padId: z.ZodNumber;
314
+ searchMinScore: z.ZodNumber;
315
+ }, z.core.$strip>>;
298
316
  }, z.core.$strip>;
299
317
  }, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
300
318
  };
@@ -0,0 +1,370 @@
1
+ /**
2
+ * `device-extension` — ONE place to see and author what a device is extended
3
+ * with by OTHER devices (D648).
4
+ *
5
+ * **A contract, not a store.** Every slot (`linked-devices`,
6
+ * `doorbell-source`, later `consumables-graft`) is declared by the cap that
7
+ * owns the function (`extensionSlots` in its `*.cap.ts`, D4) and SERVED by the
8
+ * addon that already owns its store, over that store and its existing write
9
+ * path. This cap persists nothing and has no config method (guarded by
10
+ * `scripts/check-extension-slots.ts`): D62 applied to the whole feature, and
11
+ * D3 — no shadow registry.
12
+ *
13
+ * **Shape.** A device-scoped wrapper COLLECTION, the D554 shape `videoclips`
14
+ * uses: `resolveCapMount` gives it the `device-scoped` mount and
15
+ * `requireDeviceCollection` dispatches it. Its providers are the slot owners
16
+ * (device-manager, virtual-doorbell, …), and a device's sources are its
17
+ * bindings (step 0 of `getBindings`, derived, persisted nowhere).
18
+ *
19
+ * - `listSources` — one row per provider, the D554 source-listing convention
20
+ * that lets a scalar call be routed by the prefix of its `slotRef`.
21
+ * - `listSlots` — fan-out, concatenated. A provider that throws becomes ONE
22
+ * `unreachable` row naming it, never an absence (D554.4, D315): "no
23
+ * extensions" is claimed only from an answer.
24
+ * - `listCandidates` / `setSlot` — scalar, routed by `slotRef`
25
+ * (`<source>:<slotId>`). An unclaimed ref is refused by name (D554.5).
26
+ *
27
+ * The slot's value travels as the generated discriminated union
28
+ * (`ExtensionSlotValue`, keyed on `slot`), so a value under the wrong slot is
29
+ * a schema error before it reaches any owner.
30
+ */
31
+ import { z } from 'zod';
32
+ import { type InferProvider } from './capability-definition.js';
33
+ /** Separator between the source and the slot id in a `slotRef`. It is the
34
+ * D554 routing separator: the dispatcher matches `<source>:` prefixes. */
35
+ export declare const EXTENSION_SLOT_REF_SEPARATOR = ":";
36
+ /** The contract method whose failure BECOMES a row, like `listSources`'s. */
37
+ export declare const EXTENSION_SLOT_LISTING_METHOD = "listSlots";
38
+ export declare const ExtensionSourceAvailabilitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
39
+ state: z.ZodLiteral<"ok">;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ state: z.ZodLiteral<"unreachable">;
42
+ reason: z.ZodString;
43
+ }, z.core.$strip>], "state">;
44
+ export type ExtensionSourceAvailability = z.infer<typeof ExtensionSourceAvailabilitySchema>;
45
+ /** One provider of slots — the D554 source-listing row. */
46
+ export declare const ExtensionSourceSchema: z.ZodObject<{
47
+ source: z.ZodString;
48
+ label: z.ZodString;
49
+ addonId: z.ZodOptional<z.ZodString>;
50
+ availability: z.ZodDiscriminatedUnion<[z.ZodObject<{
51
+ state: z.ZodLiteral<"ok">;
52
+ }, z.core.$strip>, z.ZodObject<{
53
+ state: z.ZodLiteral<"unreachable">;
54
+ reason: z.ZodString;
55
+ }, z.core.$strip>], "state">;
56
+ }, z.core.$strip>;
57
+ export type ExtensionSource = z.infer<typeof ExtensionSourceSchema>;
58
+ /**
59
+ * How one picked source stands. `missing` — no such device (deleted, or an id
60
+ * that never existed); `foreign` — a device the slot's owner cannot read from
61
+ * (slice 2's cross-owner graft source); `unavailable` — it exists but is not a
62
+ * valid source now (a container, which is never a pick). A source in any of
63
+ * these states is SHOWN, never silently dropped or re-pointed.
64
+ */
65
+ export declare const ExtensionSourceHealthSchema: z.ZodEnum<{
66
+ ok: "ok";
67
+ missing: "missing";
68
+ foreign: "foreign";
69
+ unavailable: "unavailable";
70
+ }>;
71
+ export type ExtensionSourceHealth = z.infer<typeof ExtensionSourceHealthSchema>;
72
+ export declare const ExtensionSlotSourceSchema: z.ZodObject<{
73
+ deviceId: z.ZodNumber;
74
+ name: z.ZodNullable<z.ZodString>;
75
+ health: z.ZodEnum<{
76
+ ok: "ok";
77
+ missing: "missing";
78
+ foreign: "foreign";
79
+ unavailable: "unavailable";
80
+ }>;
81
+ detail: z.ZodOptional<z.ZodString>;
82
+ }, z.core.$strip>;
83
+ export type ExtensionSlotSource = z.infer<typeof ExtensionSlotSourceSchema>;
84
+ /**
85
+ * A DIFFERENT authority that gates whether the slot's sources do anything —
86
+ * reported read-only, named, never written through this contract (D62). The
87
+ * virtual doorbell's sources ring only while the wrapper is bound to the
88
+ * camera, and that binding belongs to `deviceManager.setWrapperActive`.
89
+ * `unknown` means the gate could not be read; it is not "inactive" (D315).
90
+ */
91
+ export declare const ExtensionSlotActivationSchema: z.ZodObject<{
92
+ state: z.ZodEnum<{
93
+ unknown: "unknown";
94
+ active: "active";
95
+ inactive: "inactive";
96
+ }>;
97
+ authority: z.ZodString;
98
+ detail: z.ZodOptional<z.ZodString>;
99
+ }, z.core.$strip>;
100
+ export type ExtensionSlotActivation = z.infer<typeof ExtensionSlotActivationSchema>;
101
+ /** One slot of one device, as its owner reads it from its own store. */
102
+ export declare const ExtensionSlotStateSchema: z.ZodObject<{
103
+ state: z.ZodLiteral<"ok">;
104
+ slotRef: z.ZodString;
105
+ slot: z.ZodEnum<{
106
+ "linked-devices": "linked-devices";
107
+ "doorbell-source": "doorbell-source";
108
+ }>;
109
+ authority: z.ZodString;
110
+ enabled: z.ZodNullable<z.ZodBoolean>;
111
+ projects: z.ZodNullable<z.ZodString>;
112
+ activation: z.ZodNullable<z.ZodObject<{
113
+ state: z.ZodEnum<{
114
+ unknown: "unknown";
115
+ active: "active";
116
+ inactive: "inactive";
117
+ }>;
118
+ authority: z.ZodString;
119
+ detail: z.ZodOptional<z.ZodString>;
120
+ }, z.core.$strip>>;
121
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
122
+ deviceIds: z.ZodArray<z.ZodNumber>;
123
+ slot: z.ZodLiteral<"doorbell-source">;
124
+ }, z.core.$strip>, z.ZodObject<{
125
+ deviceIds: z.ZodArray<z.ZodNumber>;
126
+ slot: z.ZodLiteral<"linked-devices">;
127
+ }, z.core.$strip>], "slot">;
128
+ sources: z.ZodArray<z.ZodObject<{
129
+ deviceId: z.ZodNumber;
130
+ name: z.ZodNullable<z.ZodString>;
131
+ health: z.ZodEnum<{
132
+ ok: "ok";
133
+ missing: "missing";
134
+ foreign: "foreign";
135
+ unavailable: "unavailable";
136
+ }>;
137
+ detail: z.ZodOptional<z.ZodString>;
138
+ }, z.core.$strip>>;
139
+ }, z.core.$strip>;
140
+ export type ExtensionSlotState = z.infer<typeof ExtensionSlotStateSchema>;
141
+ /**
142
+ * A provider that could not answer `listSlots` at all. It could not name its
143
+ * own slots, so the row names the ADDON and carries the refusal verbatim.
144
+ * Written by the dispatcher, never by a provider.
145
+ */
146
+ export declare const ExtensionSlotUnreachableSchema: z.ZodObject<{
147
+ state: z.ZodLiteral<"unreachable">;
148
+ addonId: z.ZodString;
149
+ reason: z.ZodString;
150
+ }, z.core.$strip>;
151
+ export type ExtensionSlotUnreachable = z.infer<typeof ExtensionSlotUnreachableSchema>;
152
+ export declare const ExtensionSlotRowSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
153
+ state: z.ZodLiteral<"ok">;
154
+ slotRef: z.ZodString;
155
+ slot: z.ZodEnum<{
156
+ "linked-devices": "linked-devices";
157
+ "doorbell-source": "doorbell-source";
158
+ }>;
159
+ authority: z.ZodString;
160
+ enabled: z.ZodNullable<z.ZodBoolean>;
161
+ projects: z.ZodNullable<z.ZodString>;
162
+ activation: z.ZodNullable<z.ZodObject<{
163
+ state: z.ZodEnum<{
164
+ unknown: "unknown";
165
+ active: "active";
166
+ inactive: "inactive";
167
+ }>;
168
+ authority: z.ZodString;
169
+ detail: z.ZodOptional<z.ZodString>;
170
+ }, z.core.$strip>>;
171
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
172
+ deviceIds: z.ZodArray<z.ZodNumber>;
173
+ slot: z.ZodLiteral<"doorbell-source">;
174
+ }, z.core.$strip>, z.ZodObject<{
175
+ deviceIds: z.ZodArray<z.ZodNumber>;
176
+ slot: z.ZodLiteral<"linked-devices">;
177
+ }, z.core.$strip>], "slot">;
178
+ sources: z.ZodArray<z.ZodObject<{
179
+ deviceId: z.ZodNumber;
180
+ name: z.ZodNullable<z.ZodString>;
181
+ health: z.ZodEnum<{
182
+ ok: "ok";
183
+ missing: "missing";
184
+ foreign: "foreign";
185
+ unavailable: "unavailable";
186
+ }>;
187
+ detail: z.ZodOptional<z.ZodString>;
188
+ }, z.core.$strip>>;
189
+ }, z.core.$strip>, z.ZodObject<{
190
+ state: z.ZodLiteral<"unreachable">;
191
+ addonId: z.ZodString;
192
+ reason: z.ZodString;
193
+ }, z.core.$strip>], "state">;
194
+ export type ExtensionSlotRow = z.infer<typeof ExtensionSlotRowSchema>;
195
+ /** The row the dispatcher writes for a provider whose `listSlots` threw. */
196
+ export declare function unreachableExtensionSlotRow(addonId: string, reason: string): ExtensionSlotUnreachable;
197
+ /** One device the slot's editor may offer as a source. */
198
+ export declare const ExtensionCandidateSchema: z.ZodObject<{
199
+ deviceId: z.ZodNumber;
200
+ name: z.ZodString;
201
+ type: z.ZodString;
202
+ location: z.ZodNullable<z.ZodString>;
203
+ parentName: z.ZodNullable<z.ZodString>;
204
+ suggested: z.ZodBoolean;
205
+ reason: z.ZodNullable<z.ZodString>;
206
+ }, z.core.$strip>;
207
+ export type ExtensionCandidate = z.infer<typeof ExtensionCandidateSchema>;
208
+ export declare const ExtensionCandidatesSchema: z.ZodObject<{
209
+ candidates: z.ZodArray<z.ZodObject<{
210
+ deviceId: z.ZodNumber;
211
+ name: z.ZodString;
212
+ type: z.ZodString;
213
+ location: z.ZodNullable<z.ZodString>;
214
+ parentName: z.ZodNullable<z.ZodString>;
215
+ suggested: z.ZodBoolean;
216
+ reason: z.ZodNullable<z.ZodString>;
217
+ }, z.core.$strip>>;
218
+ }, z.core.$strip>;
219
+ export type ExtensionCandidates = z.infer<typeof ExtensionCandidatesSchema>;
220
+ /**
221
+ * What a write did. `none` — applied in place. `host` / `parent` — the owner
222
+ * reloaded the host (or, for an accessory child, its parent) because the
223
+ * write changed what the host REGISTERS (a graft switched on or off, slice 2).
224
+ */
225
+ export declare const ExtensionSetResultSchema: z.ZodObject<{
226
+ applied: z.ZodLiteral<true>;
227
+ reload: z.ZodEnum<{
228
+ none: "none";
229
+ host: "host";
230
+ parent: "parent";
231
+ }>;
232
+ }, z.core.$strip>;
233
+ export type ExtensionSetResult = z.infer<typeof ExtensionSetResultSchema>;
234
+ export declare const ExtensionSlotRefInputSchema: z.ZodObject<{
235
+ deviceId: z.ZodNumber;
236
+ slotRef: z.ZodString;
237
+ }, z.core.$strip>;
238
+ export type ExtensionSlotRefInput = z.infer<typeof ExtensionSlotRefInputSchema>;
239
+ export declare const ExtensionSetSlotInputSchema: z.ZodObject<{
240
+ deviceId: z.ZodNumber;
241
+ slotRef: z.ZodString;
242
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
243
+ deviceIds: z.ZodArray<z.ZodNumber>;
244
+ slot: z.ZodLiteral<"doorbell-source">;
245
+ }, z.core.$strip>, z.ZodObject<{
246
+ deviceIds: z.ZodArray<z.ZodNumber>;
247
+ slot: z.ZodLiteral<"linked-devices">;
248
+ }, z.core.$strip>], "slot">;
249
+ }, z.core.$strip>;
250
+ export type ExtensionSetSlotInput = z.infer<typeof ExtensionSetSlotInputSchema>;
251
+ export declare const deviceExtensionCapability: {
252
+ readonly name: "device-extension";
253
+ readonly scope: "device";
254
+ readonly mode: "collection";
255
+ readonly kind: "wrapper";
256
+ readonly defaultActive: true;
257
+ readonly deviceTypes: readonly import("../index.js").DeviceType[];
258
+ readonly deviceConfig: {
259
+ readonly ui: {
260
+ readonly kind: "widget";
261
+ readonly widgetId: "host/extensions-panel";
262
+ readonly tab: "general";
263
+ readonly label: "Extensions";
264
+ readonly order: 72;
265
+ };
266
+ };
267
+ readonly methods: {
268
+ /** One row per slot owner — the D554 source listing `slotRef` routes by. */
269
+ readonly listSources: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
270
+ deviceId: z.ZodNumber;
271
+ }, z.core.$strip>, z.ZodArray<z.ZodObject<{
272
+ source: z.ZodString;
273
+ label: z.ZodString;
274
+ addonId: z.ZodOptional<z.ZodString>;
275
+ availability: z.ZodDiscriminatedUnion<[z.ZodObject<{
276
+ state: z.ZodLiteral<"ok">;
277
+ }, z.core.$strip>, z.ZodObject<{
278
+ state: z.ZodLiteral<"unreachable">;
279
+ reason: z.ZodString;
280
+ }, z.core.$strip>], "state">;
281
+ }, z.core.$strip>>, import("./capability-definition.js").CapabilityMethodKind>;
282
+ /**
283
+ * Every slot this device is offered, read by each owner from its own
284
+ * store. A provider that throws is ONE `unreachable` row (D554.4).
285
+ */
286
+ readonly listSlots: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
287
+ deviceId: z.ZodNumber;
288
+ }, z.core.$strip>, z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
289
+ state: z.ZodLiteral<"ok">;
290
+ slotRef: z.ZodString;
291
+ slot: z.ZodEnum<{
292
+ "linked-devices": "linked-devices";
293
+ "doorbell-source": "doorbell-source";
294
+ }>;
295
+ authority: z.ZodString;
296
+ enabled: z.ZodNullable<z.ZodBoolean>;
297
+ projects: z.ZodNullable<z.ZodString>;
298
+ activation: z.ZodNullable<z.ZodObject<{
299
+ state: z.ZodEnum<{
300
+ unknown: "unknown";
301
+ active: "active";
302
+ inactive: "inactive";
303
+ }>;
304
+ authority: z.ZodString;
305
+ detail: z.ZodOptional<z.ZodString>;
306
+ }, z.core.$strip>>;
307
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
308
+ deviceIds: z.ZodArray<z.ZodNumber>;
309
+ slot: z.ZodLiteral<"doorbell-source">;
310
+ }, z.core.$strip>, z.ZodObject<{
311
+ deviceIds: z.ZodArray<z.ZodNumber>;
312
+ slot: z.ZodLiteral<"linked-devices">;
313
+ }, z.core.$strip>], "slot">;
314
+ sources: z.ZodArray<z.ZodObject<{
315
+ deviceId: z.ZodNumber;
316
+ name: z.ZodNullable<z.ZodString>;
317
+ health: z.ZodEnum<{
318
+ ok: "ok";
319
+ missing: "missing";
320
+ foreign: "foreign";
321
+ unavailable: "unavailable";
322
+ }>;
323
+ detail: z.ZodOptional<z.ZodString>;
324
+ }, z.core.$strip>>;
325
+ }, z.core.$strip>, z.ZodObject<{
326
+ state: z.ZodLiteral<"unreachable">;
327
+ addonId: z.ZodString;
328
+ reason: z.ZodString;
329
+ }, z.core.$strip>], "state">>, import("./capability-definition.js").CapabilityMethodKind>;
330
+ /** The devices the slot's editor may offer, suggestions pre-marked (D356). */
331
+ readonly listCandidates: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
332
+ deviceId: z.ZodNumber;
333
+ slotRef: z.ZodString;
334
+ }, z.core.$strip>, z.ZodObject<{
335
+ candidates: z.ZodArray<z.ZodObject<{
336
+ deviceId: z.ZodNumber;
337
+ name: z.ZodString;
338
+ type: z.ZodString;
339
+ location: z.ZodNullable<z.ZodString>;
340
+ parentName: z.ZodNullable<z.ZodString>;
341
+ suggested: z.ZodBoolean;
342
+ reason: z.ZodNullable<z.ZodString>;
343
+ }, z.core.$strip>>;
344
+ }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
345
+ /**
346
+ * Write one slot through its owner's EXISTING write path. The owner
347
+ * validates (a container is never a linked device, a camera is never its
348
+ * own source) and refuses by name before persisting.
349
+ */
350
+ readonly setSlot: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
351
+ deviceId: z.ZodNumber;
352
+ slotRef: z.ZodString;
353
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
354
+ deviceIds: z.ZodArray<z.ZodNumber>;
355
+ slot: z.ZodLiteral<"doorbell-source">;
356
+ }, z.core.$strip>, z.ZodObject<{
357
+ deviceIds: z.ZodArray<z.ZodNumber>;
358
+ slot: z.ZodLiteral<"linked-devices">;
359
+ }, z.core.$strip>], "slot">;
360
+ }, z.core.$strip>, z.ZodObject<{
361
+ applied: z.ZodLiteral<true>;
362
+ reload: z.ZodEnum<{
363
+ none: "none";
364
+ host: "host";
365
+ parent: "parent";
366
+ }>;
367
+ }, z.core.$strip>, "mutation">;
368
+ };
369
+ };
370
+ export type IDeviceExtensionProvider = InferProvider<typeof deviceExtensionCapability>;
@@ -125,6 +125,33 @@ export declare const LinkedDeviceSchema: z.ZodObject<{
125
125
  producesTrackedEvents: z.ZodOptional<z.ZodBoolean>;
126
126
  }, z.core.$strip>;
127
127
  export type LinkedDevice = z.infer<typeof LinkedDeviceSchema>;
128
+ /**
129
+ * The `linked-devices` extension slot's editable value (D648): the operator's
130
+ * pick list, exactly what `_linkedDeviceIds` persists. Tree children are NOT
131
+ * in it — they are always linked and are not a pick.
132
+ */
133
+ export declare const LinkedDevicesSlotValueSchema: z.ZodObject<{
134
+ deviceIds: z.ZodArray<z.ZodNumber>;
135
+ }, z.core.$strip>;
136
+ export type LinkedDevicesSlotValue = z.infer<typeof LinkedDevicesSlotValueSchema>;
137
+ /**
138
+ * The `linked-devices` slot — a camera's companion devices, owned by the
139
+ * device manager over `_linkedDeviceIds` (D648, D356). Any device may be a
140
+ * source except a container (its children are picked in its place) and the
141
+ * camera itself.
142
+ */
143
+ export declare const LINKED_DEVICES_SLOT: {
144
+ readonly id: "linked-devices";
145
+ readonly label: "Linked devices";
146
+ readonly description: string;
147
+ readonly shape: "association";
148
+ readonly hostDeviceTypes: readonly [DeviceType.Camera];
149
+ readonly sourceCaps: "any";
150
+ readonly cardinality: "many";
151
+ readonly value: z.ZodObject<{
152
+ deviceIds: z.ZodArray<z.ZodNumber>;
153
+ }, z.core.$strip>;
154
+ };
128
155
  /** One camera's resolved linked set, tagged with the camera it belongs to.
129
156
  * The batch answer needs the tag; the single-device answer already has it
130
157
  * from the input, which is why `getLinkedDevices` keeps the untagged shape. */
@@ -309,6 +336,18 @@ export declare const deviceManagerCapability: {
309
336
  readonly name: "device-manager";
310
337
  readonly scope: "system";
311
338
  readonly mode: "singleton";
339
+ readonly extensionSlots: readonly [{
340
+ readonly id: "linked-devices";
341
+ readonly label: "Linked devices";
342
+ readonly description: string;
343
+ readonly shape: "association";
344
+ readonly hostDeviceTypes: readonly [DeviceType.Camera];
345
+ readonly sourceCaps: "any";
346
+ readonly cardinality: "many";
347
+ readonly value: z.ZodObject<{
348
+ deviceIds: z.ZodArray<z.ZodNumber>;
349
+ }, z.core.$strip>;
350
+ }];
312
351
  readonly exposesDeviceSettings: true;
313
352
  readonly methods: {
314
353
  /** Reserve (or re-resolve) a progressive numeric id for `(addonId, stableId)`.
@@ -1134,11 +1173,12 @@ export declare const deviceManagerCapability: {
1134
1173
  /**
1135
1174
  * Resolve the devices LINKED to a camera — the single policy authority
1136
1175
  * both consumers call (viewer devices panel + pipeline-analytics event
1137
- * kinds/ingest). Device-tree children are ALWAYS included; mode 'auto'
1138
- * (default) adds every device sharing the camera's non-null `location`,
1139
- * mode 'manual' adds the persisted manual list instead. Excludes the
1140
- * camera itself; deduped. Configuration is standard per-device settings
1141
- * (see the module docblock) — there are no bespoke link mutations.
1176
+ * kinds/ingest). Device-tree children are ALWAYS included, plus the
1177
+ * operator's persisted pick list (`mode` is always `manual` since D356:
1178
+ * same-location devices are suggested by the picker, never linked on
1179
+ * their own). Excludes the camera itself; deduped. The list is written by
1180
+ * the settings section or the `linked-devices` extension slot, both over
1181
+ * `_linkedDeviceIds` (see the module docblock).
1142
1182
  */
1143
1183
  readonly getLinkedDevices: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
1144
1184
  deviceId: z.ZodNumber;
@@ -34,6 +34,35 @@ export declare const DoorbellPressEventSchema: z.ZodObject<{
34
34
  timestamp: z.ZodNumber;
35
35
  }, z.core.$strip>;
36
36
  export type DoorbellPressEvent = z.infer<typeof DoorbellPressEventSchema>;
37
+ /**
38
+ * The `doorbell-source` extension slot's editable value (D648): the camera's
39
+ * virtual-doorbell trigger devices, exactly what the wrapper's
40
+ * `doorbellSources` persists (as `{ deviceId }` records).
41
+ */
42
+ export declare const DoorbellSourceSlotValueSchema: z.ZodObject<{
43
+ deviceIds: z.ZodArray<z.ZodNumber>;
44
+ }, z.core.$strip>;
45
+ export type DoorbellSourceSlotValue = z.infer<typeof DoorbellSourceSlotValueSchema>;
46
+ /**
47
+ * The `doorbell-source` slot — which devices ring this camera's VIRTUAL
48
+ * doorbell, owned by the `virtual-doorbell` wrapper over its
49
+ * `doorbellSources` store (D648). A source rings when one of its
50
+ * `SOURCE_CAPS` rises. Whether the wrapper is bound to the camera at all is a
51
+ * different authority (`deviceManager.setWrapperActive`, D62) — the slot
52
+ * reports it, it never writes it.
53
+ */
54
+ export declare const DOORBELL_SOURCE_SLOT: {
55
+ readonly id: "doorbell-source";
56
+ readonly label: "Doorbell trigger devices";
57
+ readonly description: string;
58
+ readonly shape: "association";
59
+ readonly hostDeviceTypes: readonly [DeviceType.Camera];
60
+ readonly sourceCaps: readonly string[];
61
+ readonly cardinality: "many";
62
+ readonly value: z.ZodObject<{
63
+ deviceIds: z.ZodArray<z.ZodNumber>;
64
+ }, z.core.$strip>;
65
+ };
37
66
  export declare const doorbellCapability: {
38
67
  readonly name: "doorbell";
39
68
  readonly scope: "device";
@@ -43,6 +72,18 @@ export declare const doorbellCapability: {
43
72
  readonly defaultActive: false;
44
73
  readonly deviceTypes: readonly [DeviceType.Button, DeviceType.Camera];
45
74
  readonly exposesDeviceSettings: true;
75
+ readonly extensionSlots: readonly [{
76
+ readonly id: "doorbell-source";
77
+ readonly label: "Doorbell trigger devices";
78
+ readonly description: string;
79
+ readonly shape: "association";
80
+ readonly hostDeviceTypes: readonly [DeviceType.Camera];
81
+ readonly sourceCaps: readonly string[];
82
+ readonly cardinality: "many";
83
+ readonly value: z.ZodObject<{
84
+ deviceIds: z.ZodArray<z.ZodNumber>;
85
+ }, z.core.$strip>;
86
+ }];
46
87
  readonly methods: {};
47
88
  readonly events: {
48
89
  /**