@camstack/addon-agent-ui 1.2.50 → 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.
Files changed (2) hide show
  1. package/dist/addon.js +224 -8
  2. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8099,6 +8099,13 @@ var MediaRelocateModeSchema = _enum([
8099
8099
  ]);
8100
8100
  var RelocateMediaInputSchema = object({
8101
8101
  toLocationId: string(),
8102
+ /**
8103
+ * Restrict the pass to rows currently on this location. Omitted / `'*'` =
8104
+ * every row that is not already on `toLocationId` (the historical
8105
+ * behaviour). A named source is what a from→to migration needs: without it
8106
+ * "move events off disk 2" also emptied disk 1.
8107
+ */
8108
+ fromLocationId: string().optional(),
8102
8109
  throttleMbps: number().min(1).max(1e3).optional(),
8103
8110
  /** Omitted = `move`, the pre-existing behaviour. */
8104
8111
  mode: MediaRelocateModeSchema.optional()
@@ -8166,6 +8173,19 @@ var StorageMigrationDestinationsSchema = object({
8166
8173
  galleryMedia: string().min(1).optional()
8167
8174
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8168
8175
  /**
8176
+ * Optional named source per class. Omitted = the class's current default
8177
+ * (the historical behaviour). A named source that is NOT the default is a
8178
+ * drain of that disk: bytes move, the default stays, and the source is
8179
+ * disabled when the move finishes.
8180
+ */
8181
+ var StorageMigrationSourcesSchema = object({
8182
+ recordings: string().min(1).optional(),
8183
+ recordingsLow: string().min(1).optional(),
8184
+ eventMedia: string().min(1).optional(),
8185
+ backups: string().min(1).optional(),
8186
+ galleryMedia: string().min(1).optional()
8187
+ }).optional();
8188
+ /**
8169
8189
  * How a migration sequences the cutover against the byte move.
8170
8190
  *
8171
8191
  * - `blocking` — the historical order: pause, move every byte, repoint,
@@ -8187,6 +8207,8 @@ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8187
8207
  /** Shared input for planning and starting an orchestrated storage migration. */
8188
8208
  var StorageMigrationInputSchema = object({
8189
8209
  destinations: StorageMigrationDestinationsSchema,
8210
+ /** Omitted = each class's current default. */
8211
+ sources: StorageMigrationSourcesSchema,
8190
8212
  throttleMbps: number().min(1).max(1e3).optional(),
8191
8213
  /** Omitted = `blocking`, which stays the default. */
8192
8214
  mode: StorageMigrationModeSchema.optional()
@@ -8266,6 +8288,13 @@ var StorageMigrationMoveSchema = object({
8266
8288
  storageClass: StorageMigrationClassSchema,
8267
8289
  fromLocationId: string(),
8268
8290
  toLocationId: string(),
8291
+ /**
8292
+ * True when `from` was NOT the class default at plan time. The move still
8293
+ * copies bytes, but the default is left alone and the source is disabled
8294
+ * once the copy verifies. Absent on jobs planned before this field existed
8295
+ * — those jobs always repointed, which is `false`.
8296
+ */
8297
+ freezeSource: boolean().optional(),
8269
8298
  moverJobId: string().nullable(),
8270
8299
  state: RelocateJobStateSchema.nullable(),
8271
8300
  error: string().nullable(),
@@ -8279,6 +8308,7 @@ var StorageMigrationJobSchema = object({
8279
8308
  * can tell a seconds-long cutover from a thirty-hour one. */
8280
8309
  mode: StorageMigrationModeSchema,
8281
8310
  destinations: StorageMigrationDestinationsSchema,
8311
+ sources: StorageMigrationSourcesSchema,
8282
8312
  throttleMbps: number(),
8283
8313
  moves: array(StorageMigrationMoveSchema),
8284
8314
  pauseLeaseId: string().nullable(),
@@ -8304,6 +8334,7 @@ var StorageMigrationFindingSchema = object({
8304
8334
  });
8305
8335
  var StorageMigrationPlanSchema = object({
8306
8336
  destinations: StorageMigrationDestinationsSchema,
8337
+ sources: StorageMigrationSourcesSchema,
8307
8338
  /** The mode this plan was built for. A plan is only valid for its mode: the
8308
8339
  * `eventMedia` seal gate and the single-cardinality refusal both depend on
8309
8340
  * it. */
@@ -8311,7 +8342,8 @@ var StorageMigrationPlanSchema = object({
8311
8342
  moves: array(object({
8312
8343
  storageClass: StorageMigrationClassSchema,
8313
8344
  fromLocationId: string(),
8314
- toLocationId: string()
8345
+ toLocationId: string(),
8346
+ freezeSource: boolean().optional()
8315
8347
  })),
8316
8348
  findings: array(StorageMigrationFindingSchema)
8317
8349
  });
@@ -8489,10 +8521,51 @@ var LedgerWalkReportSchema = object({
8489
8521
  var RelocatableMediaCountSchema = object({ rows: number().int().nonnegative() }).nullable();
8490
8522
  var RelocatableMediaCountInputSchema = object({
8491
8523
  toLocationId: string().min(1),
8524
+ /** Restrict the count to one source; omitted / `'*'` = every non-target row. */
8525
+ fromLocationId: string().optional(),
8492
8526
  /** Omitted = `move`. */
8493
8527
  mode: MediaRelocateModeSchema.optional()
8494
8528
  });
8495
8529
  /**
8530
+ * Operator cleanup of leftover analytics rows, optional debug media, and
8531
+ * ghost ledger entries on frozen footage locations.
8532
+ *
8533
+ * A pass is tens of minutes on a standing backlog. The hub method RETURNS
8534
+ * `{ jobId }` immediately; progress is `cleanupStatus`. Awaiting the work
8535
+ * is how `addons.custom` hit the 60 s UDS deadline while reclaim continued
8536
+ * with no operator-visible status.
8537
+ */
8538
+ var StorageCleanupPhaseSchema = _enum([
8539
+ "orphans",
8540
+ "debug-media",
8541
+ "ghost-ledger",
8542
+ "done",
8543
+ "failed",
8544
+ "cancelled"
8545
+ ]);
8546
+ var StorageCleanupInputSchema = object({
8547
+ /** Also walk motion stills / track filmstrips. Off by default. */
8548
+ includeDebugMedia: boolean().optional() });
8549
+ var StorageCleanupJobSchema = object({
8550
+ jobId: string(),
8551
+ phase: StorageCleanupPhaseSchema,
8552
+ includeDebugMedia: boolean(),
8553
+ orphansReclaimed: number().int().nonnegative(),
8554
+ orphanBytesReclaimed: number().int().nonnegative(),
8555
+ debugMediaReclaimed: number().int().nonnegative(),
8556
+ debugMediaBytesReclaimed: number().int().nonnegative(),
8557
+ ghostsForgotten: number().int().nonnegative(),
8558
+ ghostBytesForgotten: number().int().nonnegative(),
8559
+ /** Short operator-facing line: current collection, pass, or location. */
8560
+ detail: string().nullable(),
8561
+ cancelRequested: boolean(),
8562
+ startedAt: number(),
8563
+ updatedAt: number(),
8564
+ finishedAt: number().nullable(),
8565
+ error: string().nullable()
8566
+ });
8567
+ var StorageCleanupStatusInputSchema = object({ jobId: string().optional() });
8568
+ /**
8496
8569
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
8497
8570
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
8498
8571
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -8520,11 +8593,10 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
8520
8593
  * The default location for a type uses `id === <type>:default` by
8521
8594
  * convention (the bare type ref like `'backups'` resolves to it).
8522
8595
  *
8523
- * `isSystem: true` marks a location as orchestrator-seeded and
8524
- * undeletable. The bootstrap-installed defaults (one per type) carry
8525
- * this flag; operator-added locations don't. Editing the config of
8526
- * a system location is allowed (path migration, provider swap) but
8527
- * deleting it is rejected at the cap level.
8596
+ * `isSystem` is a legacy persisted flag. Seed still creates the initial
8597
+ * `<type>:default` locations; the flag is no longer a lock, a badge, or a
8598
+ * prune selector. New writes leave it false. Deletion is gated on uniqueness
8599
+ * / last-enabled, not on this bit.
8528
8600
  */
8529
8601
  var StorageLocationSchema = object({
8530
8602
  id: string().regex(/^[a-z][a-zA-Z0-9-]*:[a-zA-Z0-9-]+$/),
@@ -19031,6 +19103,47 @@ var RebuildStatusSchema = object({
19031
19103
  /** Present when the pass ended by throwing. */
19032
19104
  error: string().nullable()
19033
19105
  });
19106
+ /**
19107
+ * Acknowledgement that a debug-media reclaim STARTED.
19108
+ *
19109
+ * The pass is paced at ~2 MB/s over a standing 100 GB — tens of minutes — so
19110
+ * it runs detached and this returns immediately. Awaiting it is how the
19111
+ * `addons.custom` door hit the 60 s UDS deadline while the walk carried on
19112
+ * with no status. Poll {@link pipelineAnalyticsCapability.methods.getMediaReclaimStatus}.
19113
+ */
19114
+ var MediaReclaimStartResultSchema = object({
19115
+ started: boolean(),
19116
+ /** True when a pass was already running; the new request is ignored. */
19117
+ alreadyRunning: boolean()
19118
+ });
19119
+ var MediaReclaimInputSchema = object({
19120
+ mode: _enum(["report", "reclaim"]).default("report"),
19121
+ scopes: array(_enum(["motion-still", "track-filmstrip"])).min(1).optional(),
19122
+ deviceIds: array(number().int()).min(1).optional(),
19123
+ restart: boolean().optional(),
19124
+ pageSize: number().int().min(50).max(5e3).optional(),
19125
+ maxRowsPerDevice: number().int().min(1).max(5e5).optional(),
19126
+ maxReclaimPerDevice: number().int().min(1).max(5e5).optional(),
19127
+ maxBytesPerRun: number().int().min(1).optional(),
19128
+ budgetMinutes: number().int().min(1).max(720).optional(),
19129
+ throttleBytesPerSec: number().int().min(64 * 1024).optional(),
19130
+ graceMinutes: number().int().min(1).max(10080).optional()
19131
+ });
19132
+ var MediaReclaimStatusSchema = object({
19133
+ running: boolean(),
19134
+ mode: _enum(["report", "reclaim"]).nullable(),
19135
+ totalExamined: number(),
19136
+ totalEligible: number(),
19137
+ totalReclaimed: number(),
19138
+ totalBytesReclaimed: number(),
19139
+ totalRefused: number(),
19140
+ /** Device+scope windows finished in this pass. */
19141
+ devicesDone: number(),
19142
+ complete: boolean().nullable(),
19143
+ startedAtMs: number().nullable(),
19144
+ finishedAtMs: number().nullable(),
19145
+ error: string().nullable()
19146
+ });
19034
19147
  var ReplayFrameInputSchema = object({
19035
19148
  timestamp: number(),
19036
19149
  frame: PipelineRunResultBridge
@@ -19172,6 +19285,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19172
19285
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19173
19286
  kind: "query",
19174
19287
  auth: "admin"
19288
+ }), method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
19289
+ kind: "mutation",
19290
+ auth: "admin"
19291
+ }), method(object({}), MediaReclaimStatusSchema, {
19292
+ kind: "query",
19293
+ auth: "admin"
19175
19294
  }), method(object({ deviceIds: array(number()).optional() }), TrainingExportSummarySchema, {
19176
19295
  kind: "query",
19177
19296
  auth: "admin"
@@ -21142,7 +21261,13 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
21142
21261
  }), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
21143
21262
  kind: "mutation",
21144
21263
  auth: "admin"
21145
- });
21264
+ }), method(StorageCleanupInputSchema, object({ jobId: string() }), {
21265
+ kind: "mutation",
21266
+ auth: "admin"
21267
+ }), method(StorageCleanupStatusInputSchema, StorageCleanupJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
21268
+ kind: "mutation",
21269
+ auth: "admin"
21270
+ }), method(object({}), array(StorageMigrationJobSchema).readonly(), { auth: "admin" });
21146
21271
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
21147
21272
  providerId: string().min(1),
21148
21273
  displayName: string().min(1),
@@ -26520,6 +26645,33 @@ var RecordingRebalanceInputSchema = object({
26520
26645
  minMoveGb: number().min(0).optional()
26521
26646
  });
26522
26647
  /**
26648
+ * Operator-facing placement of one camera onto a recordings location.
26649
+ *
26650
+ * `pinLocationId` is the operator instruction: a location id, or `null` for
26651
+ * Auto (the planner may move this camera). `locationId` is where high/mid
26652
+ * currently write — the plan, which may disagree with the pin when Auto.
26653
+ */
26654
+ var RecordingDevicePlacementSchema = object({
26655
+ deviceId: number().int(),
26656
+ profile: string(),
26657
+ locationId: string()
26658
+ });
26659
+ var RecordingDevicePinSchema = object({
26660
+ deviceId: number().int(),
26661
+ /** Recordings-class location this camera is pinned to. */
26662
+ locationId: string()
26663
+ });
26664
+ var RecordingPlacementViewSchema = object({
26665
+ assignments: array(RecordingDevicePlacementSchema),
26666
+ pins: array(RecordingDevicePinSchema),
26667
+ defaultLocations: record(string(), string())
26668
+ });
26669
+ var RecordingSetDevicePlacementInputSchema = object({
26670
+ deviceId: number().int(),
26671
+ /** `null` = Auto. Otherwise a `recordings:*` location id. */
26672
+ locationId: string().nullable()
26673
+ });
26674
+ /**
26523
26675
  * Result of locating footage at a wall-clock instant for one device/profile.
26524
26676
  * `segment` carries the covering segment's window; `gap` reports the forward
26525
26677
  * nearest covered edge (`null` past the end of footage / when none exists)
@@ -26745,6 +26897,12 @@ method(object({
26745
26897
  }), method(RecordingRebalanceInputSchema, RecordingRebalancePlanSchema, {
26746
26898
  kind: "mutation",
26747
26899
  auth: "admin"
26900
+ }), method(object({}), RecordingPlacementViewSchema, {
26901
+ kind: "query",
26902
+ auth: "admin"
26903
+ }), method(RecordingSetDevicePlacementInputSchema, object({ ok: literal(true) }), {
26904
+ kind: "mutation",
26905
+ auth: "admin"
26748
26906
  });
26749
26907
  /**
26750
26908
  * `recording-export` cap — render a footage time range into a single downloadable
@@ -31825,6 +31983,12 @@ Object.freeze({
31825
31983
  addonId: null,
31826
31984
  access: "view"
31827
31985
  },
31986
+ "pipelineAnalytics.getMediaReclaimStatus": {
31987
+ capName: "pipeline-analytics",
31988
+ capScope: "device",
31989
+ addonId: null,
31990
+ access: "view"
31991
+ },
31828
31992
  "pipelineAnalytics.getMotionEvents": {
31829
31993
  capName: "pipeline-analytics",
31830
31994
  capScope: "device",
@@ -31999,6 +32163,12 @@ Object.freeze({
31999
32163
  addonId: null,
32000
32164
  access: "create"
32001
32165
  },
32166
+ "pipelineAnalytics.reclaimDebugMedia": {
32167
+ capName: "pipeline-analytics",
32168
+ capScope: "device",
32169
+ addonId: null,
32170
+ access: "create"
32171
+ },
32002
32172
  "pipelineAnalytics.reconcileFromDisk": {
32003
32173
  capName: "pipeline-analytics",
32004
32174
  capScope: "device",
@@ -32923,6 +33093,12 @@ Object.freeze({
32923
33093
  addonId: null,
32924
33094
  access: "view"
32925
33095
  },
33096
+ "recording.getPlacement": {
33097
+ capName: "recording",
33098
+ capScope: "system",
33099
+ addonId: null,
33100
+ access: "view"
33101
+ },
32926
33102
  "recording.getPlaybackManifest": {
32927
33103
  capName: "recording",
32928
33104
  capScope: "system",
@@ -33049,6 +33225,12 @@ Object.freeze({
33049
33225
  addonId: null,
33050
33226
  access: "create"
33051
33227
  },
33228
+ "recording.setDevicePlacement": {
33229
+ capName: "recording",
33230
+ capScope: "system",
33231
+ addonId: null,
33232
+ access: "create"
33233
+ },
33052
33234
  "recording.startStorageMigrationMove": {
33053
33235
  capName: "recording",
33054
33236
  capScope: "system",
@@ -33493,12 +33675,36 @@ Object.freeze({
33493
33675
  addonId: null,
33494
33676
  access: "create"
33495
33677
  },
33678
+ "storageMigration.cleanupCancel": {
33679
+ capName: "storage-migration",
33680
+ capScope: "system",
33681
+ addonId: null,
33682
+ access: "create"
33683
+ },
33684
+ "storageMigration.cleanupStart": {
33685
+ capName: "storage-migration",
33686
+ capScope: "system",
33687
+ addonId: null,
33688
+ access: "create"
33689
+ },
33690
+ "storageMigration.cleanupStatus": {
33691
+ capName: "storage-migration",
33692
+ capScope: "system",
33693
+ addonId: null,
33694
+ access: "view"
33695
+ },
33496
33696
  "storageMigration.drain": {
33497
33697
  capName: "storage-migration",
33498
33698
  capScope: "system",
33499
33699
  addonId: null,
33500
33700
  access: "create"
33501
33701
  },
33702
+ "storageMigration.history": {
33703
+ capName: "storage-migration",
33704
+ capScope: "system",
33705
+ addonId: null,
33706
+ access: "view"
33707
+ },
33502
33708
  "storageMigration.movers": {
33503
33709
  capName: "storage-migration",
33504
33710
  capScope: "system",
@@ -35615,6 +35821,11 @@ Object.freeze({
35615
35821
  form: "single",
35616
35822
  optional: true
35617
35823
  }],
35824
+ "pipelineAnalytics.reclaimDebugMedia": [{
35825
+ name: "deviceIds",
35826
+ form: "array",
35827
+ optional: true
35828
+ }],
35618
35829
  "pipelineAnalytics.reconcileFromDisk": [{
35619
35830
  name: "deviceId",
35620
35831
  form: "single",
@@ -35980,6 +36191,11 @@ Object.freeze({
35980
36191
  form: "single",
35981
36192
  optional: false
35982
36193
  }],
36194
+ "recording.setDevicePlacement": [{
36195
+ name: "deviceId",
36196
+ form: "single",
36197
+ optional: false
36198
+ }],
35983
36199
  "recording.startStorageMigrationMove": [{
35984
36200
  name: "deviceId",
35985
36201
  form: "single",
@@ -36844,7 +37060,7 @@ var AgentUIAddon = class extends BaseAddon {
36844
37060
  capability: adminUiCapability,
36845
37061
  provider: {
36846
37062
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
36847
- getVersion: async () => ({ version: "1.2.50" })
37063
+ getVersion: async () => ({ version: "1.2.51" })
36848
37064
  }
36849
37065
  }];
36850
37066
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-agent-ui",
3
- "version": "1.2.50",
3
+ "version": "1.2.51",
4
4
  "description": "Agent UI — lightweight status dashboard served by every agent node",
5
5
  "keywords": [
6
6
  "camstack",