camstack 1.2.192 → 1.2.194

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/cli.js CHANGED
@@ -37,7 +37,7 @@ async function runServe(args) {
37
37
  ...typeof values.data === "string" ? { data: values.data } : {}
38
38
  };
39
39
  Object.assign(process.env, buildServeEnv(opts));
40
- await import("./launcher-PJJ7PTWL.js");
40
+ await import("./launcher-UJ7M7YRF.js");
41
41
  }
42
42
 
43
43
  // src/commands/agent.ts
@@ -82,7 +82,7 @@ async function runAgent(args) {
82
82
  ...typeof values.port === "string" ? { port: values.port } : {}
83
83
  };
84
84
  Object.assign(process.env, buildAgentEnv(opts));
85
- await import("./launcher-PJJ7PTWL.js");
85
+ await import("./launcher-UJ7M7YRF.js");
86
86
  }
87
87
 
88
88
  // src/commands/setup.ts
@@ -14773,7 +14773,7 @@ function date4(params) {
14773
14773
  // ../../node_modules/zod/v4/classic/external.js
14774
14774
  config(en_default());
14775
14775
 
14776
- // ../types/dist/sleep-yKL5gfrH.mjs
14776
+ // ../types/dist/sleep-BSuCCFjf.mjs
14777
14777
  var AUDIO_CHUNK_FORMATS = [
14778
14778
  "f32le",
14779
14779
  "pcmu",
@@ -23362,6 +23362,12 @@ var DeviceHistorySubjectSchema = external_exports.discriminatedUnion("kind", [ex
23362
23362
  nodeId: external_exports.string().min(1)
23363
23363
  })]);
23364
23364
  var DeviceHistoryKindSchema = external_exports.enum([
23365
+ "gauge",
23366
+ "counter",
23367
+ "boolean",
23368
+ "enum"
23369
+ ]);
23370
+ var DeviceHistoryProducerKindSchema = external_exports.enum([
23365
23371
  "gauge",
23366
23372
  "counter",
23367
23373
  "boolean"
@@ -23397,7 +23403,13 @@ var SeriesInfoSchema = external_exports.object({
23397
23403
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
23398
23404
  unit: external_exports.string().nullable(),
23399
23405
  displayName: external_exports.string(),
23400
- source: external_exports.enum(["cap", "addon"]),
23406
+ source: external_exports.enum([
23407
+ "cap",
23408
+ "addon",
23409
+ "derived"
23410
+ ]),
23411
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
23412
+ values: external_exports.array(external_exports.string()).readonly().nullable(),
23401
23413
  firstTs: external_exports.number(),
23402
23414
  lastTs: external_exports.number()
23403
23415
  });
@@ -23411,17 +23423,31 @@ var QueryPointSchema = external_exports.object({
23411
23423
  twMean: external_exports.number().nullable(),
23412
23424
  min: external_exports.number(),
23413
23425
  max: external_exports.number(),
23414
- /** `null` is unknown, never zero (D393). */
23415
- last: external_exports.number().nullable()
23426
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
23427
+ last: external_exports.number().nullable(),
23428
+ /**
23429
+ * The increase over the point: a `counter`'s growth since the previous point
23430
+ * or bucket (a drop is a reset, counted from zero), and for
23431
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
23432
+ * every other kind, and when it cannot be known.
23433
+ */
23434
+ delta: external_exports.number().nullable(),
23435
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
23436
+ state: external_exports.string().nullable(),
23437
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
23438
+ states: external_exports.record(external_exports.string(), external_exports.number()).nullable()
23416
23439
  });
23417
23440
  var QuerySeriesSchema = external_exports.object({
23418
23441
  scope: external_exports.string(),
23419
23442
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
23420
23443
  before: external_exports.object({
23421
23444
  t: external_exports.number(),
23422
- value: external_exports.number().nullable()
23445
+ value: external_exports.number().nullable(),
23446
+ state: external_exports.string().nullable()
23423
23447
  }).nullable(),
23424
- points: external_exports.array(QueryPointSchema).readonly()
23448
+ points: external_exports.array(QueryPointSchema).readonly(),
23449
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
23450
+ derivedFrom: external_exports.string().nullable()
23425
23451
  });
23426
23452
  var QueryWindowShape = {
23427
23453
  key: external_exports.string(),
@@ -23436,6 +23462,22 @@ var QueryResultSchema = external_exports.object({
23436
23462
  series: external_exports.array(QuerySeriesSchema).readonly(),
23437
23463
  truncated: external_exports.boolean()
23438
23464
  });
23465
+ var QueryManyItemSchema = external_exports.union([external_exports.object({
23466
+ deviceId: external_exports.number().int(),
23467
+ key: external_exports.string(),
23468
+ scope: external_exports.string().optional()
23469
+ }), external_exports.object({
23470
+ forNodeId: external_exports.string().min(1),
23471
+ key: external_exports.string(),
23472
+ scope: external_exports.string().optional()
23473
+ })]);
23474
+ var QueryManyEntrySchema = external_exports.discriminatedUnion("ok", [external_exports.object({
23475
+ ok: external_exports.literal(true),
23476
+ result: QueryResultSchema
23477
+ }), external_exports.object({
23478
+ ok: external_exports.literal(false),
23479
+ error: external_exports.string()
23480
+ })]);
23439
23481
  var TierStatusSchema = external_exports.object({
23440
23482
  tier: DeviceHistoryResolutionSchema,
23441
23483
  /** `null` until the first background count answered. */
@@ -23503,26 +23545,45 @@ var deviceHistoryCapability = {
23503
23545
  * `listNodeSeries` / `queryNode`.
23504
23546
  */
23505
23547
  listSeries: method(external_exports.object({ deviceId: external_exports.number().int() }), external_exports.array(SeriesInfoSchema).readonly()),
23506
- listNodeSeries: method(external_exports.object({ nodeId: external_exports.string().min(1) }), external_exports.array(SeriesInfoSchema).readonly(), { auth: "admin" }),
23548
+ /**
23549
+ * A NODE's series. The subject is `forNodeId`, never `nodeId`: a top-level
23550
+ * `nodeId` is the cap ROUTING key, and `nodeId: 'little-unraid'` sent the
23551
+ * read to that agent, which hosts no device-history.
23552
+ */
23553
+ listNodeSeries: method(external_exports.object({ forNodeId: external_exports.string().min(1) }), external_exports.array(SeriesInfoSchema).readonly(), { auth: "admin" }),
23507
23554
  /**
23508
23555
  * One series (or every scope of it) at one resolution. `auto` picks the
23509
23556
  * finest tier whose retention covers `from` and whose point count fits
23510
23557
  * `maxPoints`; when even the coarsest tier does not fit, the newest
23511
- * `maxPoints` points are returned and `truncated` is true.
23558
+ * `maxPoints` points are returned and `truncated` is true. A series fed by
23559
+ * closed buckets has no raw rows, so `auto` never answers it from raw; nor
23560
+ * {@link DEVICE_HISTORY_ENERGY_KEY}, which is computed from rollups.
23512
23561
  */
23513
23562
  query: method(external_exports.object({
23514
23563
  deviceId: external_exports.number().int(),
23515
23564
  ...QueryWindowShape
23516
23565
  }), QueryResultSchema),
23517
23566
  queryNode: method(external_exports.object({
23518
- nodeId: external_exports.string().min(1),
23567
+ forNodeId: external_exports.string().min(1),
23519
23568
  ...QueryWindowShape
23520
23569
  }), QueryResultSchema, { auth: "admin" }),
23570
+ /**
23571
+ * Several reads over ONE window, answered in order (one entry per item).
23572
+ * Admin-only: its subjects are nested in `items`, where the device scope
23573
+ * gate cannot see them — a principal limited to one device uses `query`.
23574
+ */
23575
+ queryMany: method(external_exports.object({
23576
+ items: external_exports.array(QueryManyItemSchema).min(1).max(24),
23577
+ from: QueryWindowShape.from,
23578
+ to: QueryWindowShape.to,
23579
+ resolution: QueryWindowShape.resolution,
23580
+ maxPoints: QueryWindowShape.maxPoints
23581
+ }), external_exports.object({ results: external_exports.array(QueryManyEntrySchema).readonly() }), { auth: "admin" }),
23521
23582
  /** Producer: declare (idempotent) a series key this addon owns: `addon:<callerAddonId>/<name>`. */
23522
23583
  declareSeries: method(external_exports.object({
23523
23584
  name: external_exports.string().regex(/^[a-z0-9-]+$/),
23524
23585
  subjectKind: external_exports.enum(["device", "node"]),
23525
- kind: DeviceHistoryKindSchema,
23586
+ kind: DeviceHistoryProducerKindSchema,
23526
23587
  unit: external_exports.string().optional(),
23527
23588
  displayName: external_exports.string().min(1),
23528
23589
  ingest: external_exports.enum(["points", "buckets"])
@@ -47077,6 +47138,88 @@ var LogEntrySchema = external_exports.object({
47077
47138
  meta: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
47078
47139
  tags: external_exports.record(external_exports.string(), external_exports.string()).optional()
47079
47140
  });
47141
+ var LogReadQuerySchema = external_exports.object({
47142
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
47143
+ requestId: external_exports.string().min(1).max(64).optional(),
47144
+ /** The device the line is about (`tags.deviceId`, numeric). */
47145
+ deviceId: external_exports.number().int().optional(),
47146
+ /**
47147
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
47148
+ * match. Not `addonId`: a cap router reads that name as "which provider".
47149
+ */
47150
+ fromAddonId: external_exports.string().min(1).max(200).optional(),
47151
+ /**
47152
+ * The emitting node: matches the agent that emitted the line, the node
47153
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
47154
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
47155
+ * name as "which node's provider".
47156
+ */
47157
+ fromNodeId: external_exports.string().min(1).max(200).optional(),
47158
+ /** Any other tag, exact match (AND). */
47159
+ tags: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number()])).optional(),
47160
+ /** Severity FLOOR: this level and above. */
47161
+ level: LogLevelSchema.optional(),
47162
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
47163
+ text: external_exports.string().min(1).max(200).optional(),
47164
+ /** Epoch ms, inclusive. */
47165
+ since: external_exports.number().optional(),
47166
+ /** Epoch ms, inclusive. */
47167
+ until: external_exports.number().optional(),
47168
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
47169
+ before: external_exports.string().min(1).max(1024).optional(),
47170
+ /** Newer than this cursor (exclusive). */
47171
+ after: external_exports.string().min(1).max(1024).optional(),
47172
+ limit: external_exports.number().int().min(1).max(1e3).optional(),
47173
+ /** Wall-clock bound of this slice. The provider caps it. */
47174
+ budgetMs: external_exports.number().int().min(50).max(1e4).optional()
47175
+ });
47176
+ var LogReadEntrySchema = external_exports.object({
47177
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
47178
+ id: external_exports.string().optional(),
47179
+ /** Epoch ms. */
47180
+ timestamp: external_exports.number(),
47181
+ level: LogLevelSchema,
47182
+ scope: external_exports.string().optional(),
47183
+ message: external_exports.string(),
47184
+ tags: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number()])).optional(),
47185
+ meta: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
47186
+ });
47187
+ var LogReadResultSchema = external_exports.object({
47188
+ /** Newest first. */
47189
+ entries: external_exports.array(LogReadEntrySchema),
47190
+ /** Pass as `before` for the next older page; null when nothing older exists. */
47191
+ nextBefore: external_exports.string().nullable(),
47192
+ /** Pass as `after` to read what arrived since; null when unknown. */
47193
+ nextAfter: external_exports.string().nullable(),
47194
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
47195
+ scannedBytes: external_exports.number().int().nonnegative(),
47196
+ /**
47197
+ * True when the scan in this direction reached the end of the store.
47198
+ * False with fewer than `limit` entries means the budget ran out first —
47199
+ * call again with `nextBefore` to go on.
47200
+ */
47201
+ done: external_exports.boolean(),
47202
+ /** True when `cancelRead` ended this slice early. */
47203
+ cancelled: external_exports.boolean().optional()
47204
+ });
47205
+ var LogReadCapabilitiesSchema = external_exports.object({
47206
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
47207
+ readable: external_exports.boolean(),
47208
+ /** Why not, when `readable` is false — rendered next to the source. */
47209
+ reason: external_exports.string().nullable(),
47210
+ /** Filters the provider applies itself. A false one is applied by nobody. */
47211
+ filters: external_exports.object({
47212
+ deviceId: external_exports.boolean(),
47213
+ addonId: external_exports.boolean(),
47214
+ nodeId: external_exports.boolean(),
47215
+ tags: external_exports.boolean(),
47216
+ level: external_exports.boolean(),
47217
+ text: external_exports.boolean(),
47218
+ timeRange: external_exports.boolean()
47219
+ }),
47220
+ /** How far back the store reaches, when the provider knows (days). */
47221
+ retentionDays: external_exports.number().nullable()
47222
+ });
47080
47223
  var logDestinationCapability = {
47081
47224
  name: "log-destination",
47082
47225
  scope: "system",
@@ -47084,14 +47227,13 @@ var logDestinationCapability = {
47084
47227
  internal: true,
47085
47228
  methods: {
47086
47229
  write: method(LogEntrySchema, external_exports.void(), { kind: "mutation" }),
47087
- query: method(external_exports.object({
47088
- scope: external_exports.array(external_exports.string()).optional(),
47089
- level: LogLevelSchema.optional(),
47090
- since: external_exports.date().optional(),
47091
- until: external_exports.date().optional(),
47092
- limit: external_exports.number().optional(),
47093
- tags: external_exports.record(external_exports.string(), external_exports.string()).optional()
47094
- }), external_exports.array(LogEntrySchema).readonly())
47230
+ /** Absent ⇒ the destination cannot read back (same as `readable: false`). */
47231
+ describeRead: optionalMethod(external_exports.void(), LogReadCapabilitiesSchema, { auth: "admin" }),
47232
+ read: optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }),
47233
+ cancelRead: optionalMethod(external_exports.object({ requestId: external_exports.string().min(1).max(64) }), external_exports.object({ cancelled: external_exports.boolean() }), {
47234
+ kind: "mutation",
47235
+ auth: "admin"
47236
+ })
47095
47237
  },
47096
47238
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
47097
47239
  mount: { kind: "skip" }
@@ -48698,9 +48840,11 @@ var alarmPanelCapability = {
48698
48840
  */
48699
48841
  durability: "restored",
48700
48842
  /**
48701
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
48843
+ * History (D850): the panel's lifecycle state as an `enum` series —
48844
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
48845
+ * few seconds keeps every step. Who armed it stays in the events ledger.
48702
48846
  */
48703
- history: "none",
48847
+ history: { fields: { state: { kind: "enum" } } },
48704
48848
  /** Clock fields: written, but excluded from the compare that decides
48705
48849
  * whether persisting is worth a SQLite commit. */
48706
48850
  volatileStateFields: ["lastChangedAt"]
@@ -49268,6 +49412,12 @@ var NcRuleTargetSchema = external_exports.object({
49268
49412
  */
49269
49413
  params: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
49270
49414
  });
49415
+ var NcMediaImageSchema = external_exports.enum([
49416
+ "scene-boxes",
49417
+ "crop",
49418
+ "clean",
49419
+ "none"
49420
+ ]);
49271
49421
  var NcMediaFrameSchema = external_exports.enum([
49272
49422
  "cropped",
49273
49423
  "full",
@@ -49275,16 +49425,29 @@ var NcMediaFrameSchema = external_exports.enum([
49275
49425
  ]);
49276
49426
  var NcLinkedCameraModeSchema = external_exports.enum(["mosaic", "each"]);
49277
49427
  var NcMediaPolicySchema = external_exports.object({
49428
+ /**
49429
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
49430
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
49431
+ * triple below, at load and at every write, and the store keeps only this.
49432
+ */
49433
+ image: NcMediaImageSchema.optional(),
49434
+ /**
49435
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
49436
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
49437
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
49438
+ * Replaces `zoneCrop`.
49439
+ */
49440
+ showTriggerZone: external_exports.boolean().optional(),
49441
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
49278
49442
  attach: external_exports.enum([
49279
49443
  "best",
49280
49444
  "best-matching",
49281
49445
  "keyFrame",
49282
49446
  "none"
49283
- ]).default("best"),
49284
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
49447
+ ]).optional(),
49448
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
49285
49449
  frame: NcMediaFrameSchema.optional(),
49286
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
49287
- * "show me the ZONE", not the whole scene or the subject crop. */
49450
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
49288
49451
  zoneCrop: external_exports.boolean().optional(),
49289
49452
  /**
49290
49453
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -49411,7 +49574,9 @@ var NcRuleInputSchema = external_exports.object({
49411
49574
  * targets.
49412
49575
  */
49413
49576
  targetUsers: external_exports.array(external_exports.string()).optional(),
49414
- media: NcMediaPolicySchema.default({ attach: "best" }),
49577
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
49578
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
49579
+ media: NcMediaPolicySchema.default({}),
49415
49580
  throttle: NcThrottleSchema.default({
49416
49581
  cooldownSec: 60,
49417
49582
  scope: "rule-device"
@@ -50168,13 +50333,31 @@ var NcAlarmModeOpeningsSchema = external_exports.object({
50168
50333
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
50169
50334
  unknown: external_exports.array(external_exports.number().int())
50170
50335
  });
50336
+ var NcAlarmInputBypassViewSchema = external_exports.object({
50337
+ ruleId: external_exports.string(),
50338
+ /** The rule's current name (its frozen name when the rule is gone). */
50339
+ ruleName: external_exports.string(),
50340
+ /** The input: the sensor of the match, else its camera. */
50341
+ deviceId: external_exports.number().int(),
50342
+ /** The input's current name. */
50343
+ name: external_exports.string(),
50344
+ /** When it was bypassed (ms epoch). */
50345
+ since: external_exports.number(),
50346
+ /** Triggers from this input dropped since. */
50347
+ dropped: external_exports.number().int().min(0)
50348
+ });
50171
50349
  var NcAlarmLiveSchema = external_exports.object({
50172
50350
  state: AlarmStateSchema,
50173
50351
  /** The mode being armed into (exit delay) or held; null when disarmed. */
50174
50352
  targetMode: AlarmArmModeSchema.nullable(),
50175
50353
  availableModes: external_exports.array(AlarmArmModeSchema),
50176
50354
  openings: external_exports.array(NcAlarmModeOpeningsSchema),
50177
- exclusions: external_exports.array(NcAlarmExclusionViewSchema)
50355
+ exclusions: external_exports.array(NcAlarmExclusionViewSchema),
50356
+ /**
50357
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
50358
+ * Defaulted so an older hub answer still parses (as "none known").
50359
+ */
50360
+ bypassedInputs: external_exports.array(NcAlarmInputBypassViewSchema).default([])
50178
50361
  });
50179
50362
  var NcAlarmConfigSchema = external_exports.object({
50180
50363
  /**
@@ -61822,9 +62005,11 @@ var connectivityCapability = {
61822
62005
  */
61823
62006
  durability: "restored",
61824
62007
  /**
61825
- * History (D850): none — duplicates device-status.online (one authority for availability).
62008
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
62009
+ * is the upstream entity's own link (a HA connectivity sensor), not the
62010
+ * device's reachability, which stays `device-status.online`.
61826
62011
  */
61827
- history: "none",
62012
+ history: { fields: { connected: { kind: "boolean" } } },
61828
62013
  /** Clock fields: written, but excluded from the compare that decides
61829
62014
  * whether persisting is worth a SQLite commit. */
61830
62015
  volatileStateFields: ["lastChangedAt"]
@@ -62521,11 +62706,22 @@ var dishwasherCapability = {
62521
62706
  },
62522
62707
  runtimeState: DishwasherStatusSchema,
62523
62708
  durability: "session",
62524
- history: { fields: { progressPercent: {
62525
- kind: "gauge",
62526
- unit: "%",
62527
- deadband: 2
62528
- } } }
62709
+ history: { fields: {
62710
+ progressPercent: {
62711
+ kind: "gauge",
62712
+ unit: "%",
62713
+ deadband: 2
62714
+ },
62715
+ state: { kind: "enum" },
62716
+ operationState: { kind: "enum" },
62717
+ remainingSeconds: {
62718
+ kind: "gauge",
62719
+ unit: "s",
62720
+ minIntervalMs: 6e4
62721
+ },
62722
+ doorOpen: { kind: "boolean" },
62723
+ powerOn: { kind: "boolean" }
62724
+ } }
62529
62725
  };
62530
62726
  var DoorbellStatusSchema = external_exports.object({
62531
62727
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -62618,9 +62814,15 @@ var enumSensorCapability = {
62618
62814
  */
62619
62815
  durability: "restored",
62620
62816
  /**
62621
- * History (D850): none — text/enum state has no history (non-goal).
62817
+ * History (D850): the value as an `enum` series (an appliance's program or
62818
+ * operation state, an HVAC action). The option set is per device, so the
62819
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
62820
+ * `format` carries a timestamp, not a state, and is not recorded.
62622
62821
  */
62623
- history: "none",
62822
+ history: { fields: { value: {
62823
+ kind: "enum",
62824
+ skipWhenSet: "format"
62825
+ } } },
62624
62826
  /** Clock fields: written, but excluded from the compare that decides
62625
62827
  * whether persisting is worth a SQLite commit. */
62626
62828
  volatileStateFields: ["lastFetchedAt"]
@@ -64489,9 +64691,10 @@ var lockControlCapability = {
64489
64691
  */
64490
64692
  durability: "restored",
64491
64693
  /**
64492
- * History (D850): none — enum state; lock events belong in the events ledger.
64694
+ * History (D850): the lock's state as an `enum` series — change-only, no
64695
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
64493
64696
  */
64494
- history: "none",
64697
+ history: { fields: { state: { kind: "enum" } } },
64495
64698
  /** Clock fields: written, but excluded from the compare that decides
64496
64699
  * whether persisting is worth a SQLite commit. */
64497
64700
  volatileStateFields: ["lastChangedAt"]
@@ -64653,9 +64856,18 @@ var mediaPlayerCapability = {
64653
64856
  */
64654
64857
  durability: "session",
64655
64858
  /**
64656
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
64859
+ * History (D850): volume (a level an operator or an automation sets; the
64860
+ * default 10 s floor folds a slider drag into its end value) and mute.
64861
+ * `positionMs` is not recorded: it moves continuously while playing.
64657
64862
  */
64658
- history: "none"
64863
+ history: { fields: {
64864
+ volumeLevel: {
64865
+ kind: "gauge",
64866
+ unit: "%",
64867
+ deadband: 1
64868
+ },
64869
+ isMuted: { kind: "boolean" }
64870
+ } }
64659
64871
  };
64660
64872
  var MeshEndpointSchema = external_exports.object({
64661
64873
  /** Stable identifier within the provider (e.g. `mesh-ipv4`, `magicdns`, `funnel`). */
@@ -66688,9 +66900,24 @@ var NpuInfoSchema = external_exports.object({
66688
66900
  name: external_exports.string().optional(),
66689
66901
  generation: external_exports.enum(["xdna1", "xdna2"]).optional()
66690
66902
  });
66903
+ var CoralBusSchema = external_exports.enum(["usb", "pci"]);
66691
66904
  var CoralInfoSchema = external_exports.object({
66692
66905
  type: external_exports.literal("coral-edgetpu"),
66693
- bus: external_exports.string().optional()
66906
+ /** Legacy single-bus report (older nodes) — read via `coralUsableUnits`. */
66907
+ bus: external_exports.string().optional(),
66908
+ /** Legacy USB unit count (older nodes) — read via `coralUsableUnits`. */
66909
+ count: external_exports.number().int().nonnegative().optional(),
66910
+ /** Usable units per bus — each one is its own `edgetpu:<bus>[:N]` device. */
66911
+ units: external_exports.array(external_exports.object({
66912
+ bus: CoralBusSchema,
66913
+ count: external_exports.number().int().nonnegative()
66914
+ })).readonly().optional(),
66915
+ /** Present-but-unusable units, each with its typed reason (never "absent"). */
66916
+ unavailable: external_exports.array(external_exports.object({
66917
+ bus: CoralBusSchema,
66918
+ count: external_exports.number().int().nonnegative(),
66919
+ reason: external_exports.enum(["driver-missing", "device-not-accessible"])
66920
+ })).readonly().optional()
66694
66921
  });
66695
66922
  var HardwareInfoSchema = external_exports.object({
66696
66923
  platform: HardwarePlatformSchema,
@@ -69454,9 +69681,29 @@ var streamParamsCapability = {
69454
69681
  */
69455
69682
  durability: "restored",
69456
69683
  /**
69457
- * History (D850): none — encoder configuration.
69684
+ * History (D850): the configured bitrate and frame rate of the main and sub
69685
+ * profiles. Configuration, so change-only on the default floor: a point is an
69686
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
69687
+ * quality over time must show.
69458
69688
  */
69459
- history: "none",
69689
+ history: { fields: {
69690
+ "main.bitrate": {
69691
+ kind: "gauge",
69692
+ unit: "kbps"
69693
+ },
69694
+ "main.framerate": {
69695
+ kind: "gauge",
69696
+ unit: "fps"
69697
+ },
69698
+ "sub.bitrate": {
69699
+ kind: "gauge",
69700
+ unit: "kbps"
69701
+ },
69702
+ "sub.framerate": {
69703
+ kind: "gauge",
69704
+ unit: "fps"
69705
+ }
69706
+ } },
69460
69707
  /** Clock fields: written, but excluded from the compare that decides
69461
69708
  * whether persisting is worth a SQLite commit. */
69462
69709
  volatileStateFields: ["lastFetchedAt"]
@@ -75221,7 +75468,19 @@ var METHOD_ACCESS_MAP = Object.freeze({
75221
75468
  addonId: null,
75222
75469
  access: "view"
75223
75470
  },
75224
- "logDestination.query": {
75471
+ "logDestination.cancelRead": {
75472
+ capName: "log-destination",
75473
+ capScope: "system",
75474
+ addonId: null,
75475
+ access: "create"
75476
+ },
75477
+ "logDestination.describeRead": {
75478
+ capName: "log-destination",
75479
+ capScope: "system",
75480
+ addonId: null,
75481
+ access: "view"
75482
+ },
75483
+ "logDestination.read": {
75225
75484
  capName: "log-destination",
75226
75485
  capScope: "system",
75227
75486
  addonId: null,
@@ -81278,6 +81537,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
81278
81537
  form: "single",
81279
81538
  optional: false
81280
81539
  }],
81540
+ "logDestination.read": [{
81541
+ name: "deviceId",
81542
+ form: "single",
81543
+ optional: true
81544
+ }],
81281
81545
  "mediaPlayer.getStatus": [{
81282
81546
  name: "deviceId",
81283
81547
  form: "single",
@@ -83005,6 +83269,21 @@ var HISTORY_CATALOG = {
83005
83269
  deadband: 1
83006
83270
  }
83007
83271
  },
83272
+ "alarm-panel": { "state": {
83273
+ kind: "enum",
83274
+ values: [
83275
+ "disarmed",
83276
+ "armed_home",
83277
+ "armed_away",
83278
+ "armed_night",
83279
+ "armed_vacation",
83280
+ "armed_custom_bypass",
83281
+ "arming",
83282
+ "disarming",
83283
+ "pending",
83284
+ "triggered"
83285
+ ]
83286
+ } },
83008
83287
  "ambient-light-sensor": { "lux": {
83009
83288
  kind: "gauge",
83010
83289
  unit: "lx",
@@ -83049,6 +83328,7 @@ var HISTORY_CATALOG = {
83049
83328
  minIntervalMs: 0
83050
83329
  }
83051
83330
  },
83331
+ "connectivity": { "connected": { kind: "boolean" } },
83052
83332
  "contact": { "entryOpen": { kind: "boolean" } },
83053
83333
  "cover": { "position": {
83054
83334
  kind: "gauge",
@@ -83056,10 +83336,48 @@ var HISTORY_CATALOG = {
83056
83336
  minIntervalMs: 0
83057
83337
  } },
83058
83338
  "device-status": { "online": { kind: "boolean" } },
83059
- "dishwasher": { "progressPercent": {
83060
- kind: "gauge",
83061
- unit: "%",
83062
- deadband: 2
83339
+ "dishwasher": {
83340
+ "progressPercent": {
83341
+ kind: "gauge",
83342
+ unit: "%",
83343
+ deadband: 2
83344
+ },
83345
+ "state": {
83346
+ kind: "enum",
83347
+ values: [
83348
+ "idle",
83349
+ "running",
83350
+ "paused",
83351
+ "finished",
83352
+ "error",
83353
+ "unavailable"
83354
+ ]
83355
+ },
83356
+ "operationState": {
83357
+ kind: "enum",
83358
+ values: [
83359
+ "Inactive",
83360
+ "Ready",
83361
+ "DelayedStart",
83362
+ "Run",
83363
+ "Pause",
83364
+ "ActionRequired",
83365
+ "Finished",
83366
+ "Error",
83367
+ "Aborting"
83368
+ ]
83369
+ },
83370
+ "remainingSeconds": {
83371
+ kind: "gauge",
83372
+ unit: "s",
83373
+ minIntervalMs: 6e4
83374
+ },
83375
+ "doorOpen": { kind: "boolean" },
83376
+ "powerOn": { kind: "boolean" }
83377
+ },
83378
+ "enum-sensor": { "value": {
83379
+ kind: "enum",
83380
+ skipWhenSet: "format"
83063
83381
  } },
83064
83382
  "fan-control": {
83065
83383
  "percentage": {
@@ -83094,6 +83412,24 @@ var HISTORY_CATALOG = {
83094
83412
  unit: "%",
83095
83413
  deadband: 2
83096
83414
  } },
83415
+ "lock-control": { "state": {
83416
+ kind: "enum",
83417
+ values: [
83418
+ "locked",
83419
+ "unlocked",
83420
+ "locking",
83421
+ "unlocking",
83422
+ "jammed"
83423
+ ]
83424
+ } },
83425
+ "media-player": {
83426
+ "volumeLevel": {
83427
+ kind: "gauge",
83428
+ unit: "%",
83429
+ deadband: 1
83430
+ },
83431
+ "isMuted": { kind: "boolean" }
83432
+ },
83097
83433
  "motion": { "detected": {
83098
83434
  kind: "boolean",
83099
83435
  excludeDeviceTypes: [DeviceType.Camera]
@@ -83180,6 +83516,24 @@ var HISTORY_CATALOG = {
83180
83516
  deadband: 0.1
83181
83517
  } },
83182
83518
  "smoke": { "detected": { kind: "boolean" } },
83519
+ "stream-params": {
83520
+ "main.bitrate": {
83521
+ kind: "gauge",
83522
+ unit: "kbps"
83523
+ },
83524
+ "main.framerate": {
83525
+ kind: "gauge",
83526
+ unit: "fps"
83527
+ },
83528
+ "sub.bitrate": {
83529
+ kind: "gauge",
83530
+ unit: "kbps"
83531
+ },
83532
+ "sub.framerate": {
83533
+ kind: "gauge",
83534
+ unit: "fps"
83535
+ }
83536
+ },
83183
83537
  "switch": { "on": { kind: "boolean" } },
83184
83538
  "tamper": { "tampered": { kind: "boolean" } },
83185
83539
  "temperature-sensor": { "celsius": {
@@ -86032,6 +86386,23 @@ function resolveLoginServer(flag, positionals, env) {
86032
86386
  return flagged ?? positional ?? (fromEnv ? normalizeHubAddress(fromEnv) : void 0);
86033
86387
  }
86034
86388
 
86389
+ // src/commands/login-legacy-flags.ts
86390
+ var LEGACY_LOGIN_FLAG_OPTIONS = {
86391
+ admin: { type: "boolean" },
86392
+ "admin-days": { type: "string" }
86393
+ };
86394
+ var LEGACY_LOGIN_FLAG_MESSAGES = {
86395
+ admin: "--admin is ignored: one login, one token \u2014 drop --admin (admin rights follow your account).",
86396
+ "admin-days": "--admin-days is ignored: one login, one token \u2014 drop --admin-days (the session renews itself)."
86397
+ };
86398
+ function legacyLoginFlagWarnings(values) {
86399
+ const names = Object.keys(LEGACY_LOGIN_FLAG_MESSAGES).filter(isLegacyFlagName);
86400
+ return names.filter((name) => values[name] !== void 0).map((name) => LEGACY_LOGIN_FLAG_MESSAGES[name]);
86401
+ }
86402
+ function isLegacyFlagName(name) {
86403
+ return name in LEGACY_LOGIN_FLAG_OPTIONS;
86404
+ }
86405
+
86035
86406
  // src/commands/auth.ts
86036
86407
  import * as clack from "@clack/prompts";
86037
86408
  import {
@@ -87522,9 +87893,7 @@ function buildCommands() {
87522
87893
  " -n, --namespace <ns> Ignored (kept so old scripts do not fail): hubs are found over mDNS",
87523
87894
  " -u, --username <name> Username (skips prompt)",
87524
87895
  " -p, --password <pwd> Password (skips prompt \u2014 prefer letting the CLI prompt)",
87525
- ` --token-name <name> Ignored (kept for scripts); login uses your hub session JWT`,
87526
- " --admin Ignored (kept for muscle memory); admin follows your account role",
87527
- " --admin-days <n> Ignored (kept for muscle memory); one login, one token format"
87896
+ ` --token-name <name> Ignored (kept for scripts); login uses your hub session JWT`
87528
87897
  ].join("\n")
87529
87898
  },
87530
87899
  {
@@ -87749,10 +88118,9 @@ async function runLogin(args) {
87749
88118
  username: { type: "string", short: "u" },
87750
88119
  password: { type: "string", short: "p" },
87751
88120
  "token-name": { type: "string" },
87752
- // Accepted-and-ignored: role comes from the logged-in user (D884). Operators
87753
- // still type `camstack login --admin <host>` from muscle memory — never fail.
87754
- admin: { type: "boolean" },
87755
- "admin-days": { type: "string" },
88121
+ // Removed (D895), still parsed so an old script does not abort: each one
88122
+ // present prints a one-line warning and the login goes on.
88123
+ ...LEGACY_LOGIN_FLAG_OPTIONS,
87756
88124
  // Accepted-and-ignored: `--no-verify` is a `deploy`-only flag (skip the
87757
88125
  // post-deploy health gate). Login has no verify step, but operators
87758
88126
  // muscle-memory it in — we swallow it here so `camstack login --no-verify`
@@ -87773,6 +88141,7 @@ async function runLogin(args) {
87773
88141
  if (stringOpt(parsed.values, "namespace") !== void 0) {
87774
88142
  console.warn("--namespace is ignored: hubs are found over mDNS, not the mesh channel.");
87775
88143
  }
88144
+ for (const warning of legacyLoginFlagWarnings(parsed.values)) console.warn(warning);
87776
88145
  await loginCommand({
87777
88146
  ...explicitServer ? { server: explicitServer } : {},
87778
88147
  ...optionalString(parsed.values, "username"),