camstack 1.1.29 → 1.1.30

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-DOq2moJx.mjs
14525
+ // ../types/dist/sleep-D8ZkNoYz.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -15585,6 +15585,46 @@ var RecordingConfigSchema = external_exports.object({
15585
15585
  */
15586
15586
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
15587
15587
  });
15588
+ var OpsLogDomainSchema = external_exports.enum(["recording", "events"]);
15589
+ var OpsLogOpSchema = external_exports.enum([
15590
+ "prune",
15591
+ "manual-delete",
15592
+ "rescan",
15593
+ "retention-run"
15594
+ ]);
15595
+ var OpsLogReasonSchema = external_exports.enum([
15596
+ "retention",
15597
+ "quota",
15598
+ "manual",
15599
+ "operator"
15600
+ ]);
15601
+ var OpsLogEntrySchema = external_exports.object({
15602
+ /** Unique row id. */
15603
+ id: external_exports.string(),
15604
+ /** Epoch ms the operation completed. */
15605
+ at: external_exports.number(),
15606
+ domain: OpsLogDomainSchema,
15607
+ op: OpsLogOpSchema,
15608
+ reason: OpsLogReasonSchema,
15609
+ /** The camera the op targeted; null for a cluster/global op. */
15610
+ deviceId: external_exports.number().nullable(),
15611
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
15612
+ nodeId: external_exports.string(),
15613
+ /** Buckets / rows deleted (op-specific unit). */
15614
+ itemsAffected: external_exports.number(),
15615
+ /** Bytes reclaimed by the op (0 when not measurable). */
15616
+ bytesReclaimed: external_exports.number(),
15617
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
15618
+ detail: external_exports.string().nullable(),
15619
+ /** Who/what triggered the op. */
15620
+ actor: external_exports.string()
15621
+ });
15622
+ var OpsLogQueryInputSchema = external_exports.object({
15623
+ /** Restrict to a single camera; omit for every row. */
15624
+ deviceId: external_exports.number().optional(),
15625
+ /** Max rows returned, newest-first. */
15626
+ limit: external_exports.number().int().min(1).max(1e3).optional()
15627
+ });
15588
15628
  var StorageLocationTypeSchema = external_exports.string().regex(/^[a-z][a-zA-Z0-9-]*$/);
15589
15629
  var StorageLocationSchema = external_exports.object({
15590
15630
  id: external_exports.string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -21847,9 +21887,10 @@ var zoneRulesCapability = {
21847
21887
  * `package` backs the package-drop detector — a package zone is a
21848
21888
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
21849
21889
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
21850
- * The orchestrator provider that writes this stage lands in a later
21851
- * slice; until then the mirror carries only `{motion, detection}` and
21852
- * consumers read `package` as absent (treat as `[]`).
21890
+ * The orchestrator provider writes this stage as a first-class slice
21891
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
21892
+ * package}` shape, so consumers read the current package rules directly
21893
+ * off `device.state.zoneRules.value.package`.
21853
21894
  */
21854
21895
  runtimeState: external_exports.object({
21855
21896
  motion: external_exports.array(ZoneRuleSchema).readonly(),
@@ -25924,6 +25965,23 @@ var TrackCascadeCountsSchema = external_exports.object({
25924
25965
  /** Per-track CLIP search vectors removed (best-effort). */
25925
25966
  embeddings: external_exports.number().int()
25926
25967
  });
25968
+ var EventStoreDeviceFootprintSchema = external_exports.object({
25969
+ deviceId: external_exports.number(),
25970
+ /** Persisted event rows (motion + object + audio) for the camera. */
25971
+ rows: external_exports.number().int(),
25972
+ /** Event-owned media bytes on disk for the camera. */
25973
+ bytes: external_exports.number().int()
25974
+ });
25975
+ var EventStoreFootprintSchema = external_exports.object({
25976
+ totalRows: external_exports.number().int(),
25977
+ totalBytes: external_exports.number().int(),
25978
+ devices: external_exports.array(EventStoreDeviceFootprintSchema).readonly()
25979
+ });
25980
+ var EventPruneCountsSchema = external_exports.object({
25981
+ motion: external_exports.number().int(),
25982
+ object: external_exports.number().int(),
25983
+ audio: external_exports.number().int()
25984
+ });
25927
25985
  var pipelineAnalyticsCapability = {
25928
25986
  name: "pipeline-analytics",
25929
25987
  scope: "device",
@@ -26085,6 +26143,45 @@ var pipelineAnalyticsCapability = {
26085
26143
  kind: "mutation",
26086
26144
  auth: "admin"
26087
26145
  }),
26146
+ /**
26147
+ * Durable event-store footprint for the management UI: event rows
26148
+ * (motion + object + audio) counted per camera + total, plus the
26149
+ * event-owned media bytes on disk per camera + total. Stat/count-based,
26150
+ * computed on demand.
26151
+ */
26152
+ getEventStoreFootprint: method(external_exports.object({}), EventStoreFootprintSchema, {
26153
+ kind: "query",
26154
+ auth: "admin"
26155
+ }),
26156
+ /**
26157
+ * Cluster-wide prune of events older than `olderThanMs` (exclusive) across
26158
+ * every camera, deleting each event's media in lockstep. Logged to the
26159
+ * events ops-log with `reason` (default `'retention'`). Returns the summed
26160
+ * per-kind deleted counts.
26161
+ */
26162
+ pruneEvents: method(external_exports.object({
26163
+ olderThanMs: external_exports.number(),
26164
+ reason: OpsLogReasonSchema.optional()
26165
+ }), EventPruneCountsSchema, {
26166
+ kind: "mutation",
26167
+ auth: "admin"
26168
+ }),
26169
+ /**
26170
+ * Manually delete EVERY event (motion + object + audio) for one camera and
26171
+ * its event-owned media in lockstep. Logged to the events ops-log as
26172
+ * `op:'manual-delete', reason:'manual'`. Destructive — the admin UI guards
26173
+ * it behind a confirm.
26174
+ */
26175
+ deleteDeviceEvents: method(external_exports.object({ deviceId: external_exports.number() }), EventPruneCountsSchema, {
26176
+ kind: "mutation",
26177
+ auth: "admin"
26178
+ }),
26179
+ /** The events ops-log rows (newest-first), optionally scoped to one camera.
26180
+ * Backed by a declared pipeline-analytics SQLite collection. */
26181
+ listOpsLog: method(OpsLogQueryInputSchema, external_exports.array(OpsLogEntrySchema).readonly(), {
26182
+ kind: "query",
26183
+ auth: "admin"
26184
+ }),
26088
26185
  getEventMedia: method(external_exports.object({
26089
26186
  eventId: external_exports.string(),
26090
26187
  kind: MediaFileKindEnum.optional()
@@ -30017,14 +30114,43 @@ var recordingCapability = {
30017
30114
  auth: "admin"
30018
30115
  }),
30019
30116
  /** Apply this device's retention policy to footage now; returns the oldest
30020
- * surviving footage start (the retention floor) or null if no footage. */
30021
- pruneFootage: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.object({
30117
+ * surviving footage start (the retention floor) or null if no footage. The
30118
+ * prune is logged to the recordings ops-log with `reason` (default
30119
+ * `'retention'` — the policy-driven prune; `'quota'` when disk-pressure
30120
+ * triggered). */
30121
+ pruneFootage: method(external_exports.object({
30122
+ deviceId: external_exports.number(),
30123
+ reason: OpsLogReasonSchema.optional()
30124
+ }), external_exports.object({
30022
30125
  floorMs: external_exports.number().nullable(),
30023
30126
  deletedBuckets: external_exports.number().int(),
30024
30127
  reclaimedBytes: external_exports.number().int()
30025
30128
  }), {
30026
30129
  kind: "mutation",
30027
30130
  auth: "admin"
30131
+ }),
30132
+ /**
30133
+ * Manually delete a camera's footage — the whole footprint, or a
30134
+ * `[fromMs, toMs)` window when either bound is given. Logged to the
30135
+ * recordings ops-log as `op:'manual-delete', reason:'manual'`. Destructive:
30136
+ * the admin UI guards it behind a confirm.
30137
+ */
30138
+ deleteFootprint: method(external_exports.object({
30139
+ deviceId: external_exports.number(),
30140
+ fromMs: external_exports.number().optional(),
30141
+ toMs: external_exports.number().optional()
30142
+ }), external_exports.object({
30143
+ deletedBuckets: external_exports.number().int(),
30144
+ reclaimedBytes: external_exports.number().int()
30145
+ }), {
30146
+ kind: "mutation",
30147
+ auth: "admin"
30148
+ }),
30149
+ /** The recordings ops-log rows (newest-first), optionally scoped to one
30150
+ * camera. Backed by the recorder's bounded DurableState ring. */
30151
+ listOpsLog: method(OpsLogQueryInputSchema, external_exports.array(OpsLogEntrySchema).readonly(), {
30152
+ kind: "query",
30153
+ auth: "admin"
30028
30154
  })
30029
30155
  }
30030
30156
  };
@@ -33163,6 +33289,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33163
33289
  addonId: null,
33164
33290
  access: "delete"
33165
33291
  },
33292
+ "pipelineAnalytics.deleteDeviceEvents": {
33293
+ capName: "pipeline-analytics",
33294
+ capScope: "device",
33295
+ addonId: null,
33296
+ access: "delete"
33297
+ },
33166
33298
  "pipelineAnalytics.deleteTracks": {
33167
33299
  capName: "pipeline-analytics",
33168
33300
  capScope: "device",
@@ -33193,6 +33325,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33193
33325
  addonId: null,
33194
33326
  access: "view"
33195
33327
  },
33328
+ "pipelineAnalytics.getEventStoreFootprint": {
33329
+ capName: "pipeline-analytics",
33330
+ capScope: "device",
33331
+ addonId: null,
33332
+ access: "view"
33333
+ },
33196
33334
  "pipelineAnalytics.getKeyEvents": {
33197
33335
  capName: "pipeline-analytics",
33198
33336
  capScope: "device",
@@ -33235,6 +33373,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33235
33373
  addonId: null,
33236
33374
  access: "view"
33237
33375
  },
33376
+ "pipelineAnalytics.listOpsLog": {
33377
+ capName: "pipeline-analytics",
33378
+ capScope: "device",
33379
+ addonId: null,
33380
+ access: "view"
33381
+ },
33238
33382
  "pipelineAnalytics.listRecentTracks": {
33239
33383
  capName: "pipeline-analytics",
33240
33384
  capScope: "device",
@@ -33247,6 +33391,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33247
33391
  addonId: null,
33248
33392
  access: "view"
33249
33393
  },
33394
+ "pipelineAnalytics.pruneEvents": {
33395
+ capName: "pipeline-analytics",
33396
+ capScope: "device",
33397
+ addonId: null,
33398
+ access: "create"
33399
+ },
33250
33400
  "pipelineAnalytics.pruneEventsBefore": {
33251
33401
  capName: "pipeline-analytics",
33252
33402
  capScope: "device",
@@ -34009,6 +34159,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34009
34159
  addonId: null,
34010
34160
  access: "create"
34011
34161
  },
34162
+ "recording.deleteFootprint": {
34163
+ capName: "recording",
34164
+ capScope: "system",
34165
+ addonId: null,
34166
+ access: "delete"
34167
+ },
34012
34168
  "recording.getAvailability": {
34013
34169
  capName: "recording",
34014
34170
  capScope: "system",
@@ -34039,6 +34195,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34039
34195
  addonId: null,
34040
34196
  access: "view"
34041
34197
  },
34198
+ "recording.listOpsLog": {
34199
+ capName: "recording",
34200
+ capScope: "system",
34201
+ addonId: null,
34202
+ access: "view"
34203
+ },
34042
34204
  "recording.locateSegment": {
34043
34205
  capName: "recording",
34044
34206
  capScope: "system",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-XGNAIFKZ.js";
4
+ } from "./chunk-WX6XSMWG.js";
5
5
  import "./chunk-K3NQKI34.js";
6
6
 
7
7
  // src/cli.ts
@@ -1079,7 +1079,7 @@ function isUnknown(_value) {
1079
1079
  return true;
1080
1080
  }
1081
1081
  async function resolveServerInteractive(presetNamespace) {
1082
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-EB7LI523.js");
1082
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-Q6UMJNDP.js");
1083
1083
  if (presetNamespace) {
1084
1084
  const spinner4 = clack.spinner();
1085
1085
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-XGNAIFKZ.js";
8
+ } from "./chunk-WX6XSMWG.js";
9
9
  import "./chunk-K3NQKI34.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.1.29",
3
+ "version": "1.1.30",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",