@camstack/addon-pipeline-orchestrator 1.2.44 → 1.2.45

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.
package/dist/index.mjs CHANGED
@@ -8365,12 +8365,11 @@ var RecordingConfigSchema = object({
8365
8365
  /**
8366
8366
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
8367
8367
  *
8368
- * One shape shared by the recorder's `relocateFootage` (segments) and
8369
- * pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
8370
- * page renders both movers with one component. Jobs are in-RAM (a restart
8371
- * forgets them re-running is safe by construction: copy-if-absent, delete
8372
- * after verify) and each completed/failed run also lands one durable ops-log
8373
- * row on the owning addon's surface.
8368
+ * One shape shared by the recorder and pipeline-analytics internal movers.
8369
+ * The public admin surface is `storage-migration`; child jobs remain in RAM
8370
+ * because copy-if-absent, verify, delete and index/row repoint are resumable.
8371
+ * Each completed/failed run also lands one durable ops-log row on its owning
8372
+ * addon surface.
8374
8373
  */
8375
8374
  var RelocateJobStateSchema = _enum([
8376
8375
  "running",
@@ -8397,19 +8396,100 @@ var RelocateJobSchema = object({
8397
8396
  finishedAt: number().nullable(),
8398
8397
  error: string().nullable()
8399
8398
  });
8399
+ /** Profile-derived footage selection used only by the migration coordinator:
8400
+ * `recordings` owns high+mid; `recordingsLow` owns low. */
8401
+ var RelocateFootageClassSchema = _enum(["recordings", "recordingsLow"]);
8400
8402
  var RelocateFootageInputSchema = object({
8401
- deviceId: number().optional(),
8402
8403
  fromLocationId: string(),
8403
8404
  toLocationId: string(),
8404
8405
  entities: array(_enum(["segments"])).optional(),
8406
+ /** Limits relocation to the logical profile class. Omit only for the
8407
+ * pre-orchestration compatibility path. */
8408
+ footageClass: RelocateFootageClassSchema.optional(),
8405
8409
  /** Copy throttle in MB/s (default 40) — the drain is a background chore,
8406
8410
  * never allowed to starve live writers. */
8407
8411
  throttleMbps: number().min(1).max(1e3).optional()
8408
8412
  });
8409
- var RelocateMediaInputSchema = object({
8410
- deviceId: number().optional(),
8413
+ /** Internal, lease-scoped participant operation. It is intentionally separate
8414
+ * from persistent recording settings: a migration never changes
8415
+ * `RecordingConfig.enabled` or camera wrapper bindings. */
8416
+ var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8417
+ var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8418
+ var StorageMigrationMediaMoveInputSchema = object({
8411
8419
  toLocationId: string(),
8412
8420
  throttleMbps: number().min(1).max(1e3).optional()
8421
+ }).extend({ leaseId: string().min(1) });
8422
+ /** The independently selectable logical storage classes. `recordings`
8423
+ * encompasses the high and mid segment profiles; `recordingsLow` is low
8424
+ * segments; `eventMedia` is post-analysis blobs. */
8425
+ var StorageMigrationClassSchema = _enum([
8426
+ "recordings",
8427
+ "recordingsLow",
8428
+ "eventMedia"
8429
+ ]);
8430
+ /** A destination is always an existing, fully-qualified location id. The
8431
+ * migration API intentionally never changes a source location's `basePath`:
8432
+ * callers create a new `<type>:<slug>` location, then select it here. */
8433
+ var StorageMigrationDestinationsSchema = object({
8434
+ recordings: string().min(1).optional(),
8435
+ recordingsLow: string().min(1).optional(),
8436
+ eventMedia: string().min(1).optional()
8437
+ }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8438
+ /** Shared input for planning and starting an orchestrated storage migration. */
8439
+ var StorageMigrationInputSchema = object({
8440
+ destinations: StorageMigrationDestinationsSchema,
8441
+ throttleMbps: number().min(1).max(1e3).optional()
8442
+ });
8443
+ /** The durable coordinator state machine. The only phase that changes default
8444
+ * locations is `repointing`, after every selected mover has completed and been
8445
+ * verified. */
8446
+ var StorageMigrationPhaseSchema = _enum([
8447
+ "planning",
8448
+ "pausing",
8449
+ "moving",
8450
+ "verifying",
8451
+ "repointing",
8452
+ "refreshing",
8453
+ "resuming",
8454
+ "done",
8455
+ "failed",
8456
+ "cancelled"
8457
+ ]);
8458
+ var StorageMigrationParticipantSchema = _enum([
8459
+ "pipeline",
8460
+ "recorder",
8461
+ "analytics"
8462
+ ]);
8463
+ var StorageMigrationMoveSchema = object({
8464
+ storageClass: StorageMigrationClassSchema,
8465
+ fromLocationId: string(),
8466
+ toLocationId: string(),
8467
+ moverJobId: string().nullable(),
8468
+ state: RelocateJobStateSchema.nullable(),
8469
+ error: string().nullable()
8470
+ });
8471
+ var StorageMigrationJobSchema = object({
8472
+ jobId: string(),
8473
+ phase: StorageMigrationPhaseSchema,
8474
+ destinations: StorageMigrationDestinationsSchema,
8475
+ throttleMbps: number(),
8476
+ moves: array(StorageMigrationMoveSchema),
8477
+ pauseLeaseId: string().nullable(),
8478
+ pausedParticipants: array(StorageMigrationParticipantSchema),
8479
+ repointed: boolean(),
8480
+ cancelRequested: boolean(),
8481
+ startedAt: number(),
8482
+ updatedAt: number(),
8483
+ finishedAt: number().nullable(),
8484
+ error: string().nullable()
8485
+ });
8486
+ var StorageMigrationPlanSchema = object({
8487
+ destinations: StorageMigrationDestinationsSchema,
8488
+ moves: array(object({
8489
+ storageClass: StorageMigrationClassSchema,
8490
+ fromLocationId: string(),
8491
+ toLocationId: string()
8492
+ }))
8413
8493
  });
8414
8494
  /**
8415
8495
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -16851,13 +16931,19 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
16851
16931
  }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
16852
16932
  kind: "mutation",
16853
16933
  auth: "admin"
16854
- }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
16934
+ }), method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
16855
16935
  kind: "mutation",
16856
16936
  auth: "admin"
16857
- }), method(object({}), array(RelocateJobSchema).readonly(), {
16858
- kind: "query",
16937
+ }), method(StorageMigrationLeaseInputSchema, object({ resumed: literal(true) }), {
16938
+ kind: "mutation",
16859
16939
  auth: "admin"
16860
- }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
16940
+ }), method(StorageMigrationLeaseInputSchema, object({ refreshed: literal(true) }), {
16941
+ kind: "mutation",
16942
+ auth: "admin"
16943
+ }), method(StorageMigrationMediaMoveInputSchema, object({ jobId: string() }), {
16944
+ kind: "mutation",
16945
+ auth: "admin"
16946
+ }), method(object({ jobId: string() }), RelocateJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
16861
16947
  kind: "mutation",
16862
16948
  auth: "admin"
16863
16949
  }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
@@ -18697,6 +18783,16 @@ var pipelineOrchestratorCapability = {
18697
18783
  nodeIdMode: "data",
18698
18784
  exposesDeviceSettings: true,
18699
18785
  methods: {
18786
+ /** Internal storage-migration participant lease. While held, dispatch
18787
+ * requests are accepted as pending but no new runner attachment starts. */
18788
+ pauseForStorageMigration: method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
18789
+ kind: "mutation",
18790
+ auth: "admin"
18791
+ }),
18792
+ resumeForStorageMigration: method(StorageMigrationLeaseInputSchema, object({ resumed: literal(true) }), {
18793
+ kind: "mutation",
18794
+ auth: "admin"
18795
+ }),
18700
18796
  /**
18701
18797
  * Pin a camera's pipeline to a specific agent (L1 affinity).
18702
18798
  * The orchestrator re-evaluates the assignment immediately and persists
@@ -19644,6 +19740,13 @@ method(object({ locationId: string() }), EvictableUsageSchema), method(object({
19644
19740
  locationId: string(),
19645
19741
  targetBytes: number().int().positive()
19646
19742
  }), EvictResultSchema, { kind: "mutation" });
19743
+ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin" }), method(StorageMigrationInputSchema, object({ jobId: string() }), {
19744
+ kind: "mutation",
19745
+ auth: "admin"
19746
+ }), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
19747
+ kind: "mutation",
19748
+ auth: "admin"
19749
+ });
19647
19750
  var ProviderInfoSchema = discriminatedUnion("shouldSaveDiskSpace", [object({
19648
19751
  providerId: string().min(1),
19649
19752
  displayName: string().min(1),
@@ -19747,6 +19850,28 @@ var TerminalProfileInfoSchema = object({
19747
19850
  label: string(),
19748
19851
  description: string().optional()
19749
19852
  });
19853
+ /**
19854
+ * A durable operator-created Terminal instance. Profiles are templates; only
19855
+ * an instance declares a camera.
19856
+ */
19857
+ var TerminalInstanceInfoSchema = object({
19858
+ instanceId: string(),
19859
+ cameraStableId: string(),
19860
+ nodeId: string(),
19861
+ profileId: string(),
19862
+ profileLabel: string(),
19863
+ name: string(),
19864
+ enabled: boolean()
19865
+ });
19866
+ var TerminalLegacyCameraSchema = object({
19867
+ stableId: string(),
19868
+ nodeId: string(),
19869
+ profileId: string(),
19870
+ profileLabel: string(),
19871
+ name: string(),
19872
+ /** Only legacy monitor cameras can retain their historic stable identity. */
19873
+ adoptable: boolean()
19874
+ });
19750
19875
  var TerminalOutputEventSchema = discriminatedUnion("kind", [object({
19751
19876
  seq: number().int().positive(),
19752
19877
  kind: literal("data"),
@@ -19763,7 +19888,29 @@ var TerminalOutputBatchSchema = object({
19763
19888
  snapshot: string().optional(),
19764
19889
  events: array(TerminalOutputEventSchema).readonly()
19765
19890
  });
19766
- method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19891
+ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19892
+ targetNodeId: string().min(1),
19893
+ profileId: string().min(1),
19894
+ name: string().trim().min(1).max(160).optional()
19895
+ }), TerminalInstanceInfoSchema, {
19896
+ kind: "mutation",
19897
+ auth: "admin"
19898
+ }), method(object({ instanceId: string().min(1) }), _void(), {
19899
+ kind: "mutation",
19900
+ auth: "admin"
19901
+ }), method(object({
19902
+ instanceId: string().min(1),
19903
+ enabled: boolean()
19904
+ }), TerminalInstanceInfoSchema, {
19905
+ kind: "mutation",
19906
+ auth: "admin"
19907
+ }), method(_void(), array(TerminalLegacyCameraSchema).readonly(), { auth: "admin" }), method(object({
19908
+ stableId: string().min(1),
19909
+ name: string().trim().min(1).max(160).optional()
19910
+ }), TerminalInstanceInfoSchema, {
19911
+ kind: "mutation",
19912
+ auth: "admin"
19913
+ }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
19767
19914
  profileId: string(),
19768
19915
  cols: number().int().positive(),
19769
19916
  rows: number().int().positive()
@@ -19780,7 +19927,13 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
19780
19927
  }), method(object({
19781
19928
  sessionId: string(),
19782
19929
  afterSeq: number().int().nonnegative(),
19783
- waitMs: number().int().min(0).max(2e3).default(0)
19930
+ waitMs: number().int().min(0).max(2e3).default(0),
19931
+ /**
19932
+ * Wait when a just-opened session has no output yet. Kept opt-in so a
19933
+ * browser's initial repaint remains immediate; the camera snapshot
19934
+ * relay uses it to avoid encoding a blank startup frame.
19935
+ */
19936
+ waitForOutput: boolean().optional()
19784
19937
  }), TerminalOutputBatchSchema, {
19785
19938
  kind: "mutation",
19786
19939
  auth: "admin",
@@ -21721,6 +21874,7 @@ var FaceInfoSchema = object({
21721
21874
  var FaceFilterEnum = _enum([
21722
21875
  "unassigned",
21723
21876
  "recognized",
21877
+ "identified",
21724
21878
  "all"
21725
21879
  ]);
21726
21880
  var MediaFileLiteSchema$1 = object({
@@ -21749,6 +21903,8 @@ method(_void(), array(IdentitySchema).readonly()), method(object({ name: string(
21749
21903
  kind: "mutation",
21750
21904
  auth: "admin"
21751
21905
  }), method(object({
21906
+ /** Restrict to one camera. Absent keeps the cluster-wide gallery view. */
21907
+ deviceId: number().int().optional(),
21752
21908
  limit: number().int().positive().optional(),
21753
21909
  filter: FaceFilterEnum.optional(),
21754
21910
  /**
@@ -23514,6 +23670,10 @@ var OsdSourceSchema = discriminatedUnion("kind", [
23514
23670
  capName: string().min(1).max(64),
23515
23671
  /** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
23516
23672
  valuePath: string().min(1).max(64)
23673
+ }),
23674
+ object({
23675
+ kind: literal("latest-recognition"),
23676
+ recognition: _enum(["person", "plate"])
23517
23677
  })
23518
23678
  ]);
23519
23679
  var OsdSlotBindingSchema = object({
@@ -23619,6 +23779,15 @@ method(object({ deviceId: number().int() }), object({
23619
23779
  }), object({ success: literal(true) }), {
23620
23780
  kind: "mutation",
23621
23781
  auth: "admin"
23782
+ }), method(object({
23783
+ sourceDeviceId: number().int(),
23784
+ targetDeviceId: number().int()
23785
+ }), object({
23786
+ copied: number().int().nonnegative(),
23787
+ skipped: number().int().nonnegative()
23788
+ }), {
23789
+ kind: "mutation",
23790
+ auth: "admin"
23622
23791
  }), method(object({
23623
23792
  deviceId: number().int(),
23624
23793
  slotId: string().min(1),
@@ -24504,13 +24673,19 @@ method(object({
24504
24673
  }), {
24505
24674
  kind: "mutation",
24506
24675
  auth: "admin"
24507
- }), method(RelocateFootageInputSchema, object({ jobId: string() }), {
24676
+ }), method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
24508
24677
  kind: "mutation",
24509
24678
  auth: "admin"
24510
- }), method(object({}), array(RelocateJobSchema).readonly(), {
24511
- kind: "query",
24679
+ }), method(StorageMigrationLeaseInputSchema, object({ resumed: literal(true) }), {
24680
+ kind: "mutation",
24681
+ auth: "admin"
24682
+ }), method(StorageMigrationLeaseInputSchema, object({ refreshed: literal(true) }), {
24683
+ kind: "mutation",
24512
24684
  auth: "admin"
24513
- }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
24685
+ }), method(StorageMigrationFootageMoveInputSchema, object({ jobId: string() }), {
24686
+ kind: "mutation",
24687
+ auth: "admin"
24688
+ }), method(object({ jobId: string() }), RelocateJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
24514
24689
  kind: "mutation",
24515
24690
  auth: "admin"
24516
24691
  });
@@ -28709,6 +28884,12 @@ Object.freeze({
28709
28884
  addonId: null,
28710
28885
  access: "delete"
28711
28886
  },
28887
+ "osdManager.copyDeviceConfiguration": {
28888
+ capName: "osd-manager",
28889
+ capScope: "system",
28890
+ addonId: null,
28891
+ access: "create"
28892
+ },
28712
28893
  "osdManager.getConditionSupport": {
28713
28894
  capName: "osd-manager",
28714
28895
  capScope: "system",
@@ -28805,7 +28986,7 @@ Object.freeze({
28805
28986
  addonId: null,
28806
28987
  access: "create"
28807
28988
  },
28808
- "pipelineAnalytics.cancelMediaRelocate": {
28989
+ "pipelineAnalytics.cancelStorageMigrationMove": {
28809
28990
  capName: "pipeline-analytics",
28810
28991
  capScope: "device",
28811
28992
  addonId: null,
@@ -28877,12 +29058,6 @@ Object.freeze({
28877
29058
  addonId: null,
28878
29059
  access: "view"
28879
29060
  },
28880
- "pipelineAnalytics.getMediaRelocateStatus": {
28881
- capName: "pipeline-analytics",
28882
- capScope: "device",
28883
- addonId: null,
28884
- access: "view"
28885
- },
28886
29061
  "pipelineAnalytics.getMotionEvents": {
28887
29062
  capName: "pipeline-analytics",
28888
29063
  capScope: "device",
@@ -28919,6 +29094,12 @@ Object.freeze({
28919
29094
  addonId: null,
28920
29095
  access: "view"
28921
29096
  },
29097
+ "pipelineAnalytics.getStorageMigrationMoveStatus": {
29098
+ capName: "pipeline-analytics",
29099
+ capScope: "device",
29100
+ addonId: null,
29101
+ access: "view"
29102
+ },
28922
29103
  "pipelineAnalytics.getTrack": {
28923
29104
  capName: "pipeline-analytics",
28924
29105
  capScope: "device",
@@ -28997,6 +29178,12 @@ Object.freeze({
28997
29178
  addonId: null,
28998
29179
  access: "view"
28999
29180
  },
29181
+ "pipelineAnalytics.pauseForStorageMigration": {
29182
+ capName: "pipeline-analytics",
29183
+ capScope: "device",
29184
+ addonId: null,
29185
+ access: "create"
29186
+ },
29000
29187
  "pipelineAnalytics.proposeRetrainAnnotations": {
29001
29188
  capName: "pipeline-analytics",
29002
29189
  capScope: "device",
@@ -29027,7 +29214,7 @@ Object.freeze({
29027
29214
  addonId: null,
29028
29215
  access: "create"
29029
29216
  },
29030
- "pipelineAnalytics.relocateMedia": {
29217
+ "pipelineAnalytics.refreshStorageLocationsForMigration": {
29031
29218
  capName: "pipeline-analytics",
29032
29219
  capScope: "device",
29033
29220
  addonId: null,
@@ -29039,6 +29226,12 @@ Object.freeze({
29039
29226
  addonId: null,
29040
29227
  access: "create"
29041
29228
  },
29229
+ "pipelineAnalytics.resumeForStorageMigration": {
29230
+ capName: "pipeline-analytics",
29231
+ capScope: "device",
29232
+ addonId: null,
29233
+ access: "create"
29234
+ },
29042
29235
  "pipelineAnalytics.saveRetrainAnnotations": {
29043
29236
  capName: "pipeline-analytics",
29044
29237
  capScope: "device",
@@ -29063,6 +29256,12 @@ Object.freeze({
29063
29256
  addonId: null,
29064
29257
  access: "create"
29065
29258
  },
29259
+ "pipelineAnalytics.startStorageMigrationMove": {
29260
+ capName: "pipeline-analytics",
29261
+ capScope: "device",
29262
+ addonId: null,
29263
+ access: "create"
29264
+ },
29066
29265
  "pipelineAnalytics.wipeAllAnalytics": {
29067
29266
  capName: "pipeline-analytics",
29068
29267
  capScope: "device",
@@ -29429,6 +29628,12 @@ Object.freeze({
29429
29628
  addonId: null,
29430
29629
  access: "view"
29431
29630
  },
29631
+ "pipelineOrchestrator.pauseForStorageMigration": {
29632
+ capName: "pipeline-orchestrator",
29633
+ capScope: "system",
29634
+ addonId: null,
29635
+ access: "create"
29636
+ },
29432
29637
  "pipelineOrchestrator.rebalance": {
29433
29638
  capName: "pipeline-orchestrator",
29434
29639
  capScope: "system",
@@ -29453,6 +29658,12 @@ Object.freeze({
29453
29658
  addonId: null,
29454
29659
  access: "view"
29455
29660
  },
29661
+ "pipelineOrchestrator.resumeForStorageMigration": {
29662
+ capName: "pipeline-orchestrator",
29663
+ capScope: "system",
29664
+ addonId: null,
29665
+ access: "create"
29666
+ },
29456
29667
  "pipelineOrchestrator.saveTemplate": {
29457
29668
  capName: "pipeline-orchestrator",
29458
29669
  capScope: "system",
@@ -29849,7 +30060,7 @@ Object.freeze({
29849
30060
  addonId: null,
29850
30061
  access: "create"
29851
30062
  },
29852
- "recording.cancelRelocate": {
30063
+ "recording.cancelStorageMigrationMove": {
29853
30064
  capName: "recording",
29854
30065
  capScope: "system",
29855
30066
  addonId: null,
@@ -29885,7 +30096,7 @@ Object.freeze({
29885
30096
  addonId: null,
29886
30097
  access: "view"
29887
30098
  },
29888
- "recording.getRelocateStatus": {
30099
+ "recording.getStorageMigrationMoveStatus": {
29889
30100
  capName: "recording",
29890
30101
  capScope: "system",
29891
30102
  addonId: null,
@@ -29909,6 +30120,12 @@ Object.freeze({
29909
30120
  addonId: null,
29910
30121
  access: "view"
29911
30122
  },
30123
+ "recording.pauseForStorageMigration": {
30124
+ capName: "recording",
30125
+ capScope: "system",
30126
+ addonId: null,
30127
+ access: "create"
30128
+ },
29912
30129
  "recording.pruneFootage": {
29913
30130
  capName: "recording",
29914
30131
  capScope: "system",
@@ -29927,7 +30144,7 @@ Object.freeze({
29927
30144
  addonId: null,
29928
30145
  access: "view"
29929
30146
  },
29930
- "recording.relocateFootage": {
30147
+ "recording.refreshStorageLocationsForMigration": {
29931
30148
  capName: "recording",
29932
30149
  capScope: "system",
29933
30150
  addonId: null,
@@ -29951,12 +30168,24 @@ Object.freeze({
29951
30168
  addonId: null,
29952
30169
  access: "create"
29953
30170
  },
30171
+ "recording.resumeForStorageMigration": {
30172
+ capName: "recording",
30173
+ capScope: "system",
30174
+ addonId: null,
30175
+ access: "create"
30176
+ },
29954
30177
  "recording.setDeviceConfig": {
29955
30178
  capName: "recording",
29956
30179
  capScope: "system",
29957
30180
  addonId: null,
29958
30181
  access: "create"
29959
30182
  },
30183
+ "recording.startStorageMigrationMove": {
30184
+ capName: "recording",
30185
+ capScope: "system",
30186
+ addonId: null,
30187
+ access: "create"
30188
+ },
29960
30189
  "recordingExport.cancelExport": {
29961
30190
  capName: "recordingExport",
29962
30191
  capScope: "system",
@@ -30347,6 +30576,30 @@ Object.freeze({
30347
30576
  addonId: null,
30348
30577
  access: "view"
30349
30578
  },
30579
+ "storageMigration.cancel": {
30580
+ capName: "storage-migration",
30581
+ capScope: "system",
30582
+ addonId: null,
30583
+ access: "create"
30584
+ },
30585
+ "storageMigration.plan": {
30586
+ capName: "storage-migration",
30587
+ capScope: "system",
30588
+ addonId: null,
30589
+ access: "view"
30590
+ },
30591
+ "storageMigration.start": {
30592
+ capName: "storage-migration",
30593
+ capScope: "system",
30594
+ addonId: null,
30595
+ access: "create"
30596
+ },
30597
+ "storageMigration.status": {
30598
+ capName: "storage-migration",
30599
+ capScope: "system",
30600
+ addonId: null,
30601
+ access: "view"
30602
+ },
30350
30603
  "storageProvider.abortUpload": {
30351
30604
  capName: "storage-provider",
30352
30605
  capScope: "system",
@@ -30725,12 +30978,42 @@ Object.freeze({
30725
30978
  addonId: null,
30726
30979
  access: "create"
30727
30980
  },
30981
+ "terminalSession.adoptLegacyMonitor": {
30982
+ capName: "terminal-session",
30983
+ capScope: "system",
30984
+ addonId: null,
30985
+ access: "create"
30986
+ },
30728
30987
  "terminalSession.close": {
30729
30988
  capName: "terminal-session",
30730
30989
  capScope: "system",
30731
30990
  addonId: null,
30732
30991
  access: "create"
30733
30992
  },
30993
+ "terminalSession.createInstance": {
30994
+ capName: "terminal-session",
30995
+ capScope: "system",
30996
+ addonId: null,
30997
+ access: "create"
30998
+ },
30999
+ "terminalSession.deleteInstance": {
31000
+ capName: "terminal-session",
31001
+ capScope: "system",
31002
+ addonId: null,
31003
+ access: "delete"
31004
+ },
31005
+ "terminalSession.listInstances": {
31006
+ capName: "terminal-session",
31007
+ capScope: "system",
31008
+ addonId: null,
31009
+ access: "view"
31010
+ },
31011
+ "terminalSession.listLegacyCameras": {
31012
+ capName: "terminal-session",
31013
+ capScope: "system",
31014
+ addonId: null,
31015
+ access: "view"
31016
+ },
30734
31017
  "terminalSession.listProfiles": {
30735
31018
  capName: "terminal-session",
30736
31019
  capScope: "system",
@@ -30761,6 +31044,12 @@ Object.freeze({
30761
31044
  addonId: null,
30762
31045
  access: "create"
30763
31046
  },
31047
+ "terminalSession.setInstanceEnabled": {
31048
+ capName: "terminal-session",
31049
+ capScope: "system",
31050
+ addonId: null,
31051
+ access: "create"
31052
+ },
30764
31053
  "terminalSession.writeInput": {
30765
31054
  capName: "terminal-session",
30766
31055
  capScope: "system",
@@ -35715,11 +36004,17 @@ var PlacementService = class {
35715
36004
  deps;
35716
36005
  /** True while an auto-rebalance pass is running (skip overlap). */
35717
36006
  autoRebalanceInFlight = false;
36007
+ inFlightAttaches = 0;
36008
+ idleWaiters = [];
35718
36009
  constructor(deps) {
35719
36010
  this.deps = deps;
35720
36011
  }
35721
36012
  async dispatchCamera(runnerConfig) {
35722
36013
  if (!this.deps.ctx()) throw new Error("PipelineOrchestrator: dispatchCamera called before initialize");
36014
+ if (this.deps.maintenancePaused?.() === true) return {
36015
+ success: true,
36016
+ kind: "pending"
36017
+ };
35723
36018
  const currentDeviceKey = this.deps.ledger.getConfig(runnerConfig.deviceId)?.deviceKey ?? null;
35724
36019
  this.deps.ledger.setConfig(runnerConfig.deviceId, runnerConfig);
35725
36020
  if (this.deps.loadShed.dispatchDeferralCheck(runnerConfig.deviceId)) return {
@@ -36110,6 +36405,7 @@ var PlacementService = class {
36110
36405
  * an absent field would produce.
36111
36406
  */
36112
36407
  async attachOn(nodeId, config) {
36408
+ if (this.deps.maintenancePaused?.() === true) throw new Error("pipeline dispatch is paused for storage migration");
36113
36409
  const ctx = this.deps.ctx();
36114
36410
  const api = ctx.api;
36115
36411
  if (!api) throw new Error(`attachOn(${nodeId}, ${config.deviceId}): this.ctx.api not available`);
@@ -36144,6 +36440,7 @@ var PlacementService = class {
36144
36440
  meta: logMeta
36145
36441
  });
36146
36442
  }).catch(() => {});
36443
+ this.inFlightAttaches++;
36147
36444
  try {
36148
36445
  await api.pipelineRunner.attachCamera.mutate({
36149
36446
  ...config,
@@ -36173,8 +36470,17 @@ var PlacementService = class {
36173
36470
  });
36174
36471
  }
36175
36472
  throw err;
36473
+ } finally {
36474
+ this.inFlightAttaches--;
36475
+ if (this.inFlightAttaches === 0) for (const resolve of this.idleWaiters.splice(0)) resolve();
36176
36476
  }
36177
36477
  }
36478
+ /** Wait until every attach that began before the maintenance gate closed has
36479
+ * settled. New attaches are rejected at the top of `attachOn`. */
36480
+ waitForMigrationIdle() {
36481
+ if (this.inFlightAttaches === 0) return Promise.resolve();
36482
+ return new Promise((resolve) => this.idleWaiters.push(resolve));
36483
+ }
36178
36484
  async detachOn(nodeId, deviceId) {
36179
36485
  const api = this.deps.ctx().api;
36180
36486
  if (!api) return;
@@ -40071,7 +40377,8 @@ async function buildOrchestratorControllers(deps) {
40071
40377
  activeSessionNode: (deviceId) => session.activeSessionNode(deviceId),
40072
40378
  closeActiveSession: (deviceId) => session.closeSessionForReassign(deviceId),
40073
40379
  reconcilePlacementFromRunners: () => reconcile.reconcilePlacementFromRunners(),
40074
- emitResolvedCameraUpdated: (deviceId) => deps.emitResolvedCameraUpdated(deviceId)
40380
+ emitResolvedCameraUpdated: (deviceId) => deps.emitResolvedCameraUpdated(deviceId),
40381
+ maintenancePaused: () => deps.maintenancePaused()
40075
40382
  });
40076
40383
  const session = new SessionDispatchController({
40077
40384
  ledger,
@@ -41096,6 +41403,9 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
41096
41403
  /** Periodic auto-rebalance sweep timer (drift correction under hysteresis). */
41097
41404
  autoRebalanceTimer = null;
41098
41405
  initTimestamp = 0;
41406
+ /** Storage migration maintenance lease. It only gates dispatch; it does not
41407
+ * change any camera wrapper or persistent pipeline configuration. */
41408
+ storageMigrationLeaseId = null;
41099
41409
  constructor() {
41100
41410
  super({});
41101
41411
  }
@@ -41143,6 +41453,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
41143
41453
  rebalance: (opts) => this.rebalance(opts),
41144
41454
  setCameraPipelineForAgent: (input) => this.setCameraPipelineForAgent(input),
41145
41455
  dispatchCamera: (config) => this.dispatchCamera(config),
41456
+ maintenancePaused: () => this.storageMigrationLeaseId !== null,
41146
41457
  setTopology: (topology) => {
41147
41458
  this.topology = topology;
41148
41459
  },
@@ -41289,8 +41600,29 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
41289
41600
  this.settingsStore = null;
41290
41601
  }
41291
41602
  async dispatchCamera(runnerConfig) {
41603
+ if (this.storageMigrationLeaseId !== null) return {
41604
+ success: true,
41605
+ kind: "pending"
41606
+ };
41292
41607
  return this.placement.dispatchCamera(runnerConfig);
41293
41608
  }
41609
+ async pauseForStorageMigration(input) {
41610
+ if (this.storageMigrationLeaseId !== null && this.storageMigrationLeaseId !== input.leaseId) throw new Error("pipeline dispatch is already paused by another storage migration");
41611
+ this.storageMigrationLeaseId = input.leaseId;
41612
+ try {
41613
+ await this.placement.waitForMigrationIdle();
41614
+ return { paused: true };
41615
+ } catch (err) {
41616
+ this.storageMigrationLeaseId = null;
41617
+ throw err;
41618
+ }
41619
+ }
41620
+ async resumeForStorageMigration(input) {
41621
+ if (this.storageMigrationLeaseId === null) return { resumed: true };
41622
+ if (this.storageMigrationLeaseId !== input.leaseId) throw new Error("pipeline storage migration lease does not match");
41623
+ this.storageMigrationLeaseId = null;
41624
+ return { resumed: true };
41625
+ }
41294
41626
  async releaseCamera(input) {
41295
41627
  return this.placement.releaseCamera(input);
41296
41628
  }
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-KN60YkLI.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-9CKmTiwO.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }