camstack 1.2.192 → 1.2.193

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-MJFET7GO.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-MJFET7GO.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`). */
@@ -69454,9 +69666,29 @@ var streamParamsCapability = {
69454
69666
  */
69455
69667
  durability: "restored",
69456
69668
  /**
69457
- * History (D850): none — encoder configuration.
69669
+ * History (D850): the configured bitrate and frame rate of the main and sub
69670
+ * profiles. Configuration, so change-only on the default floor: a point is an
69671
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
69672
+ * quality over time must show.
69458
69673
  */
69459
- history: "none",
69674
+ history: { fields: {
69675
+ "main.bitrate": {
69676
+ kind: "gauge",
69677
+ unit: "kbps"
69678
+ },
69679
+ "main.framerate": {
69680
+ kind: "gauge",
69681
+ unit: "fps"
69682
+ },
69683
+ "sub.bitrate": {
69684
+ kind: "gauge",
69685
+ unit: "kbps"
69686
+ },
69687
+ "sub.framerate": {
69688
+ kind: "gauge",
69689
+ unit: "fps"
69690
+ }
69691
+ } },
69460
69692
  /** Clock fields: written, but excluded from the compare that decides
69461
69693
  * whether persisting is worth a SQLite commit. */
69462
69694
  volatileStateFields: ["lastFetchedAt"]
@@ -75221,7 +75453,19 @@ var METHOD_ACCESS_MAP = Object.freeze({
75221
75453
  addonId: null,
75222
75454
  access: "view"
75223
75455
  },
75224
- "logDestination.query": {
75456
+ "logDestination.cancelRead": {
75457
+ capName: "log-destination",
75458
+ capScope: "system",
75459
+ addonId: null,
75460
+ access: "create"
75461
+ },
75462
+ "logDestination.describeRead": {
75463
+ capName: "log-destination",
75464
+ capScope: "system",
75465
+ addonId: null,
75466
+ access: "view"
75467
+ },
75468
+ "logDestination.read": {
75225
75469
  capName: "log-destination",
75226
75470
  capScope: "system",
75227
75471
  addonId: null,
@@ -81278,6 +81522,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
81278
81522
  form: "single",
81279
81523
  optional: false
81280
81524
  }],
81525
+ "logDestination.read": [{
81526
+ name: "deviceId",
81527
+ form: "single",
81528
+ optional: true
81529
+ }],
81281
81530
  "mediaPlayer.getStatus": [{
81282
81531
  name: "deviceId",
81283
81532
  form: "single",
@@ -83005,6 +83254,21 @@ var HISTORY_CATALOG = {
83005
83254
  deadband: 1
83006
83255
  }
83007
83256
  },
83257
+ "alarm-panel": { "state": {
83258
+ kind: "enum",
83259
+ values: [
83260
+ "disarmed",
83261
+ "armed_home",
83262
+ "armed_away",
83263
+ "armed_night",
83264
+ "armed_vacation",
83265
+ "armed_custom_bypass",
83266
+ "arming",
83267
+ "disarming",
83268
+ "pending",
83269
+ "triggered"
83270
+ ]
83271
+ } },
83008
83272
  "ambient-light-sensor": { "lux": {
83009
83273
  kind: "gauge",
83010
83274
  unit: "lx",
@@ -83049,6 +83313,7 @@ var HISTORY_CATALOG = {
83049
83313
  minIntervalMs: 0
83050
83314
  }
83051
83315
  },
83316
+ "connectivity": { "connected": { kind: "boolean" } },
83052
83317
  "contact": { "entryOpen": { kind: "boolean" } },
83053
83318
  "cover": { "position": {
83054
83319
  kind: "gauge",
@@ -83056,10 +83321,48 @@ var HISTORY_CATALOG = {
83056
83321
  minIntervalMs: 0
83057
83322
  } },
83058
83323
  "device-status": { "online": { kind: "boolean" } },
83059
- "dishwasher": { "progressPercent": {
83060
- kind: "gauge",
83061
- unit: "%",
83062
- deadband: 2
83324
+ "dishwasher": {
83325
+ "progressPercent": {
83326
+ kind: "gauge",
83327
+ unit: "%",
83328
+ deadband: 2
83329
+ },
83330
+ "state": {
83331
+ kind: "enum",
83332
+ values: [
83333
+ "idle",
83334
+ "running",
83335
+ "paused",
83336
+ "finished",
83337
+ "error",
83338
+ "unavailable"
83339
+ ]
83340
+ },
83341
+ "operationState": {
83342
+ kind: "enum",
83343
+ values: [
83344
+ "Inactive",
83345
+ "Ready",
83346
+ "DelayedStart",
83347
+ "Run",
83348
+ "Pause",
83349
+ "ActionRequired",
83350
+ "Finished",
83351
+ "Error",
83352
+ "Aborting"
83353
+ ]
83354
+ },
83355
+ "remainingSeconds": {
83356
+ kind: "gauge",
83357
+ unit: "s",
83358
+ minIntervalMs: 6e4
83359
+ },
83360
+ "doorOpen": { kind: "boolean" },
83361
+ "powerOn": { kind: "boolean" }
83362
+ },
83363
+ "enum-sensor": { "value": {
83364
+ kind: "enum",
83365
+ skipWhenSet: "format"
83063
83366
  } },
83064
83367
  "fan-control": {
83065
83368
  "percentage": {
@@ -83094,6 +83397,24 @@ var HISTORY_CATALOG = {
83094
83397
  unit: "%",
83095
83398
  deadband: 2
83096
83399
  } },
83400
+ "lock-control": { "state": {
83401
+ kind: "enum",
83402
+ values: [
83403
+ "locked",
83404
+ "unlocked",
83405
+ "locking",
83406
+ "unlocking",
83407
+ "jammed"
83408
+ ]
83409
+ } },
83410
+ "media-player": {
83411
+ "volumeLevel": {
83412
+ kind: "gauge",
83413
+ unit: "%",
83414
+ deadband: 1
83415
+ },
83416
+ "isMuted": { kind: "boolean" }
83417
+ },
83097
83418
  "motion": { "detected": {
83098
83419
  kind: "boolean",
83099
83420
  excludeDeviceTypes: [DeviceType.Camera]
@@ -83180,6 +83501,24 @@ var HISTORY_CATALOG = {
83180
83501
  deadband: 0.1
83181
83502
  } },
83182
83503
  "smoke": { "detected": { kind: "boolean" } },
83504
+ "stream-params": {
83505
+ "main.bitrate": {
83506
+ kind: "gauge",
83507
+ unit: "kbps"
83508
+ },
83509
+ "main.framerate": {
83510
+ kind: "gauge",
83511
+ unit: "fps"
83512
+ },
83513
+ "sub.bitrate": {
83514
+ kind: "gauge",
83515
+ unit: "kbps"
83516
+ },
83517
+ "sub.framerate": {
83518
+ kind: "gauge",
83519
+ unit: "fps"
83520
+ }
83521
+ },
83183
83522
  "switch": { "on": { kind: "boolean" } },
83184
83523
  "tamper": { "tampered": { kind: "boolean" } },
83185
83524
  "temperature-sensor": { "celsius": {
@@ -86032,6 +86371,23 @@ function resolveLoginServer(flag, positionals, env) {
86032
86371
  return flagged ?? positional ?? (fromEnv ? normalizeHubAddress(fromEnv) : void 0);
86033
86372
  }
86034
86373
 
86374
+ // src/commands/login-legacy-flags.ts
86375
+ var LEGACY_LOGIN_FLAG_OPTIONS = {
86376
+ admin: { type: "boolean" },
86377
+ "admin-days": { type: "string" }
86378
+ };
86379
+ var LEGACY_LOGIN_FLAG_MESSAGES = {
86380
+ admin: "--admin is ignored: one login, one token \u2014 drop --admin (admin rights follow your account).",
86381
+ "admin-days": "--admin-days is ignored: one login, one token \u2014 drop --admin-days (the session renews itself)."
86382
+ };
86383
+ function legacyLoginFlagWarnings(values) {
86384
+ const names = Object.keys(LEGACY_LOGIN_FLAG_MESSAGES).filter(isLegacyFlagName);
86385
+ return names.filter((name) => values[name] !== void 0).map((name) => LEGACY_LOGIN_FLAG_MESSAGES[name]);
86386
+ }
86387
+ function isLegacyFlagName(name) {
86388
+ return name in LEGACY_LOGIN_FLAG_OPTIONS;
86389
+ }
86390
+
86035
86391
  // src/commands/auth.ts
86036
86392
  import * as clack from "@clack/prompts";
86037
86393
  import {
@@ -87522,9 +87878,7 @@ function buildCommands() {
87522
87878
  " -n, --namespace <ns> Ignored (kept so old scripts do not fail): hubs are found over mDNS",
87523
87879
  " -u, --username <name> Username (skips prompt)",
87524
87880
  " -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"
87881
+ ` --token-name <name> Ignored (kept for scripts); login uses your hub session JWT`
87528
87882
  ].join("\n")
87529
87883
  },
87530
87884
  {
@@ -87749,10 +88103,9 @@ async function runLogin(args) {
87749
88103
  username: { type: "string", short: "u" },
87750
88104
  password: { type: "string", short: "p" },
87751
88105
  "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" },
88106
+ // Removed (D895), still parsed so an old script does not abort: each one
88107
+ // present prints a one-line warning and the login goes on.
88108
+ ...LEGACY_LOGIN_FLAG_OPTIONS,
87756
88109
  // Accepted-and-ignored: `--no-verify` is a `deploy`-only flag (skip the
87757
88110
  // post-deploy health gate). Login has no verify step, but operators
87758
88111
  // muscle-memory it in — we swallow it here so `camstack login --no-verify`
@@ -87773,6 +88126,7 @@ async function runLogin(args) {
87773
88126
  if (stringOpt(parsed.values, "namespace") !== void 0) {
87774
88127
  console.warn("--namespace is ignored: hubs are found over mDNS, not the mesh channel.");
87775
88128
  }
88129
+ for (const warning of legacyLoginFlagWarnings(parsed.values)) console.warn(warning);
87776
88130
  await loginCommand({
87777
88131
  ...explicitServer ? { server: explicitServer } : {},
87778
88132
  ...optionalString(parsed.values, "username"),