@camstack/addon-provider-homeassistant 1.2.167 → 1.2.171

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.
@@ -1,5 +1,5 @@
1
1
  require("node:crypto");
2
- //#region ../types/dist/event-category-DaIZi00R.mjs
2
+ //#region ../types/dist/event-category-C4hVnRo8.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -218,7 +218,17 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
218
218
  EventCategory["RecordingStopped"] = "recording.stopped";
219
219
  EventCategory["RecordingError"] = "recording.error";
220
220
  EventCategory["RecordingHealthDegraded"] = "recording.health.degraded";
221
+ /** Recording enabled but no segment finalized for the NC stall window. */
222
+ EventCategory["RecordingHealthStalled"] = "recording.health.stalled";
223
+ /** Recovery from {@link RecordingHealthStalled}. */
224
+ EventCategory["RecordingHealthOk"] = "recording.health.ok";
221
225
  EventCategory["RecordingStorageCritical"] = "recording.storage.critical";
226
+ /** Free space on a storage location crossed the warn bar. */
227
+ EventCategory["StorageLocationLow"] = "storage.location.low";
228
+ /** Free space at/under the critical bar, or capacity probe failed (`null`). */
229
+ EventCategory["StorageLocationCritical"] = "storage.location.critical";
230
+ /** Recovery from low/critical on a storage location. */
231
+ EventCategory["StorageLocationOk"] = "storage.location.ok";
222
232
  EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
223
233
  EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
224
234
  EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
@@ -5377,7 +5387,7 @@ var ZodIssueCode = {
5377
5387
  var ZodFirstPartyTypeKind;
5378
5388
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5379
5389
  //#endregion
5380
- //#region ../types/dist/sleep-DwAQ9sqX.mjs
5390
+ //#region ../types/dist/sleep-BBF1iXUi.mjs
5381
5391
  /**
5382
5392
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5383
5393
  * window to float samples (D455).
@@ -7979,6 +7989,21 @@ var ProfileRtspEntrySchema = object({
7979
7989
  resolution: CamStreamResolutionSchema.optional()
7980
7990
  });
7981
7991
  /**
7992
+ * The model weight formats a catalog entry can ship. Schema-free on purpose:
7993
+ * `types/models.ts` builds Zod schemas from it, but a runner-closure consumer
7994
+ * (the model downloader in `@camstack/system`) needs only the list and must
7995
+ * reach it through `@camstack/types/addon` without building the cap schema
7996
+ * graph (D28).
7997
+ */
7998
+ var MODEL_FORMATS = [
7999
+ "onnx",
8000
+ "coreml",
8001
+ "openvino",
8002
+ "tflite",
8003
+ "pt",
8004
+ "gguf"
8005
+ ];
8006
+ /**
7982
8007
  * Per-call node pinning for `ctx.api` capability calls.
7983
8008
  *
7984
8009
  * A capability call normally resolves to its DEFAULT provider — a `singleton`
@@ -8587,7 +8612,7 @@ function errMsg(err) {
8587
8612
  return String(err);
8588
8613
  }
8589
8614
  //#endregion
8590
- //#region ../types/dist/composition-Bzr7GwgP.mjs
8615
+ //#region ../types/dist/composition-C-WpVYTX.mjs
8591
8616
  /**
8592
8617
  * The ffmpeg build every CamStack node downloads, per platform and arch.
8593
8618
  *
@@ -8639,7 +8664,7 @@ var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFM
8639
8664
  function portable(target) {
8640
8665
  return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
8641
8666
  }
8642
- portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
8667
+ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64"), `${BASE}${FFMPEG_RELEASE}`;
8643
8668
  /**
8644
8669
  * THE table "which boolean of this device type counts as HIGH", and the
8645
8670
  * pure evaluator of its EDGE.
@@ -10358,6 +10383,15 @@ discriminatedUnion("type", [
10358
10383
  message: string()
10359
10384
  })
10360
10385
  ]);
10386
+ /** Every status, in the order a summary lists them. */
10387
+ var RETRAIN_REVIEW_STATUSES = [
10388
+ "unchanged",
10389
+ "adjusted",
10390
+ "reclassified",
10391
+ "added",
10392
+ "removed",
10393
+ "model-error"
10394
+ ];
10361
10395
  /**
10362
10396
  * What the gate decided about a birth, from the CALLER's point of view.
10363
10397
  *
@@ -11975,14 +12009,6 @@ var MASK_SUPPLY_STEP_IDS = ["segmentation"];
11975
12009
  ...CROP_SUPPLY_STEP_IDS,
11976
12010
  ...MASK_SUPPLY_STEP_IDS
11977
12011
  ];
11978
- var MODEL_FORMATS = [
11979
- "onnx",
11980
- "coreml",
11981
- "openvino",
11982
- "tflite",
11983
- "pt",
11984
- "gguf"
11985
- ];
11986
12012
  /**
11987
12013
  * Multi-file format payload.
11988
12014
  *
@@ -13279,6 +13305,329 @@ method(object({
13279
13305
  password: string()
13280
13306
  }), AuthResultSchema.nullable(), { kind: "mutation" }), method(object({ state: string() }), string()), method(record(string(), string()), AuthResultSchema, { kind: "mutation" }), method(object({ token: string() }), AuthResultSchema.nullable());
13281
13307
  /**
13308
+ * Query filter for settings-store collections.
13309
+ */
13310
+ var QueryFilterSchema = object({
13311
+ where: record(string(), unknown()).optional(),
13312
+ whereIn: record(string(), array(unknown())).optional(),
13313
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
13314
+ /** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
13315
+ whereNot: record(string(), unknown()).optional(),
13316
+ /** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
13317
+ * empty list excludes nothing. See `QueryFilter.whereNotIn`. */
13318
+ whereNotIn: record(string(), array(unknown())).optional(),
13319
+ orderBy: object({
13320
+ field: string(),
13321
+ direction: _enum(["asc", "desc"])
13322
+ }).optional(),
13323
+ limit: number().optional(),
13324
+ offset: number().optional()
13325
+ });
13326
+ /**
13327
+ * The predicate half of a filter, for BULK MUTATIONS.
13328
+ *
13329
+ * Deliberately not `QueryFilterSchema`: `orderBy` / `limit` / `offset` have no
13330
+ * meaning for a statement that rewrites a set, and accepting them would invite
13331
+ * a caller to believe `limit` bounds the damage. Every field is optional here
13332
+ * only so the shape stays composable — the implementation REJECTS a filter
13333
+ * that compiles to no predicate, because that is the whole collection.
13334
+ */
13335
+ var MutationFilterSchema = object({
13336
+ where: record(string(), unknown()).optional(),
13337
+ whereIn: record(string(), array(unknown())).optional(),
13338
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
13339
+ whereNot: record(string(), unknown()).optional(),
13340
+ whereNotIn: record(string(), array(unknown())).optional()
13341
+ });
13342
+ /**
13343
+ * One scalar an {@link settingsStoreCapability.methods.aggregate} call asks for.
13344
+ *
13345
+ * `as` names the slot in the result, so the SAME column may be asked twice with
13346
+ * two operations (`MIN(startMs)` and `MAX(startMs)` in one round trip) — which
13347
+ * a `Record<column, op>` shape could not express.
13348
+ */
13349
+ var AggregateFieldSchema = object({
13350
+ /** Result key. */
13351
+ as: string().min(1),
13352
+ /** Column to aggregate. Must be a real column of a declared collection. */
13353
+ field: string().min(1),
13354
+ op: _enum([
13355
+ "sum",
13356
+ "min",
13357
+ "max"
13358
+ ])
13359
+ });
13360
+ /**
13361
+ * `COUNT(*)` plus one number per requested field.
13362
+ *
13363
+ * `null` means NO ROW MATCHED, never zero: a `SUM` over an empty set and a sum
13364
+ * that really is 0 are different facts, and an accounting caller that renders
13365
+ * "0 bytes, oldest = 0" for "nothing here" reports a lie about a disk.
13366
+ */
13367
+ var AggregateResultSchema = object({
13368
+ count: number().int(),
13369
+ values: record(string(), number().nullable())
13370
+ });
13371
+ /** A single stored record: `{ id, data }`. */
13372
+ var SettingsRecordSchema = object({
13373
+ id: string(),
13374
+ data: record(string(), unknown())
13375
+ });
13376
+ /**
13377
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
13378
+ * optional.
13379
+ *
13380
+ * A separate schema rather than loosening the shared one: every other method
13381
+ * on this cap addresses a row BY its id, and making that field optional
13382
+ * everywhere would turn a forgotten key into a silently generated one on
13383
+ * `update` and `delete` as well.
13384
+ */
13385
+ var BulkRecordSchema = object({
13386
+ id: string().optional(),
13387
+ data: record(string(), unknown())
13388
+ });
13389
+ /**
13390
+ * The database FILES one `sqlite-settings` engine process owns (D851).
13391
+ * Closed on purpose: a file is a thing the engine opens, backs up and gives a
13392
+ * serving thread, so a new one is a code change, never a string a caller
13393
+ * invents. `settings` is `camstack.db` and the default for every collection
13394
+ * that names no file.
13395
+ */
13396
+ var DataStoreDatabaseSchema = _enum([
13397
+ "settings",
13398
+ "events",
13399
+ "history"
13400
+ ]);
13401
+ DataStoreDatabaseSchema.options;
13402
+ /**
13403
+ * One write inside a {@link settingsStoreCapability.methods.transact} call.
13404
+ * The three that a "replace this set, bump that revision" write needs, plus
13405
+ * the batched upsert a rollup writer needs.
13406
+ */
13407
+ var TransactOpSchema = discriminatedUnion("op", [
13408
+ object({
13409
+ op: literal("deleteWhere"),
13410
+ collection: string(),
13411
+ filter: MutationFilterSchema
13412
+ }),
13413
+ object({
13414
+ op: literal("insertMany"),
13415
+ collection: string(),
13416
+ records: array(BulkRecordSchema).readonly()
13417
+ }),
13418
+ object({
13419
+ op: literal("update"),
13420
+ collection: string(),
13421
+ id: string(),
13422
+ data: record(string(), unknown())
13423
+ }),
13424
+ object({
13425
+ op: literal("upsertMany"),
13426
+ collection: string(),
13427
+ conflict: array(string()).readonly(),
13428
+ records: array(BulkRecordSchema).readonly()
13429
+ })
13430
+ ]);
13431
+ /**
13432
+ * The precondition of a transaction: the row `key` of `collection` must hold
13433
+ * `equals` in `column`, read INSIDE the transaction.
13434
+ */
13435
+ var TransactGuardSchema = object({
13436
+ collection: string(),
13437
+ key: string(),
13438
+ column: string(),
13439
+ equals: unknown()
13440
+ });
13441
+ /**
13442
+ * Column declaration for a structured (SQL-backed) collection.
13443
+ *
13444
+ * Logical types — the backend translates each to the matching SQLite
13445
+ * storage class and handles per-type marshaling:
13446
+ * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
13447
+ * - `JSON` — TEXT under the hood; serialised on write, parsed on read
13448
+ * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
13449
+ */
13450
+ var CollectionColumnSchema = object({
13451
+ name: string(),
13452
+ type: _enum([
13453
+ "TEXT",
13454
+ "INTEGER",
13455
+ "REAL",
13456
+ "JSON",
13457
+ "BOOLEAN"
13458
+ ]),
13459
+ primaryKey: boolean().optional(),
13460
+ notNull: boolean().optional(),
13461
+ unique: boolean().optional(),
13462
+ /**
13463
+ * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
13464
+ * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
13465
+ * collection surface simply cannot express their existing tables — which is
13466
+ * why they were still on the uncapped `table*` API.
13467
+ */
13468
+ defaultValue: union([
13469
+ string(),
13470
+ number(),
13471
+ boolean()
13472
+ ]).optional()
13473
+ });
13474
+ var CollectionIndexSchema = object({
13475
+ name: string(),
13476
+ columns: array(string()).readonly(),
13477
+ unique: boolean().optional()
13478
+ });
13479
+ /**
13480
+ * The input of `declareCollection` — ONE schema for the door and for the
13481
+ * engine behind it, so the two surfaces cannot drift (the dispatcher forwards
13482
+ * the payload untouched).
13483
+ *
13484
+ * - `database` — the file the collection lives in (D851). Absent means
13485
+ * `settings`. A declaration naming a file other than the one the table is
13486
+ * already in is REFUSED by the engine, never moved.
13487
+ * - `primaryKey` — a COMPOSITE key, as column names. A single name is the same
13488
+ * as `primaryKey: true` on that column. A composite-keyed collection has no
13489
+ * `id`: it is written with `insertMany` / `upsertMany` / `transact` and read
13490
+ * with `query` / `count` / `aggregate` / `deleteWhere`; the calls that
13491
+ * address one row by id are refused.
13492
+ * - `withoutRowid` — emit `WITHOUT ROWID`. Requires a primary key.
13493
+ */
13494
+ var DeclareCollectionInputSchema = object({
13495
+ namespace: string().optional(),
13496
+ collection: string(),
13497
+ columns: array(CollectionColumnSchema).readonly(),
13498
+ indexes: array(CollectionIndexSchema).readonly().optional(),
13499
+ database: DataStoreDatabaseSchema.optional(),
13500
+ primaryKey: array(string()).readonly().optional(),
13501
+ withoutRowid: boolean().optional()
13502
+ });
13503
+ method(object({
13504
+ namespace: string().optional(),
13505
+ collection: string(),
13506
+ key: string()
13507
+ }), unknown(), { auth: "admin" }), method(object({
13508
+ namespace: string().optional(),
13509
+ collection: string(),
13510
+ key: string(),
13511
+ value: unknown()
13512
+ }), _void(), {
13513
+ kind: "mutation",
13514
+ auth: "admin"
13515
+ }), method(object({
13516
+ namespace: string().optional(),
13517
+ collection: string(),
13518
+ filter: QueryFilterSchema.optional(),
13519
+ columns: array(string()).readonly().optional()
13520
+ }), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
13521
+ namespace: string().optional(),
13522
+ collection: string(),
13523
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
13524
+ * index on the collection. Never empty. */
13525
+ conflict: array(string()).readonly(),
13526
+ record: BulkRecordSchema
13527
+ }), object({
13528
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
13529
+ * row's own id on an update. */
13530
+ id: union([string(), number()]) }), {
13531
+ kind: "mutation",
13532
+ auth: "admin"
13533
+ }), method(object({
13534
+ namespace: string().optional(),
13535
+ collection: string(),
13536
+ conflict: array(string()).readonly(),
13537
+ records: array(BulkRecordSchema).readonly()
13538
+ }), object({ upserted: number().int() }), {
13539
+ kind: "mutation",
13540
+ auth: "admin"
13541
+ }), method(object({
13542
+ namespace: string().optional(),
13543
+ collection: string(),
13544
+ record: object({
13545
+ id: string().optional(),
13546
+ data: record(string(), unknown())
13547
+ })
13548
+ }), object({
13549
+ /**
13550
+ * The id the row ACTUALLY got (D473): the one supplied, the UUID minted
13551
+ * for an absent one, or the ROWID SQLite assigned on an `INTEGER`
13552
+ * primary key — which is the only place an auto key is knowable.
13553
+ */
13554
+ id: union([string(), number()]) }), {
13555
+ kind: "mutation",
13556
+ auth: "admin"
13557
+ }), method(object({
13558
+ namespace: string().optional(),
13559
+ collection: string(),
13560
+ records: array(BulkRecordSchema).readonly()
13561
+ }), object({ inserted: number().int() }), {
13562
+ kind: "mutation",
13563
+ auth: "admin"
13564
+ }), method(object({
13565
+ namespace: string().optional(),
13566
+ guard: TransactGuardSchema.optional(),
13567
+ ops: array(TransactOpSchema).readonly()
13568
+ }), object({
13569
+ applied: boolean(),
13570
+ current: unknown().optional()
13571
+ }), {
13572
+ kind: "mutation",
13573
+ auth: "admin"
13574
+ }), method(object({
13575
+ namespace: string().optional(),
13576
+ collection: string(),
13577
+ id: string(),
13578
+ data: record(string(), unknown())
13579
+ }), _void(), {
13580
+ kind: "mutation",
13581
+ auth: "admin"
13582
+ }), method(object({
13583
+ namespace: string().optional(),
13584
+ collection: string(),
13585
+ key: string()
13586
+ }), _void(), {
13587
+ kind: "mutation",
13588
+ auth: "admin"
13589
+ }), method(object({
13590
+ namespace: string().optional(),
13591
+ collection: string(),
13592
+ filter: MutationFilterSchema
13593
+ }), object({ deleted: number().int() }), {
13594
+ kind: "mutation",
13595
+ auth: "admin"
13596
+ }), method(object({
13597
+ namespace: string().optional(),
13598
+ collection: string(),
13599
+ filter: MutationFilterSchema,
13600
+ data: record(string(), unknown())
13601
+ }), object({ updated: number().int() }), {
13602
+ kind: "mutation",
13603
+ auth: "admin"
13604
+ }), method(object({
13605
+ namespace: string().optional(),
13606
+ collection: string(),
13607
+ filter: QueryFilterSchema.optional()
13608
+ }), number(), { auth: "admin" }), method(object({
13609
+ namespace: string().optional(),
13610
+ collection: string(),
13611
+ fields: array(AggregateFieldSchema).readonly(),
13612
+ filter: QueryFilterSchema.optional()
13613
+ }), AggregateResultSchema, { auth: "admin" }), method(object({
13614
+ namespace: string().optional(),
13615
+ collection: string(),
13616
+ field: string(),
13617
+ bucketSize: number().int().positive(),
13618
+ origin: number().int(),
13619
+ filter: QueryFilterSchema.optional()
13620
+ }), array(object({
13621
+ bucket: number().int(),
13622
+ count: number().int()
13623
+ })).readonly(), { auth: "admin" }), method(object({
13624
+ namespace: string().optional(),
13625
+ collection: string()
13626
+ }), boolean(), { auth: "admin" }), method(DeclareCollectionInputSchema, _void(), {
13627
+ kind: "mutation",
13628
+ auth: "admin"
13629
+ });
13630
+ /**
13282
13631
  * How long one snapshot may take end to end: the pinned copy of the whole
13283
13632
  * database plus `PRAGMA integrity_check` over the copy, on the hub's slowest
13284
13633
  * disk. ~800 MB at a pessimistic 10 MB/s is under 3 minutes; the bound is
@@ -13291,7 +13640,11 @@ var DATABASE_SNAPSHOT_TIMEOUT_MS = 30 * 6e4;
13291
13640
  * database has no sidecars and is just as owned). Paths are absolute on the
13292
13641
  * owner's host.
13293
13642
  */
13294
- var DatabaseSnapshotTargetsSchema = object({ databases: array(object({ livePath: string() })) });
13643
+ var DatabaseSnapshotTargetsSchema = object({ databases: array(object({
13644
+ /** Which owned file this is — the handle `writeSnapshot` takes. */
13645
+ databaseId: DataStoreDatabaseSchema,
13646
+ livePath: string()
13647
+ })) });
13295
13648
  /** One b-tree table of the snapshot and the rows it holds. */
13296
13649
  var DatabaseSnapshotTableSchema = object({
13297
13650
  name: string(),
@@ -13324,6 +13677,10 @@ var DatabaseSnapshotResultSchema = object({
13324
13677
  /** When the pinned read transaction began (ms epoch) — the snapshot's instant. */
13325
13678
  takenAt: number()
13326
13679
  });
13680
+ /** A snapshot the owner wrote, with the file it belongs to. */
13681
+ var DatabaseSnapshotWrittenSchema = DatabaseSnapshotResultSchema.extend({ databaseId: DataStoreDatabaseSchema });
13682
+ /** Which database `writeSnapshot` copies. Required: an unstated ask is not guessed. */
13683
+ var DatabaseSnapshotRequestSchema = object({ databaseId: DataStoreDatabaseSchema });
13327
13684
  /**
13328
13685
  * A snapshot as an ARCHIVE records it (`ArchiveManifest.sqliteSnapshots`):
13329
13686
  * the same facts, with both paths relative to the archive root (the node's
@@ -13333,9 +13690,11 @@ var ArchiveSqliteSnapshotSchema = DatabaseSnapshotResultSchema.extend({
13333
13690
  /** Archive-relative path of the live database the archive does NOT carry. */
13334
13691
  livePath: string(),
13335
13692
  /** Archive-relative path of the verified copy it carries in its place. */
13336
- snapshotPath: string()
13693
+ snapshotPath: string(),
13694
+ /** Absent on an archive made before several files were owned: that was `settings`. */
13695
+ databaseId: DataStoreDatabaseSchema.optional()
13337
13696
  });
13338
- method(object({}), DatabaseSnapshotTargetsSchema, { auth: "admin" }), method(object({}), DatabaseSnapshotResultSchema, {
13697
+ method(object({}), DatabaseSnapshotTargetsSchema, { auth: "admin" }), method(DatabaseSnapshotRequestSchema, DatabaseSnapshotWrittenSchema, {
13339
13698
  kind: "mutation",
13340
13699
  auth: "admin",
13341
13700
  timeoutMs: DATABASE_SNAPSHOT_TIMEOUT_MS
@@ -13456,7 +13815,12 @@ var BackupArchiveEntrySchema = object({
13456
13815
  /** Top-level locations included in the archive (db, addons, tls, …). */
13457
13816
  locations: array(string()).readonly(),
13458
13817
  /** Present when the archive is encrypted; restore then needs that key. */
13459
- encryption: BackupArchiveEncryptionSchema.optional()
13818
+ encryption: BackupArchiveEncryptionSchema.optional(),
13819
+ /**
13820
+ * The databases the run asked to carry (its retention class). Absent on an
13821
+ * archive made before several files were owned: that was `['settings']`.
13822
+ */
13823
+ databases: array(DataStoreDatabaseSchema).readonly().optional()
13460
13824
  });
13461
13825
  var BackupEntrySchema = object({
13462
13826
  id: string(),
@@ -13490,7 +13854,12 @@ var ArchiveManifestSchema = object({
13490
13854
  * Live SQLite databases this archive carries as their OWNER's verified
13491
13855
  * snapshot instead of as files (D693). Absent on archives made before.
13492
13856
  */
13493
- sqliteSnapshots: array(ArchiveSqliteSnapshotSchema).optional()
13857
+ sqliteSnapshots: array(ArchiveSqliteSnapshotSchema).optional(),
13858
+ /**
13859
+ * Owned database files the run did NOT carry (not selected): left out of the
13860
+ * tar and the entry list alike. Absent when every owned file was carried.
13861
+ */
13862
+ omittedDatabases: array(DataStoreDatabaseSchema).optional()
13494
13863
  });
13495
13864
  var LocationStatSchema = object({
13496
13865
  name: string(),
@@ -13612,6 +13981,12 @@ var BackupScheduleSchema = object({
13612
13981
  /** Optional subset of source locations to include; omitted = all. */
13613
13982
  dataSources: array(string()).readonly().optional(),
13614
13983
  /**
13984
+ * Which database files this schedule carries. Absent = `['settings']`
13985
+ * (an unstated ask is the minimum, D382). Events and history run weekly,
13986
+ * settings nightly (D852).
13987
+ */
13988
+ databases: array(DataStoreDatabaseSchema).readonly().optional(),
13989
+ /**
13615
13990
  * ms-epoch of the last tick that FIRED this schedule. Stamped before the
13616
13991
  * archive runs (it is the dedupe anchor), so it says "attempted", never
13617
13992
  * "succeeded" — a run refused by every destination stamps it too.
@@ -13635,7 +14010,9 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
13635
14010
  * retention). Omitted = each destination's own policy
13636
14011
  * retention (manual runs).
13637
14012
  */
13638
- retentionCount: number().int().min(1).max(1e3).optional()
14013
+ retentionCount: number().int().min(1).max(1e3).optional(),
14014
+ /** Database files to carry; omitted = `['settings']`. */
14015
+ databases: array(DataStoreDatabaseSchema).optional()
13639
14016
  }).optional(), BackupTriggerResultSchema, {
13640
14017
  kind: "mutation",
13641
14018
  auth: "admin"
@@ -13710,14 +14087,18 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
13710
14087
  ok: boolean(),
13711
14088
  error: string().optional(),
13712
14089
  nextRuns: array(number()).readonly()
13713
- })), method(_void(), array(BackupScheduleSchema).readonly(), { auth: "admin" }), method(object({
14090
+ })), method(_void(), array(BackupScheduleSchema).readonly(), { auth: "admin" }), method(_void(), object({
14091
+ answered: boolean(),
14092
+ databases: array(DataStoreDatabaseSchema).readonly()
14093
+ }), { auth: "admin" }), method(object({
13714
14094
  id: string().optional(),
13715
14095
  label: string(),
13716
14096
  cron: string(),
13717
14097
  enabled: boolean(),
13718
14098
  locationIds: array(string()).readonly(),
13719
14099
  retentionCount: number().int().min(1).max(1e3),
13720
- dataSources: array(string()).readonly().optional()
14100
+ dataSources: array(string()).readonly().optional(),
14101
+ databases: array(DataStoreDatabaseSchema).readonly().optional()
13721
14102
  }), BackupScheduleSchema, {
13722
14103
  kind: "mutation",
13723
14104
  auth: "admin"
@@ -13825,7 +14206,14 @@ var BrokerProviderInfoSchema = object({
13825
14206
  /** Broker kinds this provider can create, with a display label. */
13826
14207
  kinds: array(object({
13827
14208
  kind: string(),
13828
- label: string()
14209
+ label: string(),
14210
+ /**
14211
+ * Relative hub path to start an interactive account link (OAuth popup).
14212
+ * May include `{{brokerId}}`; admin-ui substitutes and appends `?popup=1`.
14213
+ */
14214
+ interactiveConnectPath: string().min(1).optional(),
14215
+ /** Relative hub path to disconnect the linked account (same popup pattern). */
14216
+ interactiveDisconnectPath: string().min(1).optional()
13829
14217
  }))
13830
14218
  });
13831
14219
  var ListInputSchema = object({
@@ -14190,6 +14578,16 @@ var BrokerClientsSchema = object({
14190
14578
  /** Total encoded + raw-RTP callback subscriber count (sum of `encoded[].length`). */
14191
14579
  encodedSubscribers: number()
14192
14580
  });
14581
+ /**
14582
+ * How many people are watching one camera LIVE right now — see
14583
+ * `getLiveViewerCounts`. A camera with nobody watching is absent from the list
14584
+ * (so `viewers` is always at least 1): the listing carries the cameras that
14585
+ * have viewers, never a row of zeros.
14586
+ */
14587
+ var LiveViewerCountSchema = object({
14588
+ deviceId: number().int().nonnegative(),
14589
+ viewers: number().int().positive()
14590
+ });
14193
14591
  _enum([
14194
14592
  "reconnecting",
14195
14593
  "sleeping",
@@ -14550,7 +14948,7 @@ method(object({
14550
14948
  }), {
14551
14949
  kind: "mutation",
14552
14950
  auth: "admin"
14553
- }), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
14951
+ }), method(object({ brokerId: string() }), BrokerClientsSchema), method(_void(), array(LiveViewerCountSchema).readonly()), method(object({
14554
14952
  brokerId: string(),
14555
14953
  channel: _enum(["rtsp", "audio"]),
14556
14954
  handle: string()
@@ -15518,240 +15916,6 @@ method(_void(), array(CustomModelDescriptorSchema).readonly(), { auth: "admin" }
15518
15916
  timeoutMs: 30 * 6e4
15519
15917
  });
15520
15918
  /**
15521
- * Query filter for settings-store collections.
15522
- */
15523
- var QueryFilterSchema = object({
15524
- where: record(string(), unknown()).optional(),
15525
- whereIn: record(string(), array(unknown())).optional(),
15526
- whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
15527
- /** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
15528
- whereNot: record(string(), unknown()).optional(),
15529
- /** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
15530
- * empty list excludes nothing. See `QueryFilter.whereNotIn`. */
15531
- whereNotIn: record(string(), array(unknown())).optional(),
15532
- orderBy: object({
15533
- field: string(),
15534
- direction: _enum(["asc", "desc"])
15535
- }).optional(),
15536
- limit: number().optional(),
15537
- offset: number().optional()
15538
- });
15539
- /**
15540
- * The predicate half of a filter, for BULK MUTATIONS.
15541
- *
15542
- * Deliberately not `QueryFilterSchema`: `orderBy` / `limit` / `offset` have no
15543
- * meaning for a statement that rewrites a set, and accepting them would invite
15544
- * a caller to believe `limit` bounds the damage. Every field is optional here
15545
- * only so the shape stays composable — the implementation REJECTS a filter
15546
- * that compiles to no predicate, because that is the whole collection.
15547
- */
15548
- var MutationFilterSchema = object({
15549
- where: record(string(), unknown()).optional(),
15550
- whereIn: record(string(), array(unknown())).optional(),
15551
- whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
15552
- whereNot: record(string(), unknown()).optional(),
15553
- whereNotIn: record(string(), array(unknown())).optional()
15554
- });
15555
- /**
15556
- * One scalar an {@link settingsStoreCapability.methods.aggregate} call asks for.
15557
- *
15558
- * `as` names the slot in the result, so the SAME column may be asked twice with
15559
- * two operations (`MIN(startMs)` and `MAX(startMs)` in one round trip) — which
15560
- * a `Record<column, op>` shape could not express.
15561
- */
15562
- var AggregateFieldSchema = object({
15563
- /** Result key. */
15564
- as: string().min(1),
15565
- /** Column to aggregate. Must be a real column of a declared collection. */
15566
- field: string().min(1),
15567
- op: _enum([
15568
- "sum",
15569
- "min",
15570
- "max"
15571
- ])
15572
- });
15573
- /**
15574
- * `COUNT(*)` plus one number per requested field.
15575
- *
15576
- * `null` means NO ROW MATCHED, never zero: a `SUM` over an empty set and a sum
15577
- * that really is 0 are different facts, and an accounting caller that renders
15578
- * "0 bytes, oldest = 0" for "nothing here" reports a lie about a disk.
15579
- */
15580
- var AggregateResultSchema = object({
15581
- count: number().int(),
15582
- values: record(string(), number().nullable())
15583
- });
15584
- /** A single stored record: `{ id, data }`. */
15585
- var SettingsRecordSchema = object({
15586
- id: string(),
15587
- data: record(string(), unknown())
15588
- });
15589
- /**
15590
- * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
15591
- * optional.
15592
- *
15593
- * A separate schema rather than loosening the shared one: every other method
15594
- * on this cap addresses a row BY its id, and making that field optional
15595
- * everywhere would turn a forgotten key into a silently generated one on
15596
- * `update` and `delete` as well.
15597
- */
15598
- var BulkRecordSchema = object({
15599
- id: string().optional(),
15600
- data: record(string(), unknown())
15601
- });
15602
- /**
15603
- * Column declaration for a structured (SQL-backed) collection.
15604
- *
15605
- * Logical types — the backend translates each to the matching SQLite
15606
- * storage class and handles per-type marshaling:
15607
- * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
15608
- * - `JSON` — TEXT under the hood; serialised on write, parsed on read
15609
- * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
15610
- */
15611
- var CollectionColumnSchema = object({
15612
- name: string(),
15613
- type: _enum([
15614
- "TEXT",
15615
- "INTEGER",
15616
- "REAL",
15617
- "JSON",
15618
- "BOOLEAN"
15619
- ]),
15620
- primaryKey: boolean().optional(),
15621
- notNull: boolean().optional(),
15622
- unique: boolean().optional(),
15623
- /**
15624
- * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
15625
- * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
15626
- * collection surface simply cannot express their existing tables — which is
15627
- * why they were still on the uncapped `table*` API.
15628
- */
15629
- defaultValue: union([
15630
- string(),
15631
- number(),
15632
- boolean()
15633
- ]).optional()
15634
- });
15635
- var CollectionIndexSchema = object({
15636
- name: string(),
15637
- columns: array(string()).readonly(),
15638
- unique: boolean().optional()
15639
- });
15640
- method(object({
15641
- namespace: string().optional(),
15642
- collection: string(),
15643
- key: string()
15644
- }), unknown(), { auth: "admin" }), method(object({
15645
- namespace: string().optional(),
15646
- collection: string(),
15647
- key: string(),
15648
- value: unknown()
15649
- }), _void(), {
15650
- kind: "mutation",
15651
- auth: "admin"
15652
- }), method(object({
15653
- namespace: string().optional(),
15654
- collection: string(),
15655
- filter: QueryFilterSchema.optional(),
15656
- columns: array(string()).readonly().optional()
15657
- }), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
15658
- namespace: string().optional(),
15659
- collection: string(),
15660
- /** Declared columns identifying the slot; must be covered by a UNIQUE
15661
- * index on the collection. Never empty. */
15662
- conflict: array(string()).readonly(),
15663
- record: BulkRecordSchema
15664
- }), object({
15665
- /** The id the row HAS: assigned by SQLite on an insert, or the existing
15666
- * row's own id on an update. */
15667
- id: union([string(), number()]) }), {
15668
- kind: "mutation",
15669
- auth: "admin"
15670
- }), method(object({
15671
- namespace: string().optional(),
15672
- collection: string(),
15673
- record: object({
15674
- id: string().optional(),
15675
- data: record(string(), unknown())
15676
- })
15677
- }), object({
15678
- /**
15679
- * The id the row ACTUALLY got (D473): the one supplied, the UUID minted
15680
- * for an absent one, or the ROWID SQLite assigned on an `INTEGER`
15681
- * primary key — which is the only place an auto key is knowable.
15682
- */
15683
- id: union([string(), number()]) }), {
15684
- kind: "mutation",
15685
- auth: "admin"
15686
- }), method(object({
15687
- namespace: string().optional(),
15688
- collection: string(),
15689
- records: array(BulkRecordSchema).readonly()
15690
- }), object({ inserted: number().int() }), {
15691
- kind: "mutation",
15692
- auth: "admin"
15693
- }), method(object({
15694
- namespace: string().optional(),
15695
- collection: string(),
15696
- id: string(),
15697
- data: record(string(), unknown())
15698
- }), _void(), {
15699
- kind: "mutation",
15700
- auth: "admin"
15701
- }), method(object({
15702
- namespace: string().optional(),
15703
- collection: string(),
15704
- key: string()
15705
- }), _void(), {
15706
- kind: "mutation",
15707
- auth: "admin"
15708
- }), method(object({
15709
- namespace: string().optional(),
15710
- collection: string(),
15711
- filter: MutationFilterSchema
15712
- }), object({ deleted: number().int() }), {
15713
- kind: "mutation",
15714
- auth: "admin"
15715
- }), method(object({
15716
- namespace: string().optional(),
15717
- collection: string(),
15718
- filter: MutationFilterSchema,
15719
- data: record(string(), unknown())
15720
- }), object({ updated: number().int() }), {
15721
- kind: "mutation",
15722
- auth: "admin"
15723
- }), method(object({
15724
- namespace: string().optional(),
15725
- collection: string(),
15726
- filter: QueryFilterSchema.optional()
15727
- }), number(), { auth: "admin" }), method(object({
15728
- namespace: string().optional(),
15729
- collection: string(),
15730
- fields: array(AggregateFieldSchema).readonly(),
15731
- filter: QueryFilterSchema.optional()
15732
- }), AggregateResultSchema, { auth: "admin" }), method(object({
15733
- namespace: string().optional(),
15734
- collection: string(),
15735
- field: string(),
15736
- bucketSize: number().int().positive(),
15737
- origin: number().int(),
15738
- filter: QueryFilterSchema.optional()
15739
- }), array(object({
15740
- bucket: number().int(),
15741
- count: number().int()
15742
- })).readonly(), { auth: "admin" }), method(object({
15743
- namespace: string().optional(),
15744
- collection: string()
15745
- }), boolean(), { auth: "admin" }), method(object({
15746
- namespace: string().optional(),
15747
- collection: string(),
15748
- columns: array(CollectionColumnSchema).readonly(),
15749
- indexes: array(CollectionIndexSchema).readonly().optional()
15750
- }), _void(), {
15751
- kind: "mutation",
15752
- auth: "admin"
15753
- });
15754
- /**
15755
15919
  * What one engine says about itself. The orchestrator uses `kind` to pick
15756
15920
  * a registrant for a collection; `engineId` is what a log line names when
15757
15921
  * a call is routed or refused.
@@ -15831,6 +15995,14 @@ id: union([string(), number()]) }), {
15831
15995
  }), object({ id: union([string(), number()]) }), {
15832
15996
  kind: "mutation",
15833
15997
  auth: "admin"
15998
+ }), method(object({
15999
+ namespace: string().optional(),
16000
+ collection: string(),
16001
+ conflict: array(string()).readonly(),
16002
+ records: array(BulkRecordSchema).readonly()
16003
+ }), object({ upserted: number().int() }), {
16004
+ kind: "mutation",
16005
+ auth: "admin"
15834
16006
  }), method(object({
15835
16007
  namespace: string().optional(),
15836
16008
  collection: string(),
@@ -15838,6 +16010,16 @@ id: union([string(), number()]) }), {
15838
16010
  }), object({ inserted: number().int() }), {
15839
16011
  kind: "mutation",
15840
16012
  auth: "admin"
16013
+ }), method(object({
16014
+ namespace: string().optional(),
16015
+ guard: TransactGuardSchema.optional(),
16016
+ ops: array(TransactOpSchema).readonly()
16017
+ }), object({
16018
+ applied: boolean(),
16019
+ current: unknown().optional()
16020
+ }), {
16021
+ kind: "mutation",
16022
+ auth: "admin"
15841
16023
  }), method(object({
15842
16024
  namespace: string().optional(),
15843
16025
  collection: string(),
@@ -15890,12 +16072,7 @@ id: union([string(), number()]) }), {
15890
16072
  })).readonly(), { auth: "admin" }), method(object({
15891
16073
  namespace: string().optional(),
15892
16074
  collection: string()
15893
- }), boolean(), { auth: "admin" }), method(object({
15894
- namespace: string().optional(),
15895
- collection: string(),
15896
- columns: array(CollectionColumnSchema).readonly(),
15897
- indexes: array(CollectionIndexSchema).readonly().optional()
15898
- }), _void(), {
16075
+ }), boolean(), { auth: "admin" }), method(DeclareCollectionInputSchema, _void(), {
15899
16076
  kind: "mutation",
15900
16077
  auth: "admin"
15901
16078
  });
@@ -21071,6 +21248,12 @@ var NcSystemEventKindSchema = _enum([
21071
21248
  "node-updating",
21072
21249
  "node-inference-unavailable",
21073
21250
  "detection-blind",
21251
+ "recording-stalled",
21252
+ "recording-healthy",
21253
+ "recording-degraded",
21254
+ "storage-location-low",
21255
+ "storage-location-critical",
21256
+ "storage-location-ok",
21074
21257
  "addon-crash-loop",
21075
21258
  "addon-update-available",
21076
21259
  "server-update-available",
@@ -24742,6 +24925,58 @@ var RetrainBboxSchema = object({
24742
24925
  h: number()
24743
24926
  });
24744
24927
  /**
24928
+ * What a box LOOKED LIKE when it was offered, snapshotted at the moment the
24929
+ * operator accepted it. The saved row keeps only the final rectangle; this is
24930
+ * the other half of the pair, and the pair is what says whether the operator
24931
+ * accepted, nudged, relabelled or replaced a proposal (`retrain-review.ts`).
24932
+ *
24933
+ * `ref` names the proposal inside its frame: `pipeline:<trackId>` for a box the
24934
+ * live pipeline drew, `assist:<n>` for the n-th box of a detector or LLM run,
24935
+ * and anything unique for an operator-drawn box (`operator:<n>`). Re-derived
24936
+ * pipeline boxes carry the same ref every time, which is what lets a dismissal
24937
+ * stay dismissed.
24938
+ */
24939
+ var RetrainOriginSchema = object({
24940
+ source: RetrainAnnotationSourceSchema,
24941
+ ref: string().min(1),
24942
+ bbox: RetrainBboxSchema,
24943
+ macroClass: RetrainMacroClassSchema,
24944
+ label: string().optional(),
24945
+ score: number().optional(),
24946
+ modelId: string().optional()
24947
+ });
24948
+ /**
24949
+ * A proposal the operator deleted. Durable on the frame, so a deleted pipeline
24950
+ * box does not come back as a draft every time the frame is reopened, and so
24951
+ * the deletion itself is a recorded fact rather than an absence.
24952
+ */
24953
+ var RetrainDismissedSchema = object({
24954
+ ref: string().min(1),
24955
+ snapshot: RetrainOriginSchema
24956
+ });
24957
+ /** What the operator did with a proposal (see `retrain-review.ts`). */
24958
+ var RetrainReviewStatusSchema = _enum(RETRAIN_REVIEW_STATUSES);
24959
+ var RetrainFrameReviewSchema = object({
24960
+ boxes: array(object({
24961
+ ref: string(),
24962
+ savedId: string().optional(),
24963
+ status: RetrainReviewStatusSchema,
24964
+ /** The baseline was re-derived, not snapshotted (a pre-origin row). */
24965
+ approximate: boolean(),
24966
+ origin: RetrainOriginSchema.optional(),
24967
+ /** The class / label the box carries NOW (a removed box: its origin's). Absent on an older hub. */
24968
+ macroClass: RetrainMacroClassSchema.optional(),
24969
+ label: string().optional(),
24970
+ iou: number().optional()
24971
+ })).readonly(),
24972
+ summary: object({
24973
+ counts: record(RetrainReviewStatusSchema, number().int()),
24974
+ total: number().int(),
24975
+ changed: number().int(),
24976
+ approximate: boolean()
24977
+ })
24978
+ });
24979
+ /**
24745
24980
  * One annotated subject.
24746
24981
  *
24747
24982
  * `bbox` is normalised against the full frame, ALWAYS. The per-model shapes
@@ -24765,6 +25000,9 @@ var RetrainAnnotationSchema = object({
24765
25000
  /** Which model proposed this box — or, on a `model_error`, drew the phantom. */
24766
25001
  assistModelId: string().optional(),
24767
25002
  assistScore: number().optional(),
25003
+ /** The proposal this box started from, snapshotted at accept time. `null` on
25004
+ * a row saved before origins existed; absent on a draft nobody snapshotted. */
25005
+ origin: RetrainOriginSchema.nullable().optional(),
24768
25006
  exportedInBatch: string().optional(),
24769
25007
  createdAt: number()
24770
25008
  });
@@ -24857,7 +25095,19 @@ var RetrainFrameSchema = object({
24857
25095
  * empty when nothing the track store holds can be placed on it. */
24858
25096
  pipelineBoxes: array(RetrainPipelineBoxSchema).readonly().optional(),
24859
25097
  /** The named collections this frame belongs to. Present on list answers. */
24860
- collectionIds: array(string()).readonly().optional()
25098
+ collectionIds: array(string()).readonly().optional(),
25099
+ /** Bumped by every annotation save. A save that names a stale
25100
+ * `expectedRevision` is refused, so two surfaces cannot overwrite each other. */
25101
+ revision: number().int().optional(),
25102
+ /** Proposals the operator deleted — never re-seeded as drafts. */
25103
+ dismissed: array(RetrainDismissedSchema).readonly().optional(),
25104
+ /** What the operator did with the proposals, computed by the server. */
25105
+ review: RetrainFrameReviewSchema.optional(),
25106
+ /** The frame's pixels over the admin data plane (full size). Fetch with the
25107
+ * admin bearer token; relative to the hub root. */
25108
+ imageUrl: string().optional(),
25109
+ /** The same, as a ~480 px thumbnail for grids. */
25110
+ thumbnailUrl: string().optional()
24861
25111
  });
24862
25112
  /** Why a copy-on-select could not be honoured — named, never a silent skip. */
24863
25113
  var RetrainCopyRefusalSchema = _enum([
@@ -25936,10 +26186,33 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25936
26186
  /** The frame's track, when it has one — checked against the frame. */
25937
26187
  trackId: string().optional(),
25938
26188
  frameId: string(),
25939
- annotations: array(RetrainAnnotationDraftSchema)
26189
+ annotations: array(RetrainAnnotationDraftSchema),
26190
+ /** The frame's `revision` the caller saw. A different current revision
26191
+ * refuses the save with a `retrain-revision-conflict` error
26192
+ * (`parseRetrainRevisionConflict`). Absent ⇒ last write wins. */
26193
+ expectedRevision: number().int().optional(),
26194
+ /** The proposals the operator deleted. Absent ⇒ keep the frame's
26195
+ * current set; present ⇒ replace it (an empty array un-dismisses). */
26196
+ dismissed: array(RetrainDismissedSchema).optional()
25940
26197
  }), array(RetrainAnnotationSchema).readonly(), {
25941
26198
  kind: "mutation",
25942
26199
  auth: "admin"
26200
+ }), method(object({
26201
+ deviceId: number(),
26202
+ trackId: string().optional(),
26203
+ frameId: string(),
26204
+ expectedRevision: number().int().optional(),
26205
+ origins: array(object({
26206
+ annotationId: string(),
26207
+ origin: RetrainOriginSchema
26208
+ })).min(1).max(500)
26209
+ }), object({
26210
+ updated: number().int(),
26211
+ skipped: number().int(),
26212
+ revision: number().int()
26213
+ }), {
26214
+ kind: "mutation",
26215
+ auth: "admin"
25943
26216
  }), method(object({
25944
26217
  deviceId: number(),
25945
26218
  trackId: string()
@@ -28595,6 +28868,12 @@ var CameraStepOverridePatchSchema = object({
28595
28868
  settings: record(string(), unknown()).readonly().optional()
28596
28869
  });
28597
28870
  var CameraStepSettingsSchema = record(string(), record(string(), unknown()).readonly());
28871
+ /** The three root-detector choices a camera has (D507: at most one root). */
28872
+ var CameraDetectionSourceSchema = _enum([
28873
+ "pipeline",
28874
+ "onboard",
28875
+ "none"
28876
+ ]);
28598
28877
  var CameraPipelineSettingsSchema = object({
28599
28878
  stepToggles: record(string(), boolean()).optional(),
28600
28879
  stepSettings: CameraStepSettingsSchema.optional(),
@@ -29172,6 +29451,26 @@ method(object({
29172
29451
  }), object({ success: literal(true) }), {
29173
29452
  kind: "mutation",
29174
29453
  auth: "admin"
29454
+ }), method(object({ deviceId: number() }), object({
29455
+ source: CameraDetectionSourceSchema,
29456
+ explicit: boolean(),
29457
+ onboard: object({
29458
+ /** The camera has an onboard detector this system can read. */
29459
+ available: boolean(),
29460
+ /** What its detections carry — a camera with no box cannot be a root step. */
29461
+ geometry: _enum([
29462
+ "boxed",
29463
+ "while-streaming",
29464
+ "flag-only",
29465
+ "unknown"
29466
+ ])
29467
+ })
29468
+ })), method(object({
29469
+ deviceId: number(),
29470
+ source: CameraDetectionSourceSchema
29471
+ }), object({ success: literal(true) }), {
29472
+ kind: "mutation",
29473
+ auth: "admin"
29175
29474
  }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
29176
29475
  deviceId: number(),
29177
29476
  agentNodeId: string(),
@@ -32736,6 +33035,17 @@ var BatteryStatusSchema = object({
32736
33035
  */
32737
33036
  lastContactAt: number().optional(),
32738
33037
  /**
33038
+ * Ms epoch of the last COMPLETE scheduled refresh — every fact the provider
33039
+ * holds for the device (level, charging, link, device info, state slices) and
33040
+ * its cached snapshot, read together. Absent = never since this slice was
33041
+ * born. Unlike `lastUpdated` (any write, even a push of one field) this is
33042
+ * the staleness an operator can trust: the provider owns the device fact and
33043
+ * so owns the window on its age (D224, D847). Not a clock in the
33044
+ * runtime-state-durability sense: it moves once per window and must survive
33045
+ * a restart, or every restart would owe the camera a wake.
33046
+ */
33047
+ lastFullRefreshAt: number().optional(),
33048
+ /**
32739
33049
  * True when the source is a BINARY low-battery indicator (HA
32740
33050
  * `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
32741
33051
  * charge level — `percentage` is then a coarse stand-in (100 = normal,
@@ -32974,6 +33284,18 @@ var CalendarInfoSchema = object({
32974
33284
  source: CalendarSourceKindSchema,
32975
33285
  enabled: boolean()
32976
33286
  });
33287
+ /**
33288
+ * Time contract of {@link CalendarEvent}.
33289
+ *
33290
+ * - Timed event: `startMs` / `endMs` are real instants; `endMs` is exclusive.
33291
+ * - All-day event (`allDay: true`): the event is a run of calendar DATES, not
33292
+ * instants. `startMs` is UTC midnight of the first date and `endMs` is UTC
33293
+ * midnight of the day AFTER the last date (RFC 5545 exclusive DTEND), so a
33294
+ * one-day event spans exactly 24 h. Every provider produces that and no
33295
+ * consumer may read the instants in a local timezone: use
33296
+ * {@link calendarEventLocalSpan}. Reading UTC midnight as local time put an
33297
+ * all-day event on the following day for any viewer ahead of UTC.
33298
+ */
32977
33299
  var CalendarEventSchema = object({
32978
33300
  id: string().min(1),
32979
33301
  calendarId: string().min(1),
@@ -35972,7 +36294,15 @@ var HubAddressBookSchema = object({
35972
36294
  publicEndpoint: HubAddressRoleResolutionSchema
35973
36295
  }),
35974
36296
  /** The `hub=` an app link carries (D709), or null. */
35975
- appLinkHub: string().nullable()
36297
+ appLinkHub: string().nullable(),
36298
+ /**
36299
+ * Every origin a browser can really reach this hub at, in the scheme each
36300
+ * listener serves: `https://<lan>:<httpsPort>`, and `http://<lan>:<httpPort>`
36301
+ * while LAN HTTP is on, plus the public and custom addresses. Distinct from
36302
+ * `rows`, which show `http://` only while LAN HTTP is on. Never loopback,
36303
+ * never the app link. Absent on a hub older than D794's amendment.
36304
+ */
36305
+ listenerOrigins: array(string()).readonly().optional()
35976
36306
  });
35977
36307
  var AllowedAddressesSchema = object({
35978
36308
  /**
@@ -37361,7 +37691,14 @@ var TopologyNodeSchema = object({
37361
37691
  * completed a mutual-TLS handshake, `clear` otherwise. Absent for the hub,
37362
37692
  * for offline rows and when the hub cannot tell.
37363
37693
  */
37364
- meshTransport: _enum(["tls", "clear"]).optional()
37694
+ meshTransport: _enum(["tls", "clear"]).optional(),
37695
+ /**
37696
+ * Whether the hub holds this online AGENT's capability registration (its
37697
+ * `registerNode` manifest). `false` = online in the mesh but not ready: the
37698
+ * hub dropped the registration on a disconnect only it saw and the agent has
37699
+ * not re-sent it. Absent for the hub and offline rows.
37700
+ */
37701
+ capabilitiesRegistered: boolean().optional()
37365
37702
  });
37366
37703
  var CapUsageEdgeSchema = object({
37367
37704
  callerAddonId: string(),
@@ -45833,6 +46170,12 @@ Object.freeze({
45833
46170
  addonId: null,
45834
46171
  access: "view"
45835
46172
  },
46173
+ "backup.listAvailableDatabases": {
46174
+ capName: "backup",
46175
+ capScope: "system",
46176
+ addonId: null,
46177
+ access: "view"
46178
+ },
45836
46179
  "backup.listDestinations": {
45837
46180
  capName: "backup",
45838
46181
  capScope: "system",
@@ -46529,6 +46872,12 @@ Object.freeze({
46529
46872
  addonId: null,
46530
46873
  access: "create"
46531
46874
  },
46875
+ "dataStoreProvider.transact": {
46876
+ capName: "data-store-provider",
46877
+ capScope: "system",
46878
+ addonId: null,
46879
+ access: "create"
46880
+ },
46532
46881
  "dataStoreProvider.update": {
46533
46882
  capName: "data-store-provider",
46534
46883
  capScope: "system",
@@ -46547,6 +46896,12 @@ Object.freeze({
46547
46896
  addonId: null,
46548
46897
  access: "create"
46549
46898
  },
46899
+ "dataStoreProvider.upsertMany": {
46900
+ capName: "data-store-provider",
46901
+ capScope: "system",
46902
+ addonId: null,
46903
+ access: "create"
46904
+ },
46550
46905
  "dayNight.getOptions": {
46551
46906
  capName: "day-night",
46552
46907
  capScope: "device",
@@ -49373,6 +49728,12 @@ Object.freeze({
49373
49728
  addonId: null,
49374
49729
  access: "create"
49375
49730
  },
49731
+ "pipelineAnalytics.backfillRetrainOrigins": {
49732
+ capName: "pipeline-analytics",
49733
+ capScope: "device",
49734
+ addonId: null,
49735
+ access: "create"
49736
+ },
49376
49737
  "pipelineAnalytics.cancelRelocateMedia": {
49377
49738
  capName: "pipeline-analytics",
49378
49739
  capScope: "device",
@@ -50153,6 +50514,12 @@ Object.freeze({
50153
50514
  addonId: null,
50154
50515
  access: "view"
50155
50516
  },
50517
+ "pipelineOrchestrator.getCameraDetectionSource": {
50518
+ capName: "pipeline-orchestrator",
50519
+ capScope: "system",
50520
+ addonId: null,
50521
+ access: "view"
50522
+ },
50156
50523
  "pipelineOrchestrator.getCameraMetrics": {
50157
50524
  capName: "pipeline-orchestrator",
50158
50525
  capScope: "system",
@@ -50381,6 +50748,12 @@ Object.freeze({
50381
50748
  addonId: null,
50382
50749
  access: "create"
50383
50750
  },
50751
+ "pipelineOrchestrator.setCameraDetectionSource": {
50752
+ capName: "pipeline-orchestrator",
50753
+ capScope: "system",
50754
+ addonId: null,
50755
+ access: "create"
50756
+ },
50384
50757
  "pipelineOrchestrator.setCameraPipelineForAgent": {
50385
50758
  capName: "pipeline-orchestrator",
50386
50759
  capScope: "system",
@@ -51353,6 +51726,12 @@ Object.freeze({
51353
51726
  addonId: null,
51354
51727
  access: "create"
51355
51728
  },
51729
+ "settingsStore.transact": {
51730
+ capName: "settings-store",
51731
+ capScope: "system",
51732
+ addonId: null,
51733
+ access: "create"
51734
+ },
51356
51735
  "settingsStore.update": {
51357
51736
  capName: "settings-store",
51358
51737
  capScope: "system",
@@ -51371,6 +51750,12 @@ Object.freeze({
51371
51750
  addonId: null,
51372
51751
  access: "create"
51373
51752
  },
51753
+ "settingsStore.upsertMany": {
51754
+ capName: "settings-store",
51755
+ capScope: "system",
51756
+ addonId: null,
51757
+ access: "create"
51758
+ },
51374
51759
  "smoke.getStatus": {
51375
51760
  capName: "smoke",
51376
51761
  capScope: "device",
@@ -51833,6 +52218,12 @@ Object.freeze({
51833
52218
  addonId: null,
51834
52219
  access: "view"
51835
52220
  },
52221
+ "streamBroker.getLiveViewerCounts": {
52222
+ capName: "stream-broker",
52223
+ capScope: "system",
52224
+ addonId: null,
52225
+ access: "view"
52226
+ },
51836
52227
  "streamBroker.getPreBufferInfo": {
51837
52228
  capName: "stream-broker",
51838
52229
  capScope: "system",
@@ -55673,6 +56064,11 @@ Object.freeze({
55673
56064
  form: "single",
55674
56065
  optional: false
55675
56066
  }],
56067
+ "pipelineAnalytics.backfillRetrainOrigins": [{
56068
+ name: "deviceId",
56069
+ form: "single",
56070
+ optional: false
56071
+ }],
55676
56072
  "pipelineAnalytics.clearTrackRelation": [{
55677
56073
  name: "deviceId",
55678
56074
  form: "single",
@@ -55978,6 +56374,11 @@ Object.freeze({
55978
56374
  form: "single",
55979
56375
  optional: false
55980
56376
  }],
56377
+ "pipelineOrchestrator.getCameraDetectionSource": [{
56378
+ name: "deviceId",
56379
+ form: "single",
56380
+ optional: false
56381
+ }],
55981
56382
  "pipelineOrchestrator.getCameraMetrics": [{
55982
56383
  name: "deviceId",
55983
56384
  form: "single",
@@ -56038,6 +56439,11 @@ Object.freeze({
56038
56439
  form: "single",
56039
56440
  optional: false
56040
56441
  }],
56442
+ "pipelineOrchestrator.setCameraDetectionSource": [{
56443
+ name: "deviceId",
56444
+ form: "single",
56445
+ optional: false
56446
+ }],
56041
56447
  "pipelineOrchestrator.setCameraPipelineForAgent": [{
56042
56448
  name: "deviceId",
56043
56449
  form: "single",
@@ -57274,6 +57680,9 @@ new Map(Object.entries({
57274
57680
  "stream-online": "device-events",
57275
57681
  "stream-offline": "device-events",
57276
57682
  "detection-blind": "device-events",
57683
+ "recording-stalled": "device-events",
57684
+ "recording-healthy": "device-events",
57685
+ "recording-degraded": "device-events",
57277
57686
  "node-online": "system",
57278
57687
  "node-offline": "system",
57279
57688
  "node-restarting": "system",
@@ -57287,6 +57696,9 @@ new Map(Object.entries({
57287
57696
  "wrapper-update-available": "system",
57288
57697
  "backup-completed": "system",
57289
57698
  "export-completed": "system",
57699
+ "storage-location-low": "system",
57700
+ "storage-location-critical": "system",
57701
+ "storage-location-ok": "system",
57290
57702
  "alarm-triggered": "alarm",
57291
57703
  "alarm-armed": "alarm",
57292
57704
  "alarm-disarmed": "alarm",
@@ -57348,6 +57760,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
57348
57760
  label: "Detecting nothing",
57349
57761
  kinds: ["detection-blind"]
57350
57762
  },
57763
+ {
57764
+ id: "recording",
57765
+ family: "device-events",
57766
+ label: "Recording",
57767
+ kinds: [
57768
+ "recording-stalled",
57769
+ "recording-healthy",
57770
+ "recording-degraded"
57771
+ ]
57772
+ },
57351
57773
  {
57352
57774
  id: "nodes",
57353
57775
  family: "system",
@@ -57388,6 +57810,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
57388
57810
  label: "Backups & exports",
57389
57811
  kinds: ["backup-completed", "export-completed"]
57390
57812
  },
57813
+ {
57814
+ id: "storage",
57815
+ family: "system",
57816
+ label: "Storage locations",
57817
+ kinds: [
57818
+ "storage-location-low",
57819
+ "storage-location-critical",
57820
+ "storage-location-ok"
57821
+ ]
57822
+ },
57391
57823
  {
57392
57824
  id: "alarm",
57393
57825
  family: "alarm",
@@ -57470,6 +57902,9 @@ var DEVICE_EVENTS = [
57470
57902
  "stream-online",
57471
57903
  "stream-offline",
57472
57904
  "detection-blind",
57905
+ "recording-stalled",
57906
+ "recording-healthy",
57907
+ "recording-degraded",
57473
57908
  ...ALARM
57474
57909
  ];
57475
57910
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -57637,6 +58072,11 @@ var STATE_SUMMARY_VARS = [
57637
58072
  [...RULE_TEXT],
57638
58073
  [...RULE_TEXT],
57639
58074
  [...RULE_TEXT],
58075
+ [...RULE_TEXT],
58076
+ [...RULE_TEXT],
58077
+ [...RULE_TEXT],
58078
+ [...RULE_TEXT],
58079
+ [...RULE_TEXT],
57640
58080
  ([...RULE_TEXT], [...UPDATES]),
57641
58081
  ([...RULE_TEXT], [...PACKAGE_UPDATES]),
57642
58082
  ([...RULE_TEXT], [...PACKAGE_UPDATES]),