@camstack/addon-export-hap 1.2.63 → 1.2.66

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.
@@ -8384,7 +8384,8 @@ var OpsLogReasonSchema = _enum([
8384
8384
  "quota",
8385
8385
  "manual",
8386
8386
  "operator",
8387
- "maintenance"
8387
+ "maintenance",
8388
+ "orphaned-device"
8388
8389
  ]);
8389
8390
  /** One audit row, shared verbatim by both domains. */
8390
8391
  var OpsLogEntrySchema = object({
@@ -13550,10 +13551,39 @@ var DevicePersistConfigPayloadSchema = object({
13550
13551
  deviceId: number(),
13551
13552
  data: record(string(), unknown())
13552
13553
  });
13554
+ /** What a migration actually did, per switch. `unreachable` is a first-class
13555
+ * answer: a camera that could not be asked is not a camera that was silenced. */
13556
+ var MigrateSwitchOutcomeSchema = _enum([
13557
+ "off",
13558
+ "on",
13559
+ "not-offered",
13560
+ "unreachable"
13561
+ ]);
13562
+ var MigrateSwitchReportSchema = object({
13563
+ deviceId: number(),
13564
+ switchId: CameraSwitchIdSchema,
13565
+ outcome: MigrateSwitchOutcomeSchema,
13566
+ detail: string().optional()
13567
+ });
13568
+ var MigrateDeviceResultSchema = object({
13569
+ sourceId: number(),
13570
+ targetId: number(),
13571
+ switches: array(MigrateSwitchReportSchema).readonly(),
13572
+ /** Switches that could NOT be turned off on the source. Empty is the only
13573
+ * value meaning the replaced hardware is quiet. */
13574
+ sourceStillLive: array(CameraSwitchIdSchema).readonly(),
13575
+ swapped: boolean()
13576
+ });
13553
13577
  method(object({
13554
13578
  addonId: string(),
13555
13579
  stableId: string()
13556
- }), object({ id: number() }), { kind: "mutation" }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), DeviceMetaSchema.nullable()), method(object({
13580
+ }), object({ id: number() }), { kind: "mutation" }), method(object({
13581
+ sourceId: number(),
13582
+ targetId: number()
13583
+ }), MigrateDeviceResultSchema, {
13584
+ kind: "mutation",
13585
+ auth: "admin"
13586
+ }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), DeviceMetaSchema.nullable()), method(object({
13557
13587
  deviceId: number(),
13558
13588
  name: string()
13559
13589
  }), _void(), {
@@ -14028,6 +14058,35 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
14028
14058
  auth: "admin"
14029
14059
  });
14030
14060
  /**
14061
+ * Transport bounds for AI capability methods.
14062
+ *
14063
+ * Its own module because `llm.cap.ts` and `llm-runtime.cap.ts` already import
14064
+ * each other: declaring the constant in either one hands the other `undefined`
14065
+ * at module-init time, and an undefined `timeoutMs` silently falls back to the
14066
+ * kernel's 60 s default — the exact failure this constant exists to prevent,
14067
+ * reintroduced invisibly. Found by the guard, not by review.
14068
+ */
14069
+ /**
14070
+ * Ceiling for a cap method that runs inference or loads a model.
14071
+ *
14072
+ * Deliberately far above anything the AI layer itself may wait for (a summary
14073
+ * asks 180 s by default, a rule may ask 600 s), because the TRANSPORT must
14074
+ * never be the layer that gives up first: when it does, the failure is
14075
+ * reported as a transport error for a model that was still thinking, naming
14076
+ * the wrong layer and hiding the real one.
14077
+ *
14078
+ * Measured 2026-09-03: a 6-image vision request needs 44.8 s warm and ~20 s
14079
+ * more on a cold model load. With no declaration every digest failed at
14080
+ * exactly 60 s and shipped without its text.
14081
+ *
14082
+ * A ceiling, not a budget. The AI layer's own timeouts (the rule's `timeoutMs`,
14083
+ * the profile's `timeoutMs` / `firstTokenTimeoutMs`) remain the things that
14084
+ * decide when to stop, because only they can say WHY.
14085
+ */
14086
+ var AI_CAP_TRANSPORT_TIMEOUT_MS = 6e5;
14087
+ /** A multi-gigabyte download. An hour is not generous, it is honest. */
14088
+ var AI_MODEL_INSTALL_TIMEOUT_MS = 60 * 6e4;
14089
+ /**
14031
14090
  * Shared LLM generate contracts — imported by BOTH `llm.cap.ts` (consumer
14032
14091
  * surface) and `llm-runtime.cap.ts` (node-side managed executor) so the two
14033
14092
  * caps stay wire-compatible without a circular cap→cap import.
@@ -14299,16 +14358,19 @@ method(LlmGenerateBaseInputSchema.extend({
14299
14358
  timeoutMs: number().int().positive().optional()
14300
14359
  }), LlmGenerateResultSchema, {
14301
14360
  kind: "mutation",
14302
- auth: "admin"
14361
+ auth: "admin",
14362
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14303
14363
  }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
14304
14364
  kind: "mutation",
14305
- auth: "admin"
14365
+ auth: "admin",
14366
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14306
14367
  }), method(object({}), _void(), {
14307
14368
  kind: "mutation",
14308
14369
  auth: "admin"
14309
14370
  }), method(object({}), LlmRuntimeStatusSchema, { auth: "admin" }), method(object({ model: ManagedModelRefSchema }), _void(), {
14310
14371
  kind: "mutation",
14311
- auth: "admin"
14372
+ auth: "admin",
14373
+ timeoutMs: AI_MODEL_INSTALL_TIMEOUT_MS
14312
14374
  }), method(object({ file: string() }), _void(), {
14313
14375
  kind: "mutation",
14314
14376
  auth: "admin"
@@ -14476,7 +14538,13 @@ var ProfileRefInputSchema = object({
14476
14538
  addonId: string(),
14477
14539
  profileId: string()
14478
14540
  });
14479
- method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
14541
+ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
14542
+ kind: "mutation",
14543
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14544
+ }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, {
14545
+ kind: "mutation",
14546
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14547
+ }), method(object({
14480
14548
  addonId: string().optional(),
14481
14549
  requestId: string()
14482
14550
  }), _void(), { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
@@ -14487,7 +14555,8 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }
14487
14555
  auth: "admin"
14488
14556
  }), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
14489
14557
  kind: "mutation",
14490
- auth: "admin"
14558
+ auth: "admin",
14559
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14491
14560
  }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
14492
14561
  selector: LlmDefaultSelectorSchema,
14493
14562
  profileId: string().nullable()
@@ -31129,6 +31198,12 @@ Object.freeze({
31129
31198
  addonId: null,
31130
31199
  access: "view"
31131
31200
  },
31201
+ "deviceManager.migrateDevice": {
31202
+ capName: "device-manager",
31203
+ capScope: "system",
31204
+ addonId: null,
31205
+ access: "create"
31206
+ },
31132
31207
  "deviceManager.persistConfig": {
31133
31208
  capName: "device-manager",
31134
31209
  capScope: "system",
@@ -8372,7 +8372,8 @@ var OpsLogReasonSchema = _enum([
8372
8372
  "quota",
8373
8373
  "manual",
8374
8374
  "operator",
8375
- "maintenance"
8375
+ "maintenance",
8376
+ "orphaned-device"
8376
8377
  ]);
8377
8378
  /** One audit row, shared verbatim by both domains. */
8378
8379
  var OpsLogEntrySchema = object({
@@ -13538,10 +13539,39 @@ var DevicePersistConfigPayloadSchema = object({
13538
13539
  deviceId: number(),
13539
13540
  data: record(string(), unknown())
13540
13541
  });
13542
+ /** What a migration actually did, per switch. `unreachable` is a first-class
13543
+ * answer: a camera that could not be asked is not a camera that was silenced. */
13544
+ var MigrateSwitchOutcomeSchema = _enum([
13545
+ "off",
13546
+ "on",
13547
+ "not-offered",
13548
+ "unreachable"
13549
+ ]);
13550
+ var MigrateSwitchReportSchema = object({
13551
+ deviceId: number(),
13552
+ switchId: CameraSwitchIdSchema,
13553
+ outcome: MigrateSwitchOutcomeSchema,
13554
+ detail: string().optional()
13555
+ });
13556
+ var MigrateDeviceResultSchema = object({
13557
+ sourceId: number(),
13558
+ targetId: number(),
13559
+ switches: array(MigrateSwitchReportSchema).readonly(),
13560
+ /** Switches that could NOT be turned off on the source. Empty is the only
13561
+ * value meaning the replaced hardware is quiet. */
13562
+ sourceStillLive: array(CameraSwitchIdSchema).readonly(),
13563
+ swapped: boolean()
13564
+ });
13541
13565
  method(object({
13542
13566
  addonId: string(),
13543
13567
  stableId: string()
13544
- }), object({ id: number() }), { kind: "mutation" }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), DeviceMetaSchema.nullable()), method(object({
13568
+ }), object({ id: number() }), { kind: "mutation" }), method(object({
13569
+ sourceId: number(),
13570
+ targetId: number()
13571
+ }), MigrateDeviceResultSchema, {
13572
+ kind: "mutation",
13573
+ auth: "admin"
13574
+ }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), record(string(), unknown())), method(object({ deviceId: number() }), DeviceMetaSchema.nullable()), method(object({
13545
13575
  deviceId: number(),
13546
13576
  name: string()
13547
13577
  }), _void(), {
@@ -14016,6 +14046,35 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
14016
14046
  auth: "admin"
14017
14047
  });
14018
14048
  /**
14049
+ * Transport bounds for AI capability methods.
14050
+ *
14051
+ * Its own module because `llm.cap.ts` and `llm-runtime.cap.ts` already import
14052
+ * each other: declaring the constant in either one hands the other `undefined`
14053
+ * at module-init time, and an undefined `timeoutMs` silently falls back to the
14054
+ * kernel's 60 s default — the exact failure this constant exists to prevent,
14055
+ * reintroduced invisibly. Found by the guard, not by review.
14056
+ */
14057
+ /**
14058
+ * Ceiling for a cap method that runs inference or loads a model.
14059
+ *
14060
+ * Deliberately far above anything the AI layer itself may wait for (a summary
14061
+ * asks 180 s by default, a rule may ask 600 s), because the TRANSPORT must
14062
+ * never be the layer that gives up first: when it does, the failure is
14063
+ * reported as a transport error for a model that was still thinking, naming
14064
+ * the wrong layer and hiding the real one.
14065
+ *
14066
+ * Measured 2026-09-03: a 6-image vision request needs 44.8 s warm and ~20 s
14067
+ * more on a cold model load. With no declaration every digest failed at
14068
+ * exactly 60 s and shipped without its text.
14069
+ *
14070
+ * A ceiling, not a budget. The AI layer's own timeouts (the rule's `timeoutMs`,
14071
+ * the profile's `timeoutMs` / `firstTokenTimeoutMs`) remain the things that
14072
+ * decide when to stop, because only they can say WHY.
14073
+ */
14074
+ var AI_CAP_TRANSPORT_TIMEOUT_MS = 6e5;
14075
+ /** A multi-gigabyte download. An hour is not generous, it is honest. */
14076
+ var AI_MODEL_INSTALL_TIMEOUT_MS = 60 * 6e4;
14077
+ /**
14019
14078
  * Shared LLM generate contracts — imported by BOTH `llm.cap.ts` (consumer
14020
14079
  * surface) and `llm-runtime.cap.ts` (node-side managed executor) so the two
14021
14080
  * caps stay wire-compatible without a circular cap→cap import.
@@ -14287,16 +14346,19 @@ method(LlmGenerateBaseInputSchema.extend({
14287
14346
  timeoutMs: number().int().positive().optional()
14288
14347
  }), LlmGenerateResultSchema, {
14289
14348
  kind: "mutation",
14290
- auth: "admin"
14349
+ auth: "admin",
14350
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14291
14351
  }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
14292
14352
  kind: "mutation",
14293
- auth: "admin"
14353
+ auth: "admin",
14354
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14294
14355
  }), method(object({}), _void(), {
14295
14356
  kind: "mutation",
14296
14357
  auth: "admin"
14297
14358
  }), method(object({}), LlmRuntimeStatusSchema, { auth: "admin" }), method(object({ model: ManagedModelRefSchema }), _void(), {
14298
14359
  kind: "mutation",
14299
- auth: "admin"
14360
+ auth: "admin",
14361
+ timeoutMs: AI_MODEL_INSTALL_TIMEOUT_MS
14300
14362
  }), method(object({ file: string() }), _void(), {
14301
14363
  kind: "mutation",
14302
14364
  auth: "admin"
@@ -14464,7 +14526,13 @@ var ProfileRefInputSchema = object({
14464
14526
  addonId: string(),
14465
14527
  profileId: string()
14466
14528
  });
14467
- method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
14529
+ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
14530
+ kind: "mutation",
14531
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14532
+ }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, {
14533
+ kind: "mutation",
14534
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14535
+ }), method(object({
14468
14536
  addonId: string().optional(),
14469
14537
  requestId: string()
14470
14538
  }), _void(), { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
@@ -14475,7 +14543,8 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }
14475
14543
  auth: "admin"
14476
14544
  }), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
14477
14545
  kind: "mutation",
14478
- auth: "admin"
14546
+ auth: "admin",
14547
+ timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
14479
14548
  }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
14480
14549
  selector: LlmDefaultSelectorSchema,
14481
14550
  profileId: string().nullable()
@@ -31117,6 +31186,12 @@ Object.freeze({
31117
31186
  addonId: null,
31118
31187
  access: "view"
31119
31188
  },
31189
+ "deviceManager.migrateDevice": {
31190
+ capName: "device-manager",
31191
+ capScope: "system",
31192
+ addonId: null,
31193
+ access: "create"
31194
+ },
31120
31195
  "deviceManager.persistConfig": {
31121
31196
  capName: "device-manager",
31122
31197
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.2.63",
3
+ "version": "1.2.66",
4
4
  "description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
5
5
  "keywords": [
6
6
  "camstack",