@camstack/addon-training 0.1.107 → 0.1.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{MotionZonesSettings-B-HW_hQS.mjs → MotionZonesSettings-BFubqBUi.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-D24QEivW.mjs → PrivacyMaskSettings-sNWgI2Ak.mjs} +2 -2
  4. package/dist/{SceneMonitorEditor-BJhJhwU_.mjs → SceneMonitorEditor-CyQQi49c.mjs} +2 -2
  5. package/dist/_stub.js +1399 -1365
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-BRcFqfn3.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-CoE4OqSm.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-L5NIyvFm.mjs +26 -0
  8. package/dist/{dist-BzQ67_ca.js → dist-BkNG49yZ.js} +584 -67
  9. package/dist/{dist-CJWYZwLF.mjs → dist-DW0wmCpB.mjs} +584 -67
  10. package/dist/{hostInit-B2Q4U9vQ.mjs → hostInit-C5xfMSma.mjs} +2 -2
  11. package/dist/index.js +1 -1
  12. package/dist/orchestrator/training.addon.js +1 -1
  13. package/dist/orchestrator/training.addon.mjs +1 -1
  14. package/dist/{player-overlays-CAEteoxw.mjs → player-overlays-DPQZJVmM.mjs} +1 -1
  15. package/dist/providers/modal/training-modal.addon.js +1 -1
  16. package/dist/providers/modal/training-modal.addon.mjs +1 -1
  17. package/dist/remoteEntry.js +1 -1
  18. package/dist/{responsive-BJqCg1mL.mjs → responsive-Dq7_CDVT.mjs} +1 -1
  19. package/dist/{scene-monitor-copy-CkZtRtGd.mjs → scene-monitor-copy-B6AKXb0r.mjs} +1 -1
  20. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-CWBMcDrQ.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-CLjAuQ-T.mjs} +1 -1
  21. package/package.json +1 -1
  22. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CV7yw1Ol.mjs +0 -26
@@ -15885,6 +15885,478 @@ object({
15885
15885
  path: ["expr"]
15886
15886
  });
15887
15887
  });
15888
+ /**
15889
+ * Identity envelope for a device's upstream-system metadata.
15890
+ *
15891
+ * Two jobs:
15892
+ *
15893
+ * 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
15894
+ * uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
15895
+ * WS-Discovery endpoint UUID, …). Provider code keeps a
15896
+ * `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
15897
+ * without round-tripping through `stableId` / `id` mappings.
15898
+ *
15899
+ * 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
15900
+ * one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
15901
+ * for vendors where MAC is the natural key). For systems where the
15902
+ * live dispatch key can be renamed (HA `entity_id` can be edited),
15903
+ * providers detect renames by matching `uniqueId` and patch `id`
15904
+ * in-place so dispatch keeps working.
15905
+ *
15906
+ * **Display unit and precision are NOT stored here.** They are a read-time
15907
+ * preference (D944). A polymorphic reading stores its `quantity` here once,
15908
+ * at adopt, and a date/time value stores `dateTimeShape` the same way —
15909
+ * neither is repeated on each sample. The `device_class` tag is an
15910
+ * HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
15911
+ * to derive the CamStack `DeviceRole`; it is never stored after that point.
15912
+ *
15913
+ * The `raw` escape hatch carries provider-specific attributes that don't
15914
+ * fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
15915
+ * details, …). Providers control what lands here.
15916
+ */
15917
+ var SourceInfoSchema = object({
15918
+ /** Live dispatch key — mutable when the source system allows rename. */
15919
+ id: string(),
15920
+ /** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
15921
+ system: string(),
15922
+ /** Immutable upstream identifier when available (HA `unique_id`, … ).
15923
+ * Used to detect rename when `id` changes. */
15924
+ uniqueId: string().optional(),
15925
+ /** Quantity of a polymorphic reading, written once at adopt (D944). */
15926
+ quantity: ReadingQuantitySchema.optional(),
15927
+ /** Date / time / datetime shape of a string reading, written once at adopt. */
15928
+ dateTimeShape: _enum([
15929
+ "date",
15930
+ "time",
15931
+ "datetime"
15932
+ ]).optional(),
15933
+ /** Provider-specific extras that don't fit the structured slots.
15934
+ * Whitelist what goes here per provider — do NOT dump entire HA
15935
+ * attribute blobs (would explode the meta JSON column). */
15936
+ raw: record(string(), unknown()).optional()
15937
+ });
15938
+ /**
15939
+ * Frozen unit → spec table. `•` in the doc marks each dimension's canonical
15940
+ * unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
15941
+ * `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
15942
+ * decimals). K derives from `°C = K − 273.15`.
15943
+ */
15944
+ var UNIT_TABLE = {
15945
+ "°C": {
15946
+ dimension: "temperature",
15947
+ factor: 1,
15948
+ offset: 0
15949
+ },
15950
+ "°F": {
15951
+ dimension: "temperature",
15952
+ factor: 5 / 9,
15953
+ offset: -160 / 9
15954
+ },
15955
+ K: {
15956
+ dimension: "temperature",
15957
+ factor: 1,
15958
+ offset: -273.15
15959
+ },
15960
+ hPa: {
15961
+ dimension: "pressure",
15962
+ factor: 1,
15963
+ offset: 0
15964
+ },
15965
+ kPa: {
15966
+ dimension: "pressure",
15967
+ factor: 10,
15968
+ offset: 0
15969
+ },
15970
+ Pa: {
15971
+ dimension: "pressure",
15972
+ factor: .01,
15973
+ offset: 0
15974
+ },
15975
+ mbar: {
15976
+ dimension: "pressure",
15977
+ factor: 1,
15978
+ offset: 0
15979
+ },
15980
+ bar: {
15981
+ dimension: "pressure",
15982
+ factor: 1e3,
15983
+ offset: 0
15984
+ },
15985
+ inHg: {
15986
+ dimension: "pressure",
15987
+ factor: 33.8639,
15988
+ offset: 0
15989
+ },
15990
+ mmHg: {
15991
+ dimension: "pressure",
15992
+ factor: 1.33322,
15993
+ offset: 0
15994
+ },
15995
+ psi: {
15996
+ dimension: "pressure",
15997
+ factor: 68.9476,
15998
+ offset: 0
15999
+ },
16000
+ "m/s": {
16001
+ dimension: "speed",
16002
+ factor: 1,
16003
+ offset: 0
16004
+ },
16005
+ "km/h": {
16006
+ dimension: "speed",
16007
+ factor: 1 / 3.6,
16008
+ offset: 0
16009
+ },
16010
+ mph: {
16011
+ dimension: "speed",
16012
+ factor: .44704,
16013
+ offset: 0
16014
+ },
16015
+ kn: {
16016
+ dimension: "speed",
16017
+ factor: .514444,
16018
+ offset: 0
16019
+ },
16020
+ "mm/h": {
16021
+ dimension: "precipitation-rate",
16022
+ factor: 1,
16023
+ offset: 0
16024
+ },
16025
+ "in/h": {
16026
+ dimension: "precipitation-rate",
16027
+ factor: 25.4,
16028
+ offset: 0
16029
+ },
16030
+ m: {
16031
+ dimension: "length",
16032
+ factor: 1,
16033
+ offset: 0
16034
+ },
16035
+ mm: {
16036
+ dimension: "length",
16037
+ factor: .001,
16038
+ offset: 0
16039
+ },
16040
+ cm: {
16041
+ dimension: "length",
16042
+ factor: .01,
16043
+ offset: 0
16044
+ },
16045
+ km: {
16046
+ dimension: "length",
16047
+ factor: 1e3,
16048
+ offset: 0
16049
+ },
16050
+ in: {
16051
+ dimension: "length",
16052
+ factor: .0254,
16053
+ offset: 0
16054
+ },
16055
+ ft: {
16056
+ dimension: "length",
16057
+ factor: .3048,
16058
+ offset: 0
16059
+ },
16060
+ mi: {
16061
+ dimension: "length",
16062
+ factor: 1609.344,
16063
+ offset: 0
16064
+ },
16065
+ "m²": {
16066
+ dimension: "area",
16067
+ factor: 1,
16068
+ offset: 0
16069
+ },
16070
+ lx: {
16071
+ dimension: "illuminance",
16072
+ factor: 1,
16073
+ offset: 0
16074
+ },
16075
+ "W/m²": {
16076
+ dimension: "irradiance",
16077
+ factor: 1,
16078
+ offset: 0
16079
+ },
16080
+ W: {
16081
+ dimension: "power",
16082
+ factor: 1,
16083
+ offset: 0
16084
+ },
16085
+ kW: {
16086
+ dimension: "power",
16087
+ factor: 1e3,
16088
+ offset: 0
16089
+ },
16090
+ VA: {
16091
+ dimension: "apparent-power",
16092
+ factor: 1,
16093
+ offset: 0
16094
+ },
16095
+ Wh: {
16096
+ dimension: "energy",
16097
+ factor: 1,
16098
+ offset: 0
16099
+ },
16100
+ kWh: {
16101
+ dimension: "energy",
16102
+ factor: 1e3,
16103
+ offset: 0
16104
+ },
16105
+ MWh: {
16106
+ dimension: "energy",
16107
+ factor: 1e6,
16108
+ offset: 0
16109
+ },
16110
+ V: {
16111
+ dimension: "voltage",
16112
+ factor: 1,
16113
+ offset: 0
16114
+ },
16115
+ mV: {
16116
+ dimension: "voltage",
16117
+ factor: .001,
16118
+ offset: 0
16119
+ },
16120
+ A: {
16121
+ dimension: "current",
16122
+ factor: 1,
16123
+ offset: 0
16124
+ },
16125
+ mA: {
16126
+ dimension: "current",
16127
+ factor: .001,
16128
+ offset: 0
16129
+ },
16130
+ ppm: {
16131
+ dimension: "concentration-volume",
16132
+ factor: 1,
16133
+ offset: 0
16134
+ },
16135
+ ppb: {
16136
+ dimension: "concentration-volume",
16137
+ factor: .001,
16138
+ offset: 0
16139
+ },
16140
+ "µg/m³": {
16141
+ dimension: "concentration-mass",
16142
+ factor: 1,
16143
+ offset: 0
16144
+ },
16145
+ "mg/m³": {
16146
+ dimension: "concentration-mass",
16147
+ factor: 1e3,
16148
+ offset: 0
16149
+ },
16150
+ kg: {
16151
+ dimension: "mass",
16152
+ factor: 1,
16153
+ offset: 0
16154
+ },
16155
+ g: {
16156
+ dimension: "mass",
16157
+ factor: .001,
16158
+ offset: 0
16159
+ },
16160
+ lb: {
16161
+ dimension: "mass",
16162
+ factor: .453592,
16163
+ offset: 0
16164
+ },
16165
+ oz: {
16166
+ dimension: "mass",
16167
+ factor: .0283495,
16168
+ offset: 0
16169
+ },
16170
+ "%": {
16171
+ dimension: "percentage",
16172
+ factor: 1,
16173
+ offset: 0
16174
+ },
16175
+ L: {
16176
+ dimension: "volume",
16177
+ factor: 1,
16178
+ offset: 0
16179
+ },
16180
+ mL: {
16181
+ dimension: "volume",
16182
+ factor: .001,
16183
+ offset: 0
16184
+ },
16185
+ gal: {
16186
+ dimension: "volume",
16187
+ factor: 3.785411784,
16188
+ offset: 0
16189
+ },
16190
+ s: {
16191
+ dimension: "duration",
16192
+ factor: 1,
16193
+ offset: 0
16194
+ },
16195
+ ms: {
16196
+ dimension: "duration",
16197
+ factor: .001,
16198
+ offset: 0
16199
+ },
16200
+ min: {
16201
+ dimension: "duration",
16202
+ factor: 60,
16203
+ offset: 0
16204
+ },
16205
+ h: {
16206
+ dimension: "duration",
16207
+ factor: 3600,
16208
+ offset: 0
16209
+ },
16210
+ d: {
16211
+ dimension: "duration",
16212
+ factor: 86400,
16213
+ offset: 0
16214
+ },
16215
+ B: {
16216
+ dimension: "information",
16217
+ factor: 1,
16218
+ offset: 0
16219
+ },
16220
+ KiB: {
16221
+ dimension: "information",
16222
+ factor: 1024,
16223
+ offset: 0
16224
+ },
16225
+ MiB: {
16226
+ dimension: "information",
16227
+ factor: 1024 ** 2,
16228
+ offset: 0
16229
+ },
16230
+ GiB: {
16231
+ dimension: "information",
16232
+ factor: 1024 ** 3,
16233
+ offset: 0
16234
+ },
16235
+ TiB: {
16236
+ dimension: "information",
16237
+ factor: 1024 ** 4,
16238
+ offset: 0
16239
+ },
16240
+ kB: {
16241
+ dimension: "information",
16242
+ factor: 1e3,
16243
+ offset: 0
16244
+ },
16245
+ MB: {
16246
+ dimension: "information",
16247
+ factor: 1e6,
16248
+ offset: 0
16249
+ },
16250
+ GB: {
16251
+ dimension: "information",
16252
+ factor: 1e9,
16253
+ offset: 0
16254
+ },
16255
+ "°": {
16256
+ dimension: "angle",
16257
+ factor: 1,
16258
+ offset: 0
16259
+ },
16260
+ dBFS: {
16261
+ dimension: "sound-level",
16262
+ factor: 1,
16263
+ offset: 0
16264
+ },
16265
+ dBm: {
16266
+ dimension: "signal-level",
16267
+ factor: 1,
16268
+ offset: 0
16269
+ },
16270
+ mired: {
16271
+ dimension: "colour-temperature",
16272
+ factor: 1,
16273
+ offset: 0
16274
+ },
16275
+ kbps: {
16276
+ dimension: "bitrate",
16277
+ factor: 1,
16278
+ offset: 0
16279
+ },
16280
+ Mbps: {
16281
+ dimension: "bitrate",
16282
+ factor: 1e3,
16283
+ offset: 0
16284
+ },
16285
+ fps: {
16286
+ dimension: "rate",
16287
+ factor: 1,
16288
+ offset: 0
16289
+ }
16290
+ };
16291
+ /** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
16292
+ function specFor(unit) {
16293
+ return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
16294
+ }
16295
+ /** Value in `spec`'s unit → its dimension's canonical unit. */
16296
+ function toCanonical(value, spec) {
16297
+ return value * spec.factor + spec.offset;
16298
+ }
16299
+ /** Canonical-unit value → the unit described by `spec`. */
16300
+ function fromCanonical(canonical, spec) {
16301
+ return (canonical - spec.offset) / spec.factor;
16302
+ }
16303
+ /**
16304
+ * Graceful variant for the render path: returns the converted value, or
16305
+ * `undefined` when the conversion is refused (unknown unit / cross-dimension).
16306
+ * Never throws — a render caller falls back to the raw value + source unit.
16307
+ */
16308
+ function tryConvertUnit(value, from, to) {
16309
+ if (from === to) return value;
16310
+ const fromSpec = specFor(from);
16311
+ if (!fromSpec) return void 0;
16312
+ const toSpec = specFor(to);
16313
+ if (!toSpec) return void 0;
16314
+ if (fromSpec.dimension !== toSpec.dimension) return void 0;
16315
+ return fromCanonical(toCanonical(value, fromSpec), toSpec);
16316
+ }
16317
+ /**
16318
+ * A number a person types for a physical quantity — the input side of the
16319
+ * value + unit contract (D972).
16320
+ *
16321
+ * Readings are stored in the base unit of their quantity (D944); a cap method
16322
+ * param is stored in the unit its input schema DECLARES (`paramMeta`). The
16323
+ * wire pair {@link QuantityValue} says "this number is expressed in this
16324
+ * unit"; {@link convertQuantityInput} brings it to the stored unit and refuses,
16325
+ * with a typed {@link QuantityUnitError}, a unit that cannot be that quantity.
16326
+ */
16327
+ /** A unit that cannot be applied to the number it was given with. */
16328
+ var QuantityUnitError = class extends Error {
16329
+ code;
16330
+ constructor(code, message) {
16331
+ super(`[${code}] ${message}`);
16332
+ this.name = "QuantityUnitError";
16333
+ this.code = code;
16334
+ }
16335
+ };
16336
+ /** The wire pair: `value` is expressed in `unit`. */
16337
+ var QuantityValueSchema = object({
16338
+ value: number(),
16339
+ unit: string().min(1)
16340
+ });
16341
+ /**
16342
+ * Zod `.meta()` bag for a cap METHOD param that is a physical quantity — the
16343
+ * input-side twin of `readingMeta`. The value is carried in `unit` (a gram
16344
+ * portion stays in grams); the unit must belong to the quantity, checked once
16345
+ * when the cap is declared.
16346
+ */
16347
+ function paramMeta(declared) {
16348
+ const base = baseUnitOf(declared.quantity);
16349
+ if (base === void 0) throw new QuantityUnitError("unknown-unit", `quantity "${declared.quantity}" has no unit`);
16350
+ if (tryConvertUnit(1, declared.unit, base) === void 0) throw new QuantityUnitError("cross-dimension", `"${declared.unit}" is not a unit of ${declared.quantity}`);
16351
+ return {
16352
+ quantity: declared.quantity,
16353
+ unit: declared.unit
16354
+ };
16355
+ }
16356
+ object({
16357
+ quantity: ReadingQuantitySchema,
16358
+ unit: string().min(1)
16359
+ });
15888
16360
  /** How a leaf compares a device field to a value. Derived from the field's
15889
16361
  * `kind` in `deviceManager.getWireableFields`, never hand-maintained. */
15890
16362
  var AutomationConditionOperatorSchema = _enum([
@@ -15907,8 +16379,10 @@ var AutomationConditionLeafSchema = object({
15907
16379
  string(),
15908
16380
  number(),
15909
16381
  boolean(),
15910
- array(union([string(), number()]))
15911
- ])
16382
+ array(union([string(), number()])),
16383
+ QuantityValueSchema
16384
+ ]),
16385
+ unit: string().min(1).optional()
15912
16386
  });
15913
16387
  var AutomationConditionStationaryPresentSchema = object({
15914
16388
  kind: literal("stationary-present"),
@@ -16061,7 +16535,13 @@ var AutomationCapStepSchema = object({
16061
16535
  /** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
16062
16536
  * SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
16063
16537
  * the expression leaf. */
16064
- args: record(string(), unknown()).optional()
16538
+ args: record(string(), unknown()).optional(),
16539
+ /**
16540
+ * The unit the person picked per arg (display only). `args` always hold the
16541
+ * value in the unit the method's input DECLARES (`paramMeta`); on a write an
16542
+ * arg may be a {@link QuantityValue}, which the save boundary converts.
16543
+ */
16544
+ argUnits: record(string(), string().min(1)).optional()
16065
16545
  });
16066
16546
  /**
16067
16547
  * The steps an internal Action may contain: cap and wait, and nothing that can
@@ -16441,6 +16921,16 @@ object({
16441
16921
  lastRunAt: number().nullable(),
16442
16922
  lastError: string().nullable()
16443
16923
  });
16924
+ /** A bare number accepted as a base unit — the save succeeded, say so. */
16925
+ var UnitWarningSchema = object({
16926
+ /** Where in the saved record, e.g. `conditions.children.0` or `steps.2.args.grams`. */
16927
+ path: string(),
16928
+ deviceId: number().int().optional(),
16929
+ field: string(),
16930
+ value: number(),
16931
+ assumedUnit: string(),
16932
+ message: string()
16933
+ });
16444
16934
  /**
16445
16935
  * notification-output — canonical, capability-gated notification delivery.
16446
16936
  *
@@ -21785,56 +22275,6 @@ var DeviceAdminLinkSchema = object({
21785
22275
  });
21786
22276
  method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema.nullable(), { auth: "admin" });
21787
22277
  /**
21788
- * Identity envelope for a device's upstream-system metadata.
21789
- *
21790
- * Two jobs:
21791
- *
21792
- * 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
21793
- * uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
21794
- * WS-Discovery endpoint UUID, …). Provider code keeps a
21795
- * `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
21796
- * without round-tripping through `stableId` / `id` mappings.
21797
- *
21798
- * 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
21799
- * one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
21800
- * for vendors where MAC is the natural key). For systems where the
21801
- * live dispatch key can be renamed (HA `entity_id` can be edited),
21802
- * providers detect renames by matching `uniqueId` and patch `id`
21803
- * in-place so dispatch keeps working.
21804
- *
21805
- * **Display unit and precision are NOT stored here.** They are a read-time
21806
- * preference (D944). A polymorphic reading stores its `quantity` here once,
21807
- * at adopt, and a date/time value stores `dateTimeShape` the same way —
21808
- * neither is repeated on each sample. The `device_class` tag is an
21809
- * HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
21810
- * to derive the CamStack `DeviceRole`; it is never stored after that point.
21811
- *
21812
- * The `raw` escape hatch carries provider-specific attributes that don't
21813
- * fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
21814
- * details, …). Providers control what lands here.
21815
- */
21816
- var SourceInfoSchema = object({
21817
- /** Live dispatch key — mutable when the source system allows rename. */
21818
- id: string(),
21819
- /** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
21820
- system: string(),
21821
- /** Immutable upstream identifier when available (HA `unique_id`, … ).
21822
- * Used to detect rename when `id` changes. */
21823
- uniqueId: string().optional(),
21824
- /** Quantity of a polymorphic reading, written once at adopt (D944). */
21825
- quantity: ReadingQuantitySchema.optional(),
21826
- /** Date / time / datetime shape of a string reading, written once at adopt. */
21827
- dateTimeShape: _enum([
21828
- "date",
21829
- "time",
21830
- "datetime"
21831
- ]).optional(),
21832
- /** Provider-specific extras that don't fit the structured slots.
21833
- * Whitelist what goes here per provider — do NOT dump entire HA
21834
- * attribute blobs (would explode the meta JSON column). */
21835
- raw: record(string(), unknown()).optional()
21836
- });
21837
- /**
21838
22278
  * device-discovery — device-scoped capability for parents that host /
21839
22279
  * enumerate child devices (Reolink Hub / NVR, ONVIF gateway, future
21840
22280
  * integrations). The parent advertises a list of discoverable children,
@@ -54581,11 +55021,13 @@ var ImageContractSchema = object({
54581
55021
  * The shell verdict (see {@link WrapperKindSchema}) with the proofs that
54582
55022
  * produced it.
54583
55023
  *
54584
- * There is deliberately NO `canSelfUpdate` and no apply action: a wrapper
54585
- * update is an ANNOUNCEMENT. The notification body carries the exact command
54586
- * for a `docker` shell and says the app restarts into the new build for
54587
- * `electron`, and that sentence is chosen from `kind` alone — a boolean
54588
- * nothing reads is the defect this repo keeps paying for.
55024
+ * There is deliberately NO `canSelfUpdate` boolean: a wrapper update is an
55025
+ * ANNOUNCEMENT. The notification body carries the exact command for a `docker`
55026
+ * shell and says the app restarts into the new build for `electron`, and that
55027
+ * sentence is chosen from `kind` alone — a boolean nothing reads is the defect
55028
+ * this repo keeps paying for. The one shell that CAN be acted on is the
55029
+ * Electron app, and only through `installDesktopUpdate` (see
55030
+ * {@link DesktopAppStatusSchema} for what the node reads from the app first).
54589
55031
  */
54590
55032
  var WrapperIdentitySchema = object({
54591
55033
  kind: _enum([
@@ -54633,6 +55075,49 @@ var ServerRollbackInfoSchema = object({
54633
55075
  reason: string()
54634
55076
  });
54635
55077
  /**
55078
+ * What the native desktop app (Electron) that hosts this node says about
55079
+ * itself, read from `<dataDir>/server-root/desktop-app-state.json` (ADR-0971).
55080
+ * Absent on the status = no desktop app, or it never wrote the file.
55081
+ *
55082
+ * `stale` is the honest answer to an app that stopped writing (closed, hung,
55083
+ * crashed): the update facts are then the LAST ones known, not current ones,
55084
+ * and a consumer must not read `update.available: false` from a stale record
55085
+ * as "no update". `stateAtMs` is when the app last wrote.
55086
+ */
55087
+ var DesktopAppStatusSchema = object({
55088
+ /** The Electron app's own version (not the node closure's). */
55089
+ version: string(),
55090
+ update: object({
55091
+ available: boolean(),
55092
+ /** The new build is downloaded and `installDesktopUpdate` can apply it. */
55093
+ downloaded: boolean(),
55094
+ version: string().nullable(),
55095
+ checking: boolean(),
55096
+ /** Why the app's last update check produced no answer; `null` when it did. */
55097
+ error: string().nullable()
55098
+ }),
55099
+ stateAtMs: number(),
55100
+ stale: boolean()
55101
+ });
55102
+ /**
55103
+ * Why `installDesktopUpdate` did nothing. Stable names a UI maps to a sentence:
55104
+ * - `not-electron` — this node does not run inside the desktop app.
55105
+ * - `no-app-state` — the app never published its state (or the file is unreadable).
55106
+ * - `app-state-stale` — the app stopped writing; it is probably not running.
55107
+ * - `not-downloaded` — no update is downloaded yet; nothing to install.
55108
+ */
55109
+ var InstallDesktopUpdateReasonSchema = _enum([
55110
+ "not-electron",
55111
+ "no-app-state",
55112
+ "app-state-stale",
55113
+ "not-downloaded"
55114
+ ]);
55115
+ var InstallDesktopUpdateResultSchema = object({
55116
+ accepted: boolean(),
55117
+ /** Non-null exactly when `accepted` is false. */
55118
+ reason: InstallDesktopUpdateReasonSchema.nullable()
55119
+ });
55120
+ /**
54636
55121
  * The runner boot check (D877): the runners this node PLANNED (hub: one per
54637
55122
  * `resolveRunnerId` over its forked addons; agent: the runners its process
54638
55123
  * service holds, because only the hub plans) against the states the process
@@ -54736,7 +55221,12 @@ var ServerPackageStatusSchema = object({
54736
55221
  * on a provider that predates it. Absent is "not checked yet", never "all
54737
55222
  * well": a consumer that needs the answer treats it as pending.
54738
55223
  */
54739
- runners: RunnerBootCheckSchema.optional()
55224
+ runners: RunnerBootCheckSchema.optional(),
55225
+ /**
55226
+ * The desktop app hosting this node (see {@link DesktopAppStatusSchema}).
55227
+ * Optional for version skew AND because most nodes have no desktop app.
55228
+ */
55229
+ desktopApp: DesktopAppStatusSchema.optional()
54740
55230
  });
54741
55231
  var ServerUpdateCheckResultSchema = object({
54742
55232
  packageName: string(),
@@ -54841,6 +55331,9 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
54841
55331
  kind: "mutation",
54842
55332
  auth: "admin",
54843
55333
  timeoutMs: 16 * 6e4
55334
+ }), method(_void(), InstallDesktopUpdateResultSchema, {
55335
+ kind: "mutation",
55336
+ auth: "admin"
54844
55337
  }), method(_void(), ServerUpdateActionResultSchema, {
54845
55338
  kind: "mutation",
54846
55339
  auth: "admin"
@@ -57788,13 +58281,19 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
57788
58281
  }), method(ActionIdInput, _void(), {
57789
58282
  kind: "mutation",
57790
58283
  auth: "admin"
57791
- }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
58284
+ }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
58285
+ action: ActionEntrySchema,
58286
+ warnings: array(UnitWarningSchema).optional()
58287
+ }), {
57792
58288
  kind: "mutation",
57793
58289
  auth: "admin"
57794
58290
  }), method(object({
57795
58291
  actionId: string().min(1),
57796
58292
  action: ActionInputSchema.partial()
57797
- }), object({ action: ActionEntrySchema }), {
58293
+ }), object({
58294
+ action: ActionEntrySchema,
58295
+ warnings: array(UnitWarningSchema).optional()
58296
+ }), {
57798
58297
  kind: "mutation",
57799
58298
  auth: "admin"
57800
58299
  }), method(ActionIdInput, _void(), {
@@ -62441,6 +62940,14 @@ var PetFeederDeviceStatusSchema = _enum([
62441
62940
  "on_batteries"
62442
62941
  ]);
62443
62942
  var gramsPortion = number().int().min(4).max(200);
62943
+ /** A portion REQUESTED of the feeder is a mass the method takes in GRAMS (the
62944
+ * hardware's own unit). The bounds are grams; a caller entering another unit
62945
+ * converts to grams first (`paramMeta`, D972). The STATUS fields above stay
62946
+ * plain grams — they are not readings in the kilogram base. */
62947
+ var gramsParam = gramsPortion.meta(paramMeta({
62948
+ quantity: "mass",
62949
+ unit: "g"
62950
+ }));
62444
62951
  object({
62445
62952
  /** Food in the TANK (hopper), as the feeder's own sensor reports it
62446
62953
  * (`state.food`). A coarse level code, not grams — `0` is empty. The
@@ -62515,9 +63022,9 @@ object({
62515
63022
  });
62516
63023
  DeviceType.PetFeeder, method(object({
62517
63024
  deviceId: number().int().nonnegative(),
62518
- grams: gramsPortion.optional(),
62519
- hopper1: gramsPortion.optional(),
62520
- hopper2: gramsPortion.optional()
63025
+ grams: gramsParam.optional(),
63026
+ hopper1: gramsParam.optional(),
63027
+ hopper2: gramsParam.optional()
62521
63028
  }), _void(), {
62522
63029
  kind: "mutation",
62523
63030
  auth: "protected"
@@ -75301,6 +75808,13 @@ Object.freeze({
75301
75808
  access: "view",
75302
75809
  role: "admin"
75303
75810
  },
75811
+ "serverManagement.installDesktopUpdate": {
75812
+ capName: "server-management",
75813
+ capScope: "system",
75814
+ addonId: null,
75815
+ access: "create",
75816
+ role: "admin"
75817
+ },
75304
75818
  "serverManagement.restartServer": {
75305
75819
  capName: "server-management",
75306
75820
  capScope: "system",
@@ -79211,7 +79725,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79211
79725
  min: 4,
79212
79726
  max: 200,
79213
79727
  step: 1,
79214
- unit: "g"
79728
+ unit: "g",
79729
+ quantity: "mass"
79215
79730
  },
79216
79731
  optional: true
79217
79732
  }]
@@ -79230,7 +79745,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79230
79745
  min: 4,
79231
79746
  max: 200,
79232
79747
  step: 1,
79233
- unit: "g"
79748
+ unit: "g",
79749
+ quantity: "mass"
79234
79750
  },
79235
79751
  optional: true
79236
79752
  }, {
@@ -79241,7 +79757,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79241
79757
  min: 4,
79242
79758
  max: 200,
79243
79759
  step: 1,
79244
- unit: "g"
79760
+ unit: "g",
79761
+ quantity: "mass"
79245
79762
  },
79246
79763
  optional: true
79247
79764
  }]