@camstack/addon-tailscale 1.2.49 → 1.2.51

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.
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_dist = require("../dist-Cv-ufJXF.js");
27
+ const require_dist = require("../dist-DZmp04sL.js");
28
28
  let node_child_process = require("node:child_process");
29
29
  let node_util = require("node:util");
30
30
  let node_fs = require("node:fs");
@@ -1,4 +1,4 @@
1
- import { a as EventCategory, i as BaseAddon, n as networkAccessCapability, r as BOOT_RECOVERY_BACKOFF_MS, t as meshNetworkCapability } from "../dist-8Fi7VglU.mjs";
1
+ import { a as EventCategory, i as BaseAddon, n as networkAccessCapability, r as BOOT_RECOVERY_BACKOFF_MS, t as meshNetworkCapability } from "../dist-CLEhB-7g.mjs";
2
2
  import { execFile, spawn } from "node:child_process";
3
3
  import { promisify } from "node:util";
4
4
  import * as fs from "node:fs";
@@ -8113,6 +8113,13 @@ var MediaRelocateModeSchema = _enum([
8113
8113
  ]);
8114
8114
  var RelocateMediaInputSchema = object({
8115
8115
  toLocationId: string(),
8116
+ /**
8117
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8118
+ * every row that is not already on `toLocationId` (the historical
8119
+ * behaviour). A named source is what a from→to migration needs: without it
8120
+ * "move events off disk 2" also emptied disk 1.
8121
+ */
8122
+ fromLocationId: string().optional(),
8116
8123
  throttleMbps: number().min(1).max(1e3).optional(),
8117
8124
  /** Omitted = `move`, the pre-existing behaviour. */
8118
8125
  mode: MediaRelocateModeSchema.optional()
@@ -8180,6 +8187,19 @@ var StorageMigrationDestinationsSchema = object({
8180
8187
  galleryMedia: string().min(1).optional()
8181
8188
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8182
8189
  /**
8190
+ * Optional named source per class. Omitted = the class's current default
8191
+ * (the historical behaviour). A named source that is NOT the default is a
8192
+ * drain of that disk: bytes move, the default stays, and the source is
8193
+ * disabled when the move finishes.
8194
+ */
8195
+ var StorageMigrationSourcesSchema = object({
8196
+ recordings: string().min(1).optional(),
8197
+ recordingsLow: string().min(1).optional(),
8198
+ eventMedia: string().min(1).optional(),
8199
+ backups: string().min(1).optional(),
8200
+ galleryMedia: string().min(1).optional()
8201
+ }).optional();
8202
+ /**
8183
8203
  * How a migration sequences the cutover against the byte move.
8184
8204
  *
8185
8205
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8201,6 +8221,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8201
8221
  /** Shared input for planning and starting an orchestrated storage migration. */
8202
8222
  var StorageMigrationInputSchema = object({
8203
8223
  destinations: StorageMigrationDestinationsSchema,
8224
+ /** Omitted = each class's current default. */
8225
+ sources: StorageMigrationSourcesSchema,
8204
8226
  throttleMbps: number().min(1).max(1e3).optional(),
8205
8227
  /** Omitted = `blocking`, which stays the default. */
8206
8228
  mode: StorageMigrationModeSchema.optional()
@@ -8280,6 +8302,13 @@ var StorageMigrationMoveSchema = object({
8280
8302
  storageClass: StorageMigrationClassSchema,
8281
8303
  fromLocationId: string(),
8282
8304
  toLocationId: string(),
8305
+ /**
8306
+ * True when `from` was NOT the class default at plan time. The move still
8307
+ * copies bytes, but the default is left alone and the source is disabled
8308
+ * once the copy verifies. Absent on jobs planned before this field existed
8309
+ * — those jobs always repointed, which is `false`.
8310
+ */
8311
+ freezeSource: boolean().optional(),
8283
8312
  moverJobId: string().nullable(),
8284
8313
  state: RelocateJobStateSchema.nullable(),
8285
8314
  error: string().nullable(),
@@ -8293,6 +8322,7 @@ var StorageMigrationJobSchema = object({
8293
8322
  * can tell a seconds-long cutover from a thirty-hour one. */
8294
8323
  mode: StorageMigrationModeSchema,
8295
8324
  destinations: StorageMigrationDestinationsSchema,
8325
+ sources: StorageMigrationSourcesSchema,
8296
8326
  throttleMbps: number(),
8297
8327
  moves: array(StorageMigrationMoveSchema),
8298
8328
  pauseLeaseId: string().nullable(),
@@ -8318,6 +8348,7 @@ var StorageMigrationFindingSchema = object({
8318
8348
  });
8319
8349
  var StorageMigrationPlanSchema = object({
8320
8350
  destinations: StorageMigrationDestinationsSchema,
8351
+ sources: StorageMigrationSourcesSchema,
8321
8352
  /** The mode this plan was built for. A plan is only valid for its mode: the
8322
8353
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8323
8354
  * it. */
@@ -8325,7 +8356,8 @@ var StorageMigrationPlanSchema = object({
8325
8356
  moves: array(object({
8326
8357
  storageClass: StorageMigrationClassSchema,
8327
8358
  fromLocationId: string(),
8328
- toLocationId: string()
8359
+ toLocationId: string(),
8360
+ freezeSource: boolean().optional()
8329
8361
  })),
8330
8362
  findings: array(StorageMigrationFindingSchema)
8331
8363
  });
@@ -8503,10 +8535,51 @@ var LedgerWalkReportSchema = object({
8503
8535
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8504
8536
  var RelocatableMediaCountInputSchema = object({
8505
8537
  toLocationId: string().min(1),
8538
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8539
+ fromLocationId: string().optional(),
8506
8540
  /** Omitted = `move`. */
8507
8541
  mode: MediaRelocateModeSchema.optional()
8508
8542
  });
8509
8543
  /**
8544
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8545
+ * ghost ledger entries on frozen footage locations.
8546
+ *
8547
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8548
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8549
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8550
+ * with no operator-visible status.
8551
+ */
8552
+ var StorageCleanupPhaseSchema = _enum([
8553
+ "orphans",
8554
+ "debug-media",
8555
+ "ghost-ledger",
8556
+ "done",
8557
+ "failed",
8558
+ "cancelled"
8559
+ ]);
8560
+ var StorageCleanupInputSchema = object({
8561
+ /** Also walk motion stills / track filmstrips. Off by default. */
8562
+ includeDebugMedia: boolean().optional() });
8563
+ var StorageCleanupJobSchema = object({
8564
+ jobId: string(),
8565
+ phase: StorageCleanupPhaseSchema,
8566
+ includeDebugMedia: boolean(),
8567
+ orphansReclaimed: number().int().nonnegative(),
8568
+ orphanBytesReclaimed: number().int().nonnegative(),
8569
+ debugMediaReclaimed: number().int().nonnegative(),
8570
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8571
+ ghostsForgotten: number().int().nonnegative(),
8572
+ ghostBytesForgotten: number().int().nonnegative(),
8573
+ /** Short operator-facing line: current collection, pass, or location. */
8574
+ detail: string().nullable(),
8575
+ cancelRequested: boolean(),
8576
+ startedAt: number(),
8577
+ updatedAt: number(),
8578
+ finishedAt: number().nullable(),
8579
+ error: string().nullable()
8580
+ });
8581
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8582
+ /**
8510
8583
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8511
8584
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8512
8585
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8534,11 +8607,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8534
8607
  * The default location for a type uses `id === <type>:default` by
8535
8608
  * convention (the bare type ref like `'backups'` resolves to it).
8536
8609
  *
8537
- * `isSystem: true` marks a location as orchestrator-seeded and
8538
- * undeletable. The bootstrap-installed defaults (one per type) carry
8539
- * this flag; operator-added locations don't. Editing the config of
8540
- * a system location is allowed (path migration, provider swap) but
8541
- * deleting it is rejected at the cap level.
8610
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8611
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8612
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8613
+ * / last-enabled, not on this bit.
8542
8614
  */
8543
8615
  var StorageLocationSchema = object({
8544
8616
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12800,6 +12872,12 @@ method(object({
12800
12872
  }), _void(), {
12801
12873
  kind: "mutation",
12802
12874
  auth: "admin"
12875
+ }), method(object({
12876
+ from: string(),
12877
+ to: string()
12878
+ }), object({ moved: number() }), {
12879
+ kind: "mutation",
12880
+ auth: "admin"
12803
12881
  }), method(object({
12804
12882
  deviceId: number(),
12805
12883
  disabled: boolean()
@@ -15529,6 +15607,8 @@ var NcSystemEventKindSchema = _enum([
15529
15607
  "device-offline",
15530
15608
  "device-disabled",
15531
15609
  "device-enabled",
15610
+ "device-battery-low",
15611
+ "device-battery-normal",
15532
15612
  "stream-online",
15533
15613
  "stream-offline",
15534
15614
  "node-online",
@@ -18747,46 +18827,6 @@ var RecentTracksPageSchema = object({
18747
18827
  /** Cursor for the next page, or null when this page is the last. */
18748
18828
  nextCursor: string().nullable()
18749
18829
  });
18750
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18751
- var LIST_GROUPS_MAX_LIMIT = 100;
18752
- var AnalyticsGroupRecordSchema = object({
18753
- id: string(),
18754
- deviceId: number().int(),
18755
- openedAt: number().int(),
18756
- closedAt: number().int(),
18757
- timestamp: number().int(),
18758
- memberCount: number().int(),
18759
- memberTrackIds: array(string()).readonly(),
18760
- className: string(),
18761
- classes: array(string()).readonly(),
18762
- /** Relative event-media path, or null when the group has no picture yet. */
18763
- mediaUrl: string().nullable(),
18764
- singleton: boolean()
18765
- });
18766
- var AnalyticsGroupMemberSchema = object({
18767
- trackId: string(),
18768
- deviceId: number().int(),
18769
- className: string(),
18770
- firstSeen: number().int(),
18771
- lastSeen: number().int(),
18772
- mediaUrl: string().nullable()
18773
- });
18774
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18775
- var ListGroupsQueryInput = object({
18776
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18777
- deviceIds: array(number()),
18778
- /** Window lower bound on `closedAt` (inclusive). */
18779
- since: number().optional(),
18780
- /** Window upper bound on `openedAt` (inclusive). */
18781
- until: number().optional(),
18782
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18783
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18784
- cursor: string().optional()
18785
- });
18786
- var ListGroupsPageSchema = object({
18787
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18788
- nextCursor: string().nullable()
18789
- });
18790
18830
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18791
18831
  var KEY_EVENTS_MAX_LIMIT = 200;
18792
18832
  var KeyEventQueryInput = object({
@@ -18890,9 +18930,7 @@ var TrackCascadeCountsSchema = object({
18890
18930
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
18891
18931
  plates: number().int(),
18892
18932
  /** Per-track CLIP search vectors removed (best-effort). */
18893
- embeddings: number().int(),
18894
- /** Group membership + group rows removed with their last member (best-effort). */
18895
- groups: number().int()
18933
+ embeddings: number().int()
18896
18934
  });
18897
18935
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18898
18936
  var DiskReconcileCountsSchema = object({
@@ -19062,6 +19100,47 @@ var RebuildStatusSchema = object({
19062
19100
  /** Present when the pass ended by throwing. */
19063
19101
  error: string().nullable()
19064
19102
  });
19103
+ /**
19104
+ * Acknowledgement that a debug-media reclaim STARTED.
19105
+ *
19106
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19107
+ * it runs detached and this returns immediately. Awaiting it is how the
19108
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19109
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19110
+ */
19111
+ var MediaReclaimStartResultSchema = object({
19112
+ started: boolean(),
19113
+ /** True when a pass was already running; the new request is ignored. */
19114
+ alreadyRunning: boolean()
19115
+ });
19116
+ var MediaReclaimInputSchema = object({
19117
+ mode: _enum(["report", "reclaim"]).default("report"),
19118
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19119
+ deviceIds: array(number().int()).min(1).optional(),
19120
+ restart: boolean().optional(),
19121
+ pageSize: number().int().min(50).max(5e3).optional(),
19122
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19123
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19124
+ maxBytesPerRun: number().int().min(1).optional(),
19125
+ budgetMinutes: number().int().min(1).max(720).optional(),
19126
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19127
+ graceMinutes: number().int().min(1).max(10080).optional()
19128
+ });
19129
+ var MediaReclaimStatusSchema = object({
19130
+ running: boolean(),
19131
+ mode: _enum(["report", "reclaim"]).nullable(),
19132
+ totalExamined: number(),
19133
+ totalEligible: number(),
19134
+ totalReclaimed: number(),
19135
+ totalBytesReclaimed: number(),
19136
+ totalRefused: number(),
19137
+ /** Device+scope windows finished in this pass. */
19138
+ devicesDone: number(),
19139
+ complete: boolean().nullable(),
19140
+ startedAtMs: number().nullable(),
19141
+ finishedAtMs: number().nullable(),
19142
+ error: string().nullable()
19143
+ });
19065
19144
  var ReplayFrameInputSchema = object({
19066
19145
  timestamp: number(),
19067
19146
  frame: PipelineRunResultBridge
@@ -19100,10 +19179,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19100
19179
  * stationary registry). Default false: the timeline lists passages,
19101
19180
  * not parking records (operator decision, 2026-08-15). */
19102
19181
  includeStationary: boolean().optional()
19103
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19104
- deviceId: number(),
19105
- groupId: string().min(1)
19106
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19182
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19107
19183
  kind: "mutation",
19108
19184
  auth: "admin"
19109
19185
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -19203,6 +19279,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19203
19279
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19204
19280
  kind: "query",
19205
19281
  auth: "admin"
19282
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19283
+ kind: "mutation",
19284
+ auth: "admin"
19285
+ }), method(object({}), MediaReclaimStatusSchema, {
19286
+ kind: "query",
19287
+ auth: "admin"
19206
19288
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19207
19289
  kind: "query",
19208
19290
  auth: "admin"
@@ -21173,7 +21255,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21173
21255
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21174
21256
  kind: "mutation",
21175
21257
  auth: "admin"
21176
- });
21258
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21259
+ kind: "mutation",
21260
+ auth: "admin"
21261
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21262
+ kind: "mutation",
21263
+ auth: "admin"
21264
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21177
21265
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21178
21266
  providerId: string().min(1),
21179
21267
  displayName: string().min(1),
@@ -26612,6 +26700,33 @@ var RecordingRebalanceInputSchema = object({
26612
26700
  minMoveGb: number().min(0).optional()
26613
26701
  });
26614
26702
  /**
26703
+ * Operator-facing placement of one camera onto a recordings location.
26704
+ *
26705
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26706
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26707
+ * currently write — the plan, which may disagree with the pin when Auto.
26708
+ */
26709
+ var RecordingDevicePlacementSchema = object({
26710
+ deviceId: number().int(),
26711
+ profile: string(),
26712
+ locationId: string()
26713
+ });
26714
+ var RecordingDevicePinSchema = object({
26715
+ deviceId: number().int(),
26716
+ /** Recordings-class location this camera is pinned to. */
26717
+ locationId: string()
26718
+ });
26719
+ var RecordingPlacementViewSchema = object({
26720
+ assignments: array(RecordingDevicePlacementSchema),
26721
+ pins: array(RecordingDevicePinSchema),
26722
+ defaultLocations: record(string(), string())
26723
+ });
26724
+ var RecordingSetDevicePlacementInputSchema = object({
26725
+ deviceId: number().int(),
26726
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26727
+ locationId: string().nullable()
26728
+ });
26729
+ /**
26615
26730
  * Result of locating footage at a wall-clock instant for one device/profile.
26616
26731
  * `segment` carries the covering segment's window; `gap` reports the forward
26617
26732
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26837,6 +26952,12 @@ method(object({
26837
26952
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26838
26953
  kind: "mutation",
26839
26954
  auth: "admin"
26955
+ }), method(object({}), RecordingPlacementViewSchema, {
26956
+ kind: "query",
26957
+ auth: "admin"
26958
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
26959
+ kind: "mutation",
26960
+ auth: "admin"
26840
26961
  });
26841
26962
  /**
26842
26963
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30207,6 +30328,12 @@ Object.freeze({
30207
30328
  addonId: null,
30208
30329
  access: "delete"
30209
30330
  },
30331
+ "deviceManager.renameLocation": {
30332
+ capName: "device-manager",
30333
+ capScope: "system",
30334
+ addonId: null,
30335
+ access: "create"
30336
+ },
30210
30337
  "deviceManager.runDeviceAction": {
30211
30338
  capName: "device-manager",
30212
30339
  capScope: "system",
@@ -31899,19 +32026,19 @@ Object.freeze({
31899
32026
  addonId: null,
31900
32027
  access: "view"
31901
32028
  },
31902
- "pipelineAnalytics.getGroup": {
32029
+ "pipelineAnalytics.getKeyEvents": {
31903
32030
  capName: "pipeline-analytics",
31904
32031
  capScope: "device",
31905
32032
  addonId: null,
31906
32033
  access: "view"
31907
32034
  },
31908
- "pipelineAnalytics.getKeyEvents": {
32035
+ "pipelineAnalytics.getKeyEventsBatch": {
31909
32036
  capName: "pipeline-analytics",
31910
32037
  capScope: "device",
31911
32038
  addonId: null,
31912
32039
  access: "view"
31913
32040
  },
31914
- "pipelineAnalytics.getKeyEventsBatch": {
32041
+ "pipelineAnalytics.getMediaReclaimStatus": {
31915
32042
  capName: "pipeline-analytics",
31916
32043
  capScope: "device",
31917
32044
  addonId: null,
@@ -32001,12 +32128,6 @@ Object.freeze({
32001
32128
  addonId: null,
32002
32129
  access: "view"
32003
32130
  },
32004
- "pipelineAnalytics.listGroups": {
32005
- capName: "pipeline-analytics",
32006
- capScope: "device",
32007
- addonId: null,
32008
- access: "view"
32009
- },
32010
32131
  "pipelineAnalytics.listOpsLog": {
32011
32132
  capName: "pipeline-analytics",
32012
32133
  capScope: "device",
@@ -32091,6 +32212,12 @@ Object.freeze({
32091
32212
  addonId: null,
32092
32213
  access: "create"
32093
32214
  },
32215
+ "pipelineAnalytics.reclaimDebugMedia": {
32216
+ capName: "pipeline-analytics",
32217
+ capScope: "device",
32218
+ addonId: null,
32219
+ access: "create"
32220
+ },
32094
32221
  "pipelineAnalytics.reconcileFromDisk": {
32095
32222
  capName: "pipeline-analytics",
32096
32223
  capScope: "device",
@@ -33015,6 +33142,12 @@ Object.freeze({
33015
33142
  addonId: null,
33016
33143
  access: "view"
33017
33144
  },
33145
+ "recording.getPlacement": {
33146
+ capName: "recording",
33147
+ capScope: "system",
33148
+ addonId: null,
33149
+ access: "view"
33150
+ },
33018
33151
  "recording.getPlaybackManifest": {
33019
33152
  capName: "recording",
33020
33153
  capScope: "system",
@@ -33141,6 +33274,12 @@ Object.freeze({
33141
33274
  addonId: null,
33142
33275
  access: "create"
33143
33276
  },
33277
+ "recording.setDevicePlacement": {
33278
+ capName: "recording",
33279
+ capScope: "system",
33280
+ addonId: null,
33281
+ access: "create"
33282
+ },
33144
33283
  "recording.startStorageMigrationMove": {
33145
33284
  capName: "recording",
33146
33285
  capScope: "system",
@@ -33585,12 +33724,36 @@ Object.freeze({
33585
33724
  addonId: null,
33586
33725
  access: "create"
33587
33726
  },
33727
+ "storageMigration.cleanupCancel": {
33728
+ capName: "storage-migration",
33729
+ capScope: "system",
33730
+ addonId: null,
33731
+ access: "create"
33732
+ },
33733
+ "storageMigration.cleanupStart": {
33734
+ capName: "storage-migration",
33735
+ capScope: "system",
33736
+ addonId: null,
33737
+ access: "create"
33738
+ },
33739
+ "storageMigration.cleanupStatus": {
33740
+ capName: "storage-migration",
33741
+ capScope: "system",
33742
+ addonId: null,
33743
+ access: "view"
33744
+ },
33588
33745
  "storageMigration.drain": {
33589
33746
  capName: "storage-migration",
33590
33747
  capScope: "system",
33591
33748
  addonId: null,
33592
33749
  access: "create"
33593
33750
  },
33751
+ "storageMigration.history": {
33752
+ capName: "storage-migration",
33753
+ capScope: "system",
33754
+ addonId: null,
33755
+ access: "view"
33756
+ },
33594
33757
  "storageMigration.movers": {
33595
33758
  capName: "storage-migration",
33596
33759
  capScope: "system",
@@ -35587,11 +35750,6 @@ Object.freeze({
35587
35750
  form: "single",
35588
35751
  optional: true
35589
35752
  }],
35590
- "pipelineAnalytics.getGroup": [{
35591
- name: "deviceId",
35592
- form: "single",
35593
- optional: false
35594
- }],
35595
35753
  "pipelineAnalytics.getKeyEvents": [{
35596
35754
  name: "deviceId",
35597
35755
  form: "single",
@@ -35657,11 +35815,6 @@ Object.freeze({
35657
35815
  form: "single",
35658
35816
  optional: false
35659
35817
  }],
35660
- "pipelineAnalytics.listGroups": [{
35661
- name: "deviceIds",
35662
- form: "array",
35663
- optional: false
35664
- }],
35665
35818
  "pipelineAnalytics.listOpsLog": [{
35666
35819
  name: "deviceId",
35667
35820
  form: "single",
@@ -35707,6 +35860,11 @@ Object.freeze({
35707
35860
  form: "single",
35708
35861
  optional: true
35709
35862
  }],
35863
+ "pipelineAnalytics.reclaimDebugMedia": [{
35864
+ name: "deviceIds",
35865
+ form: "array",
35866
+ optional: true
35867
+ }],
35710
35868
  "pipelineAnalytics.reconcileFromDisk": [{
35711
35869
  name: "deviceId",
35712
35870
  form: "single",
@@ -36072,6 +36230,11 @@ Object.freeze({
36072
36230
  form: "single",
36073
36231
  optional: false
36074
36232
  }],
36233
+ "recording.setDevicePlacement": [{
36234
+ name: "deviceId",
36235
+ form: "single",
36236
+ optional: false
36237
+ }],
36075
36238
  "recording.startStorageMigrationMove": [{
36076
36239
  name: "deviceId",
36077
36240
  form: "single",
@@ -8113,6 +8113,13 @@ var MediaRelocateModeSchema = _enum([
8113
8113
  ]);
8114
8114
  var RelocateMediaInputSchema = object({
8115
8115
  toLocationId: string(),
8116
+ /**
8117
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8118
+ * every row that is not already on `toLocationId` (the historical
8119
+ * behaviour). A named source is what a from→to migration needs: without it
8120
+ * "move events off disk 2" also emptied disk 1.
8121
+ */
8122
+ fromLocationId: string().optional(),
8116
8123
  throttleMbps: number().min(1).max(1e3).optional(),
8117
8124
  /** Omitted = `move`, the pre-existing behaviour. */
8118
8125
  mode: MediaRelocateModeSchema.optional()
@@ -8180,6 +8187,19 @@ var StorageMigrationDestinationsSchema = object({
8180
8187
  galleryMedia: string().min(1).optional()
8181
8188
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8182
8189
  /**
8190
+ * Optional named source per class. Omitted = the class's current default
8191
+ * (the historical behaviour). A named source that is NOT the default is a
8192
+ * drain of that disk: bytes move, the default stays, and the source is
8193
+ * disabled when the move finishes.
8194
+ */
8195
+ var StorageMigrationSourcesSchema = object({
8196
+ recordings: string().min(1).optional(),
8197
+ recordingsLow: string().min(1).optional(),
8198
+ eventMedia: string().min(1).optional(),
8199
+ backups: string().min(1).optional(),
8200
+ galleryMedia: string().min(1).optional()
8201
+ }).optional();
8202
+ /**
8183
8203
  * How a migration sequences the cutover against the byte move.
8184
8204
  *
8185
8205
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8201,6 +8221,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8201
8221
  /** Shared input for planning and starting an orchestrated storage migration. */
8202
8222
  var StorageMigrationInputSchema = object({
8203
8223
  destinations: StorageMigrationDestinationsSchema,
8224
+ /** Omitted = each class's current default. */
8225
+ sources: StorageMigrationSourcesSchema,
8204
8226
  throttleMbps: number().min(1).max(1e3).optional(),
8205
8227
  /** Omitted = `blocking`, which stays the default. */
8206
8228
  mode: StorageMigrationModeSchema.optional()
@@ -8280,6 +8302,13 @@ var StorageMigrationMoveSchema = object({
8280
8302
  storageClass: StorageMigrationClassSchema,
8281
8303
  fromLocationId: string(),
8282
8304
  toLocationId: string(),
8305
+ /**
8306
+ * True when `from` was NOT the class default at plan time. The move still
8307
+ * copies bytes, but the default is left alone and the source is disabled
8308
+ * once the copy verifies. Absent on jobs planned before this field existed
8309
+ * — those jobs always repointed, which is `false`.
8310
+ */
8311
+ freezeSource: boolean().optional(),
8283
8312
  moverJobId: string().nullable(),
8284
8313
  state: RelocateJobStateSchema.nullable(),
8285
8314
  error: string().nullable(),
@@ -8293,6 +8322,7 @@ var StorageMigrationJobSchema = object({
8293
8322
  * can tell a seconds-long cutover from a thirty-hour one. */
8294
8323
  mode: StorageMigrationModeSchema,
8295
8324
  destinations: StorageMigrationDestinationsSchema,
8325
+ sources: StorageMigrationSourcesSchema,
8296
8326
  throttleMbps: number(),
8297
8327
  moves: array(StorageMigrationMoveSchema),
8298
8328
  pauseLeaseId: string().nullable(),
@@ -8318,6 +8348,7 @@ var StorageMigrationFindingSchema = object({
8318
8348
  });
8319
8349
  var StorageMigrationPlanSchema = object({
8320
8350
  destinations: StorageMigrationDestinationsSchema,
8351
+ sources: StorageMigrationSourcesSchema,
8321
8352
  /** The mode this plan was built for. A plan is only valid for its mode: the
8322
8353
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8323
8354
  * it. */
@@ -8325,7 +8356,8 @@ var StorageMigrationPlanSchema = object({
8325
8356
  moves: array(object({
8326
8357
  storageClass: StorageMigrationClassSchema,
8327
8358
  fromLocationId: string(),
8328
- toLocationId: string()
8359
+ toLocationId: string(),
8360
+ freezeSource: boolean().optional()
8329
8361
  })),
8330
8362
  findings: array(StorageMigrationFindingSchema)
8331
8363
  });
@@ -8503,10 +8535,51 @@ var LedgerWalkReportSchema = object({
8503
8535
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8504
8536
  var RelocatableMediaCountInputSchema = object({
8505
8537
  toLocationId: string().min(1),
8538
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8539
+ fromLocationId: string().optional(),
8506
8540
  /** Omitted = `move`. */
8507
8541
  mode: MediaRelocateModeSchema.optional()
8508
8542
  });
8509
8543
  /**
8544
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8545
+ * ghost ledger entries on frozen footage locations.
8546
+ *
8547
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8548
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8549
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8550
+ * with no operator-visible status.
8551
+ */
8552
+ var StorageCleanupPhaseSchema = _enum([
8553
+ "orphans",
8554
+ "debug-media",
8555
+ "ghost-ledger",
8556
+ "done",
8557
+ "failed",
8558
+ "cancelled"
8559
+ ]);
8560
+ var StorageCleanupInputSchema = object({
8561
+ /** Also walk motion stills / track filmstrips. Off by default. */
8562
+ includeDebugMedia: boolean().optional() });
8563
+ var StorageCleanupJobSchema = object({
8564
+ jobId: string(),
8565
+ phase: StorageCleanupPhaseSchema,
8566
+ includeDebugMedia: boolean(),
8567
+ orphansReclaimed: number().int().nonnegative(),
8568
+ orphanBytesReclaimed: number().int().nonnegative(),
8569
+ debugMediaReclaimed: number().int().nonnegative(),
8570
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8571
+ ghostsForgotten: number().int().nonnegative(),
8572
+ ghostBytesForgotten: number().int().nonnegative(),
8573
+ /** Short operator-facing line: current collection, pass, or location. */
8574
+ detail: string().nullable(),
8575
+ cancelRequested: boolean(),
8576
+ startedAt: number(),
8577
+ updatedAt: number(),
8578
+ finishedAt: number().nullable(),
8579
+ error: string().nullable()
8580
+ });
8581
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8582
+ /**
8510
8583
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8511
8584
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8512
8585
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8534,11 +8607,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8534
8607
  * The default location for a type uses `id === <type>:default` by
8535
8608
  * convention (the bare type ref like `'backups'` resolves to it).
8536
8609
  *
8537
- * `isSystem: true` marks a location as orchestrator-seeded and
8538
- * undeletable. The bootstrap-installed defaults (one per type) carry
8539
- * this flag; operator-added locations don't. Editing the config of
8540
- * a system location is allowed (path migration, provider swap) but
8541
- * deleting it is rejected at the cap level.
8610
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8611
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8612
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8613
+ * / last-enabled, not on this bit.
8542
8614
  */
8543
8615
  var StorageLocationSchema = object({
8544
8616
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -12800,6 +12872,12 @@ method(object({
12800
12872
  }), _void(), {
12801
12873
  kind: "mutation",
12802
12874
  auth: "admin"
12875
+ }), method(object({
12876
+ from: string(),
12877
+ to: string()
12878
+ }), object({ moved: number() }), {
12879
+ kind: "mutation",
12880
+ auth: "admin"
12803
12881
  }), method(object({
12804
12882
  deviceId: number(),
12805
12883
  disabled: boolean()
@@ -15529,6 +15607,8 @@ var NcSystemEventKindSchema = _enum([
15529
15607
  "device-offline",
15530
15608
  "device-disabled",
15531
15609
  "device-enabled",
15610
+ "device-battery-low",
15611
+ "device-battery-normal",
15532
15612
  "stream-online",
15533
15613
  "stream-offline",
15534
15614
  "node-online",
@@ -18747,46 +18827,6 @@ var RecentTracksPageSchema = object({
18747
18827
  /** Cursor for the next page, or null when this page is the last. */
18748
18828
  nextCursor: string().nullable()
18749
18829
  });
18750
- var LIST_GROUPS_DEFAULT_LIMIT = 40;
18751
- var LIST_GROUPS_MAX_LIMIT = 100;
18752
- var AnalyticsGroupRecordSchema = object({
18753
- id: string(),
18754
- deviceId: number().int(),
18755
- openedAt: number().int(),
18756
- closedAt: number().int(),
18757
- timestamp: number().int(),
18758
- memberCount: number().int(),
18759
- memberTrackIds: array(string()).readonly(),
18760
- className: string(),
18761
- classes: array(string()).readonly(),
18762
- /** Relative event-media path, or null when the group has no picture yet. */
18763
- mediaUrl: string().nullable(),
18764
- singleton: boolean()
18765
- });
18766
- var AnalyticsGroupMemberSchema = object({
18767
- trackId: string(),
18768
- deviceId: number().int(),
18769
- className: string(),
18770
- firstSeen: number().int(),
18771
- lastSeen: number().int(),
18772
- mediaUrl: string().nullable()
18773
- });
18774
- var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
18775
- var ListGroupsQueryInput = object({
18776
- /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
18777
- deviceIds: array(number()),
18778
- /** Window lower bound on `closedAt` (inclusive). */
18779
- since: number().optional(),
18780
- /** Window upper bound on `openedAt` (inclusive). */
18781
- until: number().optional(),
18782
- limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
18783
- /** Opaque continuation cursor from a previous page's `nextCursor`. */
18784
- cursor: string().optional()
18785
- });
18786
- var ListGroupsPageSchema = object({
18787
- groups: array(AnalyticsGroupRecordSchema).readonly(),
18788
- nextCursor: string().nullable()
18789
- });
18790
18830
  var KEY_EVENTS_DEFAULT_LIMIT = 50;
18791
18831
  var KEY_EVENTS_MAX_LIMIT = 200;
18792
18832
  var KeyEventQueryInput = object({
@@ -18890,9 +18930,7 @@ var TrackCascadeCountsSchema = object({
18890
18930
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
18891
18931
  plates: number().int(),
18892
18932
  /** Per-track CLIP search vectors removed (best-effort). */
18893
- embeddings: number().int(),
18894
- /** Group membership + group rows removed with their last member (best-effort). */
18895
- groups: number().int()
18933
+ embeddings: number().int()
18896
18934
  });
18897
18935
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18898
18936
  var DiskReconcileCountsSchema = object({
@@ -19062,6 +19100,47 @@ var RebuildStatusSchema = object({
19062
19100
  /** Present when the pass ended by throwing. */
19063
19101
  error: string().nullable()
19064
19102
  });
19103
+ /**
19104
+ * Acknowledgement that a debug-media reclaim STARTED.
19105
+ *
19106
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19107
+ * it runs detached and this returns immediately. Awaiting it is how the
19108
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19109
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19110
+ */
19111
+ var MediaReclaimStartResultSchema = object({
19112
+ started: boolean(),
19113
+ /** True when a pass was already running; the new request is ignored. */
19114
+ alreadyRunning: boolean()
19115
+ });
19116
+ var MediaReclaimInputSchema = object({
19117
+ mode: _enum(["report", "reclaim"]).default("report"),
19118
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19119
+ deviceIds: array(number().int()).min(1).optional(),
19120
+ restart: boolean().optional(),
19121
+ pageSize: number().int().min(50).max(5e3).optional(),
19122
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19123
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19124
+ maxBytesPerRun: number().int().min(1).optional(),
19125
+ budgetMinutes: number().int().min(1).max(720).optional(),
19126
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19127
+ graceMinutes: number().int().min(1).max(10080).optional()
19128
+ });
19129
+ var MediaReclaimStatusSchema = object({
19130
+ running: boolean(),
19131
+ mode: _enum(["report", "reclaim"]).nullable(),
19132
+ totalExamined: number(),
19133
+ totalEligible: number(),
19134
+ totalReclaimed: number(),
19135
+ totalBytesReclaimed: number(),
19136
+ totalRefused: number(),
19137
+ /** Device+scope windows finished in this pass. */
19138
+ devicesDone: number(),
19139
+ complete: boolean().nullable(),
19140
+ startedAtMs: number().nullable(),
19141
+ finishedAtMs: number().nullable(),
19142
+ error: string().nullable()
19143
+ });
19065
19144
  var ReplayFrameInputSchema = object({
19066
19145
  timestamp: number(),
19067
19146
  frame: PipelineRunResultBridge
@@ -19100,10 +19179,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19100
19179
  * stationary registry). Default false: the timeline lists passages,
19101
19180
  * not parking records (operator decision, 2026-08-15). */
19102
19181
  includeStationary: boolean().optional()
19103
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
19104
- deviceId: number(),
19105
- groupId: string().min(1)
19106
- }), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
19182
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19107
19183
  kind: "mutation",
19108
19184
  auth: "admin"
19109
19185
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -19203,6 +19279,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19203
19279
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19204
19280
  kind: "query",
19205
19281
  auth: "admin"
19282
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19283
+ kind: "mutation",
19284
+ auth: "admin"
19285
+ }), method(object({}), MediaReclaimStatusSchema, {
19286
+ kind: "query",
19287
+ auth: "admin"
19206
19288
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19207
19289
  kind: "query",
19208
19290
  auth: "admin"
@@ -21173,7 +21255,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21173
21255
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21174
21256
  kind: "mutation",
21175
21257
  auth: "admin"
21176
- });
21258
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21259
+ kind: "mutation",
21260
+ auth: "admin"
21261
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21262
+ kind: "mutation",
21263
+ auth: "admin"
21264
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21177
21265
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21178
21266
  providerId: string().min(1),
21179
21267
  displayName: string().min(1),
@@ -26612,6 +26700,33 @@ var RecordingRebalanceInputSchema = object({
26612
26700
  minMoveGb: number().min(0).optional()
26613
26701
  });
26614
26702
  /**
26703
+ * Operator-facing placement of one camera onto a recordings location.
26704
+ *
26705
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26706
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26707
+ * currently write — the plan, which may disagree with the pin when Auto.
26708
+ */
26709
+ var RecordingDevicePlacementSchema = object({
26710
+ deviceId: number().int(),
26711
+ profile: string(),
26712
+ locationId: string()
26713
+ });
26714
+ var RecordingDevicePinSchema = object({
26715
+ deviceId: number().int(),
26716
+ /** Recordings-class location this camera is pinned to. */
26717
+ locationId: string()
26718
+ });
26719
+ var RecordingPlacementViewSchema = object({
26720
+ assignments: array(RecordingDevicePlacementSchema),
26721
+ pins: array(RecordingDevicePinSchema),
26722
+ defaultLocations: record(string(), string())
26723
+ });
26724
+ var RecordingSetDevicePlacementInputSchema = object({
26725
+ deviceId: number().int(),
26726
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26727
+ locationId: string().nullable()
26728
+ });
26729
+ /**
26615
26730
  * Result of locating footage at a wall-clock instant for one device/profile.
26616
26731
  * `segment` carries the covering segment's window; `gap` reports the forward
26617
26732
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26837,6 +26952,12 @@ method(object({
26837
26952
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26838
26953
  kind: "mutation",
26839
26954
  auth: "admin"
26955
+ }), method(object({}), RecordingPlacementViewSchema, {
26956
+ kind: "query",
26957
+ auth: "admin"
26958
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
26959
+ kind: "mutation",
26960
+ auth: "admin"
26840
26961
  });
26841
26962
  /**
26842
26963
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -30207,6 +30328,12 @@ Object.freeze({
30207
30328
  addonId: null,
30208
30329
  access: "delete"
30209
30330
  },
30331
+ "deviceManager.renameLocation": {
30332
+ capName: "device-manager",
30333
+ capScope: "system",
30334
+ addonId: null,
30335
+ access: "create"
30336
+ },
30210
30337
  "deviceManager.runDeviceAction": {
30211
30338
  capName: "device-manager",
30212
30339
  capScope: "system",
@@ -31899,19 +32026,19 @@ Object.freeze({
31899
32026
  addonId: null,
31900
32027
  access: "view"
31901
32028
  },
31902
- "pipelineAnalytics.getGroup": {
32029
+ "pipelineAnalytics.getKeyEvents": {
31903
32030
  capName: "pipeline-analytics",
31904
32031
  capScope: "device",
31905
32032
  addonId: null,
31906
32033
  access: "view"
31907
32034
  },
31908
- "pipelineAnalytics.getKeyEvents": {
32035
+ "pipelineAnalytics.getKeyEventsBatch": {
31909
32036
  capName: "pipeline-analytics",
31910
32037
  capScope: "device",
31911
32038
  addonId: null,
31912
32039
  access: "view"
31913
32040
  },
31914
- "pipelineAnalytics.getKeyEventsBatch": {
32041
+ "pipelineAnalytics.getMediaReclaimStatus": {
31915
32042
  capName: "pipeline-analytics",
31916
32043
  capScope: "device",
31917
32044
  addonId: null,
@@ -32001,12 +32128,6 @@ Object.freeze({
32001
32128
  addonId: null,
32002
32129
  access: "view"
32003
32130
  },
32004
- "pipelineAnalytics.listGroups": {
32005
- capName: "pipeline-analytics",
32006
- capScope: "device",
32007
- addonId: null,
32008
- access: "view"
32009
- },
32010
32131
  "pipelineAnalytics.listOpsLog": {
32011
32132
  capName: "pipeline-analytics",
32012
32133
  capScope: "device",
@@ -32091,6 +32212,12 @@ Object.freeze({
32091
32212
  addonId: null,
32092
32213
  access: "create"
32093
32214
  },
32215
+ "pipelineAnalytics.reclaimDebugMedia": {
32216
+ capName: "pipeline-analytics",
32217
+ capScope: "device",
32218
+ addonId: null,
32219
+ access: "create"
32220
+ },
32094
32221
  "pipelineAnalytics.reconcileFromDisk": {
32095
32222
  capName: "pipeline-analytics",
32096
32223
  capScope: "device",
@@ -33015,6 +33142,12 @@ Object.freeze({
33015
33142
  addonId: null,
33016
33143
  access: "view"
33017
33144
  },
33145
+ "recording.getPlacement": {
33146
+ capName: "recording",
33147
+ capScope: "system",
33148
+ addonId: null,
33149
+ access: "view"
33150
+ },
33018
33151
  "recording.getPlaybackManifest": {
33019
33152
  capName: "recording",
33020
33153
  capScope: "system",
@@ -33141,6 +33274,12 @@ Object.freeze({
33141
33274
  addonId: null,
33142
33275
  access: "create"
33143
33276
  },
33277
+ "recording.setDevicePlacement": {
33278
+ capName: "recording",
33279
+ capScope: "system",
33280
+ addonId: null,
33281
+ access: "create"
33282
+ },
33144
33283
  "recording.startStorageMigrationMove": {
33145
33284
  capName: "recording",
33146
33285
  capScope: "system",
@@ -33585,12 +33724,36 @@ Object.freeze({
33585
33724
  addonId: null,
33586
33725
  access: "create"
33587
33726
  },
33727
+ "storageMigration.cleanupCancel": {
33728
+ capName: "storage-migration",
33729
+ capScope: "system",
33730
+ addonId: null,
33731
+ access: "create"
33732
+ },
33733
+ "storageMigration.cleanupStart": {
33734
+ capName: "storage-migration",
33735
+ capScope: "system",
33736
+ addonId: null,
33737
+ access: "create"
33738
+ },
33739
+ "storageMigration.cleanupStatus": {
33740
+ capName: "storage-migration",
33741
+ capScope: "system",
33742
+ addonId: null,
33743
+ access: "view"
33744
+ },
33588
33745
  "storageMigration.drain": {
33589
33746
  capName: "storage-migration",
33590
33747
  capScope: "system",
33591
33748
  addonId: null,
33592
33749
  access: "create"
33593
33750
  },
33751
+ "storageMigration.history": {
33752
+ capName: "storage-migration",
33753
+ capScope: "system",
33754
+ addonId: null,
33755
+ access: "view"
33756
+ },
33594
33757
  "storageMigration.movers": {
33595
33758
  capName: "storage-migration",
33596
33759
  capScope: "system",
@@ -35587,11 +35750,6 @@ Object.freeze({
35587
35750
  form: "single",
35588
35751
  optional: true
35589
35752
  }],
35590
- "pipelineAnalytics.getGroup": [{
35591
- name: "deviceId",
35592
- form: "single",
35593
- optional: false
35594
- }],
35595
35753
  "pipelineAnalytics.getKeyEvents": [{
35596
35754
  name: "deviceId",
35597
35755
  form: "single",
@@ -35657,11 +35815,6 @@ Object.freeze({
35657
35815
  form: "single",
35658
35816
  optional: false
35659
35817
  }],
35660
- "pipelineAnalytics.listGroups": [{
35661
- name: "deviceIds",
35662
- form: "array",
35663
- optional: false
35664
- }],
35665
35818
  "pipelineAnalytics.listOpsLog": [{
35666
35819
  name: "deviceId",
35667
35820
  form: "single",
@@ -35707,6 +35860,11 @@ Object.freeze({
35707
35860
  form: "single",
35708
35861
  optional: true
35709
35862
  }],
35863
+ "pipelineAnalytics.reclaimDebugMedia": [{
35864
+ name: "deviceIds",
35865
+ form: "array",
35866
+ optional: true
35867
+ }],
35710
35868
  "pipelineAnalytics.reconcileFromDisk": [{
35711
35869
  name: "deviceId",
35712
35870
  form: "single",
@@ -36072,6 +36230,11 @@ Object.freeze({
36072
36230
  form: "single",
36073
36231
  optional: false
36074
36232
  }],
36233
+ "recording.setDevicePlacement": [{
36234
+ name: "deviceId",
36235
+ form: "single",
36236
+ optional: false
36237
+ }],
36075
36238
  "recording.startStorageMigrationMove": [{
36076
36239
  name: "deviceId",
36077
36240
  form: "single",
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-Cv-ufJXF.js");
5
+ const require_dist = require("../dist-DZmp04sL.js");
6
6
  let node_crypto = require("node:crypto");
7
7
  let node_child_process = require("node:child_process");
8
8
  //#region src/ingress/tailscale-cli.ts
@@ -1,4 +1,4 @@
1
- import { a as EventCategory, i as BaseAddon, n as networkAccessCapability } from "../dist-8Fi7VglU.mjs";
1
+ import { a as EventCategory, i as BaseAddon, n as networkAccessCapability } from "../dist-CLEhB-7g.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-tailscale",
3
- "version": "1.2.49",
3
+ "version": "1.2.51",
4
4
  "description": "Tailscale bundle for CamStack — joins the host to a tailnet (client) and exposes the hub via Serve/Funnel (ingress). Multi-entry npm package shipping 2 addons under a single bundle.",
5
5
  "keywords": [
6
6
  "camstack",