@camstack/addon-export-hap 1.1.3 → 1.1.5

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.
@@ -4664,7 +4664,7 @@ function _instanceof(cls, params = {}) {
4664
4664
  return inst;
4665
4665
  }
4666
4666
  //#endregion
4667
- //#region ../types/dist/sleep-BV7rLc6Y.mjs
4667
+ //#region ../types/dist/sleep-NOH4yRwj.mjs
4668
4668
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4669
4669
  EventCategory["SystemBoot"] = "system.boot";
4670
4670
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5779,15 +5779,24 @@ var BaseAddon = class {
5779
5779
  } catch {}
5780
5780
  }
5781
5781
  /**
5782
- * Resolve the shared models directory path via the storage capability.
5783
- * Falls back to `camstack-data/models` if storage is unavailable.
5784
- * Used by inference addons (detection-pipeline, audio-classifier, embedding-encoder).
5782
+ * Resolve the shared, node-local models directory: `<nodeDataDir>/models`.
5783
+ *
5784
+ * This is the SINGLE centralized models-dir resolver for every inference addon
5785
+ * (detection-pipeline, audio-analyzer, embedding-encoder, model-studio). It is
5786
+ * anchored at the node's own writable data root (`ctx.nodeDataDir`, i.e.
5787
+ * `CAMSTACK_DATA` ?? the kernel boot dir) — never the hub-singleton `storage`
5788
+ * cap, which returns the hub's `/data/models` to every node and breaks any node
5789
+ * whose real data dir differs (e.g. the macOS electron agent).
5790
+ *
5791
+ * `node:path`/`node:fs` are imported dynamically so the `@camstack/types` root
5792
+ * barrel (re-exported into browser bundles) stays free of node builtins.
5785
5793
  */
5786
5794
  async resolveModelsDir() {
5787
- return this.ctx.api.storage.resolve.query({
5788
- location: "models",
5789
- relativePath: ""
5790
- }).catch(() => "camstack-data/models");
5795
+ const { join } = await import("node:path");
5796
+ const { promises: fsp } = await import("node:fs");
5797
+ const dir = join(this.ctx.nodeDataDir, "models");
5798
+ await fsp.mkdir(dir, { recursive: true });
5799
+ return dir;
5791
5800
  }
5792
5801
  /**
5793
5802
  * Access the runtime capability registry for in-process provider lookups.
@@ -12762,7 +12771,8 @@ method(object({
12762
12771
  sessionId: string().optional()
12763
12772
  }), ConvertResultSchema, {
12764
12773
  kind: "mutation",
12765
- auth: "admin"
12774
+ auth: "admin",
12775
+ timeoutMs: 6e5
12766
12776
  });
12767
12777
  var AddonHttpRouteSchema = object({
12768
12778
  method: _enum([
@@ -14298,7 +14308,14 @@ var NotificationRuleConditionsSchema = object({
14298
14308
  /** Match against `event.data.eventType` token (e.g. `'press_long'`). When non-empty, only events
14299
14309
  * carrying a matching `data.eventType` string pass this condition. Rules without this field are
14300
14310
  * unaffected (back-compat). Distinct from `rule.eventTypes` which holds EventCategory strings. */
14301
- eventTypeTokens: array(string()).readonly().optional()
14311
+ eventTypeTokens: array(string()).readonly().optional(),
14312
+ /** Match detections whose CLIP image embedding is semantically similar to this free-text
14313
+ * description. Requires the embedding-encoder cap to have pre-warmed the text vector.
14314
+ * `minSimilarity` is the cosine similarity threshold in [0, 1]. */
14315
+ clipDescription: object({
14316
+ text: string().min(1),
14317
+ minSimilarity: number().min(0).max(1)
14318
+ }).optional()
14302
14319
  });
14303
14320
  var NotificationRuleTemplateSchema = object({
14304
14321
  title: string(),
@@ -14540,6 +14557,16 @@ var TrackedDetectionSchema = object({
14540
14557
  zones: array(string()).readonly(),
14541
14558
  state: TrackStateSchema
14542
14559
  });
14560
+ var ScoredObjectEventSchema = ObjectEventSchema.extend({ score: number() });
14561
+ var SearchObjectEventsInput = object({
14562
+ text: string(),
14563
+ deviceId: number().optional(),
14564
+ since: number().optional(),
14565
+ until: number().optional(),
14566
+ classFilter: string().optional(),
14567
+ limit: number().default(50),
14568
+ minScore: number().min(0).max(1).default(.2)
14569
+ });
14543
14570
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
14544
14571
  deviceId: number(),
14545
14572
  trackId: string()
@@ -14574,7 +14601,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
14574
14601
  }), method(object({
14575
14602
  eventId: string(),
14576
14603
  kind: MediaFileKindEnum.optional()
14577
- }), array(MediaFileSchema).readonly()), method(object({ trackId: string() }), array(MediaFileSchema).readonly()), object({
14604
+ }), array(MediaFileSchema).readonly()), method(object({ trackId: string() }), array(MediaFileSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), object({
14578
14605
  deviceId: number(),
14579
14606
  timestamp: number(),
14580
14607
  frameWidth: number(),
@@ -19224,6 +19251,12 @@ Object.freeze({
19224
19251
  addonId: null,
19225
19252
  access: "create"
19226
19253
  },
19254
+ "pipelineAnalytics.searchObjectEvents": {
19255
+ capName: "pipeline-analytics",
19256
+ capScope: "device",
19257
+ addonId: null,
19258
+ access: "view"
19259
+ },
19227
19260
  "pipelineExecutor.cacheFrameInPool": {
19228
19261
  capName: "pipeline-executor",
19229
19262
  capScope: "system",
@@ -4639,7 +4639,7 @@ function _instanceof(cls, params = {}) {
4639
4639
  return inst;
4640
4640
  }
4641
4641
  //#endregion
4642
- //#region ../types/dist/sleep-BV7rLc6Y.mjs
4642
+ //#region ../types/dist/sleep-NOH4yRwj.mjs
4643
4643
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4644
4644
  EventCategory["SystemBoot"] = "system.boot";
4645
4645
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5754,15 +5754,24 @@ var BaseAddon = class {
5754
5754
  } catch {}
5755
5755
  }
5756
5756
  /**
5757
- * Resolve the shared models directory path via the storage capability.
5758
- * Falls back to `camstack-data/models` if storage is unavailable.
5759
- * Used by inference addons (detection-pipeline, audio-classifier, embedding-encoder).
5757
+ * Resolve the shared, node-local models directory: `<nodeDataDir>/models`.
5758
+ *
5759
+ * This is the SINGLE centralized models-dir resolver for every inference addon
5760
+ * (detection-pipeline, audio-analyzer, embedding-encoder, model-studio). It is
5761
+ * anchored at the node's own writable data root (`ctx.nodeDataDir`, i.e.
5762
+ * `CAMSTACK_DATA` ?? the kernel boot dir) — never the hub-singleton `storage`
5763
+ * cap, which returns the hub's `/data/models` to every node and breaks any node
5764
+ * whose real data dir differs (e.g. the macOS electron agent).
5765
+ *
5766
+ * `node:path`/`node:fs` are imported dynamically so the `@camstack/types` root
5767
+ * barrel (re-exported into browser bundles) stays free of node builtins.
5760
5768
  */
5761
5769
  async resolveModelsDir() {
5762
- return this.ctx.api.storage.resolve.query({
5763
- location: "models",
5764
- relativePath: ""
5765
- }).catch(() => "camstack-data/models");
5770
+ const { join } = await import("node:path");
5771
+ const { promises: fsp } = await import("node:fs");
5772
+ const dir = join(this.ctx.nodeDataDir, "models");
5773
+ await fsp.mkdir(dir, { recursive: true });
5774
+ return dir;
5766
5775
  }
5767
5776
  /**
5768
5777
  * Access the runtime capability registry for in-process provider lookups.
@@ -12737,7 +12746,8 @@ method(object({
12737
12746
  sessionId: string().optional()
12738
12747
  }), ConvertResultSchema, {
12739
12748
  kind: "mutation",
12740
- auth: "admin"
12749
+ auth: "admin",
12750
+ timeoutMs: 6e5
12741
12751
  });
12742
12752
  var AddonHttpRouteSchema = object({
12743
12753
  method: _enum([
@@ -14273,7 +14283,14 @@ var NotificationRuleConditionsSchema = object({
14273
14283
  /** Match against `event.data.eventType` token (e.g. `'press_long'`). When non-empty, only events
14274
14284
  * carrying a matching `data.eventType` string pass this condition. Rules without this field are
14275
14285
  * unaffected (back-compat). Distinct from `rule.eventTypes` which holds EventCategory strings. */
14276
- eventTypeTokens: array(string()).readonly().optional()
14286
+ eventTypeTokens: array(string()).readonly().optional(),
14287
+ /** Match detections whose CLIP image embedding is semantically similar to this free-text
14288
+ * description. Requires the embedding-encoder cap to have pre-warmed the text vector.
14289
+ * `minSimilarity` is the cosine similarity threshold in [0, 1]. */
14290
+ clipDescription: object({
14291
+ text: string().min(1),
14292
+ minSimilarity: number().min(0).max(1)
14293
+ }).optional()
14277
14294
  });
14278
14295
  var NotificationRuleTemplateSchema = object({
14279
14296
  title: string(),
@@ -14515,6 +14532,16 @@ var TrackedDetectionSchema = object({
14515
14532
  zones: array(string()).readonly(),
14516
14533
  state: TrackStateSchema
14517
14534
  });
14535
+ var ScoredObjectEventSchema = ObjectEventSchema.extend({ score: number() });
14536
+ var SearchObjectEventsInput = object({
14537
+ text: string(),
14538
+ deviceId: number().optional(),
14539
+ since: number().optional(),
14540
+ until: number().optional(),
14541
+ classFilter: string().optional(),
14542
+ limit: number().default(50),
14543
+ minScore: number().min(0).max(1).default(.2)
14544
+ });
14518
14545
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
14519
14546
  deviceId: number(),
14520
14547
  trackId: string()
@@ -14549,7 +14576,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
14549
14576
  }), method(object({
14550
14577
  eventId: string(),
14551
14578
  kind: MediaFileKindEnum.optional()
14552
- }), array(MediaFileSchema).readonly()), method(object({ trackId: string() }), array(MediaFileSchema).readonly()), object({
14579
+ }), array(MediaFileSchema).readonly()), method(object({ trackId: string() }), array(MediaFileSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), object({
14553
14580
  deviceId: number(),
14554
14581
  timestamp: number(),
14555
14582
  frameWidth: number(),
@@ -19199,6 +19226,12 @@ Object.freeze({
19199
19226
  addonId: null,
19200
19227
  access: "create"
19201
19228
  },
19229
+ "pipelineAnalytics.searchObjectEvents": {
19230
+ capName: "pipeline-analytics",
19231
+ capScope: "device",
19232
+ addonId: null,
19233
+ access: "view"
19234
+ },
19202
19235
  "pipelineExecutor.cacheFrameInPool": {
19203
19236
  capName: "pipeline-executor",
19204
19237
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "HomeKit (HAP) bridge exporter for CamStack devices. Publishes a bridged accessory per exposed device — MotionSensor in this MVP; Camera/Doorbell/Switch/Light follow.",
5
5
  "keywords": [
6
6
  "camstack",