@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
@@ -15852,6 +15852,478 @@ object({
15852
15852
  path: ["expr"]
15853
15853
  });
15854
15854
  });
15855
+ /**
15856
+ * Identity envelope for a device's upstream-system metadata.
15857
+ *
15858
+ * Two jobs:
15859
+ *
15860
+ * 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
15861
+ * uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
15862
+ * WS-Discovery endpoint UUID, …). Provider code keeps a
15863
+ * `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
15864
+ * without round-tripping through `stableId` / `id` mappings.
15865
+ *
15866
+ * 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
15867
+ * one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
15868
+ * for vendors where MAC is the natural key). For systems where the
15869
+ * live dispatch key can be renamed (HA `entity_id` can be edited),
15870
+ * providers detect renames by matching `uniqueId` and patch `id`
15871
+ * in-place so dispatch keeps working.
15872
+ *
15873
+ * **Display unit and precision are NOT stored here.** They are a read-time
15874
+ * preference (D944). A polymorphic reading stores its `quantity` here once,
15875
+ * at adopt, and a date/time value stores `dateTimeShape` the same way —
15876
+ * neither is repeated on each sample. The `device_class` tag is an
15877
+ * HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
15878
+ * to derive the CamStack `DeviceRole`; it is never stored after that point.
15879
+ *
15880
+ * The `raw` escape hatch carries provider-specific attributes that don't
15881
+ * fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
15882
+ * details, …). Providers control what lands here.
15883
+ */
15884
+ var SourceInfoSchema = object({
15885
+ /** Live dispatch key — mutable when the source system allows rename. */
15886
+ id: string(),
15887
+ /** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
15888
+ system: string(),
15889
+ /** Immutable upstream identifier when available (HA `unique_id`, … ).
15890
+ * Used to detect rename when `id` changes. */
15891
+ uniqueId: string().optional(),
15892
+ /** Quantity of a polymorphic reading, written once at adopt (D944). */
15893
+ quantity: ReadingQuantitySchema.optional(),
15894
+ /** Date / time / datetime shape of a string reading, written once at adopt. */
15895
+ dateTimeShape: _enum([
15896
+ "date",
15897
+ "time",
15898
+ "datetime"
15899
+ ]).optional(),
15900
+ /** Provider-specific extras that don't fit the structured slots.
15901
+ * Whitelist what goes here per provider — do NOT dump entire HA
15902
+ * attribute blobs (would explode the meta JSON column). */
15903
+ raw: record(string(), unknown()).optional()
15904
+ });
15905
+ /**
15906
+ * Frozen unit → spec table. `•` in the doc marks each dimension's canonical
15907
+ * unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
15908
+ * `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
15909
+ * decimals). K derives from `°C = K − 273.15`.
15910
+ */
15911
+ var UNIT_TABLE = {
15912
+ "°C": {
15913
+ dimension: "temperature",
15914
+ factor: 1,
15915
+ offset: 0
15916
+ },
15917
+ "°F": {
15918
+ dimension: "temperature",
15919
+ factor: 5 / 9,
15920
+ offset: -160 / 9
15921
+ },
15922
+ K: {
15923
+ dimension: "temperature",
15924
+ factor: 1,
15925
+ offset: -273.15
15926
+ },
15927
+ hPa: {
15928
+ dimension: "pressure",
15929
+ factor: 1,
15930
+ offset: 0
15931
+ },
15932
+ kPa: {
15933
+ dimension: "pressure",
15934
+ factor: 10,
15935
+ offset: 0
15936
+ },
15937
+ Pa: {
15938
+ dimension: "pressure",
15939
+ factor: .01,
15940
+ offset: 0
15941
+ },
15942
+ mbar: {
15943
+ dimension: "pressure",
15944
+ factor: 1,
15945
+ offset: 0
15946
+ },
15947
+ bar: {
15948
+ dimension: "pressure",
15949
+ factor: 1e3,
15950
+ offset: 0
15951
+ },
15952
+ inHg: {
15953
+ dimension: "pressure",
15954
+ factor: 33.8639,
15955
+ offset: 0
15956
+ },
15957
+ mmHg: {
15958
+ dimension: "pressure",
15959
+ factor: 1.33322,
15960
+ offset: 0
15961
+ },
15962
+ psi: {
15963
+ dimension: "pressure",
15964
+ factor: 68.9476,
15965
+ offset: 0
15966
+ },
15967
+ "m/s": {
15968
+ dimension: "speed",
15969
+ factor: 1,
15970
+ offset: 0
15971
+ },
15972
+ "km/h": {
15973
+ dimension: "speed",
15974
+ factor: 1 / 3.6,
15975
+ offset: 0
15976
+ },
15977
+ mph: {
15978
+ dimension: "speed",
15979
+ factor: .44704,
15980
+ offset: 0
15981
+ },
15982
+ kn: {
15983
+ dimension: "speed",
15984
+ factor: .514444,
15985
+ offset: 0
15986
+ },
15987
+ "mm/h": {
15988
+ dimension: "precipitation-rate",
15989
+ factor: 1,
15990
+ offset: 0
15991
+ },
15992
+ "in/h": {
15993
+ dimension: "precipitation-rate",
15994
+ factor: 25.4,
15995
+ offset: 0
15996
+ },
15997
+ m: {
15998
+ dimension: "length",
15999
+ factor: 1,
16000
+ offset: 0
16001
+ },
16002
+ mm: {
16003
+ dimension: "length",
16004
+ factor: .001,
16005
+ offset: 0
16006
+ },
16007
+ cm: {
16008
+ dimension: "length",
16009
+ factor: .01,
16010
+ offset: 0
16011
+ },
16012
+ km: {
16013
+ dimension: "length",
16014
+ factor: 1e3,
16015
+ offset: 0
16016
+ },
16017
+ in: {
16018
+ dimension: "length",
16019
+ factor: .0254,
16020
+ offset: 0
16021
+ },
16022
+ ft: {
16023
+ dimension: "length",
16024
+ factor: .3048,
16025
+ offset: 0
16026
+ },
16027
+ mi: {
16028
+ dimension: "length",
16029
+ factor: 1609.344,
16030
+ offset: 0
16031
+ },
16032
+ "m²": {
16033
+ dimension: "area",
16034
+ factor: 1,
16035
+ offset: 0
16036
+ },
16037
+ lx: {
16038
+ dimension: "illuminance",
16039
+ factor: 1,
16040
+ offset: 0
16041
+ },
16042
+ "W/m²": {
16043
+ dimension: "irradiance",
16044
+ factor: 1,
16045
+ offset: 0
16046
+ },
16047
+ W: {
16048
+ dimension: "power",
16049
+ factor: 1,
16050
+ offset: 0
16051
+ },
16052
+ kW: {
16053
+ dimension: "power",
16054
+ factor: 1e3,
16055
+ offset: 0
16056
+ },
16057
+ VA: {
16058
+ dimension: "apparent-power",
16059
+ factor: 1,
16060
+ offset: 0
16061
+ },
16062
+ Wh: {
16063
+ dimension: "energy",
16064
+ factor: 1,
16065
+ offset: 0
16066
+ },
16067
+ kWh: {
16068
+ dimension: "energy",
16069
+ factor: 1e3,
16070
+ offset: 0
16071
+ },
16072
+ MWh: {
16073
+ dimension: "energy",
16074
+ factor: 1e6,
16075
+ offset: 0
16076
+ },
16077
+ V: {
16078
+ dimension: "voltage",
16079
+ factor: 1,
16080
+ offset: 0
16081
+ },
16082
+ mV: {
16083
+ dimension: "voltage",
16084
+ factor: .001,
16085
+ offset: 0
16086
+ },
16087
+ A: {
16088
+ dimension: "current",
16089
+ factor: 1,
16090
+ offset: 0
16091
+ },
16092
+ mA: {
16093
+ dimension: "current",
16094
+ factor: .001,
16095
+ offset: 0
16096
+ },
16097
+ ppm: {
16098
+ dimension: "concentration-volume",
16099
+ factor: 1,
16100
+ offset: 0
16101
+ },
16102
+ ppb: {
16103
+ dimension: "concentration-volume",
16104
+ factor: .001,
16105
+ offset: 0
16106
+ },
16107
+ "µg/m³": {
16108
+ dimension: "concentration-mass",
16109
+ factor: 1,
16110
+ offset: 0
16111
+ },
16112
+ "mg/m³": {
16113
+ dimension: "concentration-mass",
16114
+ factor: 1e3,
16115
+ offset: 0
16116
+ },
16117
+ kg: {
16118
+ dimension: "mass",
16119
+ factor: 1,
16120
+ offset: 0
16121
+ },
16122
+ g: {
16123
+ dimension: "mass",
16124
+ factor: .001,
16125
+ offset: 0
16126
+ },
16127
+ lb: {
16128
+ dimension: "mass",
16129
+ factor: .453592,
16130
+ offset: 0
16131
+ },
16132
+ oz: {
16133
+ dimension: "mass",
16134
+ factor: .0283495,
16135
+ offset: 0
16136
+ },
16137
+ "%": {
16138
+ dimension: "percentage",
16139
+ factor: 1,
16140
+ offset: 0
16141
+ },
16142
+ L: {
16143
+ dimension: "volume",
16144
+ factor: 1,
16145
+ offset: 0
16146
+ },
16147
+ mL: {
16148
+ dimension: "volume",
16149
+ factor: .001,
16150
+ offset: 0
16151
+ },
16152
+ gal: {
16153
+ dimension: "volume",
16154
+ factor: 3.785411784,
16155
+ offset: 0
16156
+ },
16157
+ s: {
16158
+ dimension: "duration",
16159
+ factor: 1,
16160
+ offset: 0
16161
+ },
16162
+ ms: {
16163
+ dimension: "duration",
16164
+ factor: .001,
16165
+ offset: 0
16166
+ },
16167
+ min: {
16168
+ dimension: "duration",
16169
+ factor: 60,
16170
+ offset: 0
16171
+ },
16172
+ h: {
16173
+ dimension: "duration",
16174
+ factor: 3600,
16175
+ offset: 0
16176
+ },
16177
+ d: {
16178
+ dimension: "duration",
16179
+ factor: 86400,
16180
+ offset: 0
16181
+ },
16182
+ B: {
16183
+ dimension: "information",
16184
+ factor: 1,
16185
+ offset: 0
16186
+ },
16187
+ KiB: {
16188
+ dimension: "information",
16189
+ factor: 1024,
16190
+ offset: 0
16191
+ },
16192
+ MiB: {
16193
+ dimension: "information",
16194
+ factor: 1024 ** 2,
16195
+ offset: 0
16196
+ },
16197
+ GiB: {
16198
+ dimension: "information",
16199
+ factor: 1024 ** 3,
16200
+ offset: 0
16201
+ },
16202
+ TiB: {
16203
+ dimension: "information",
16204
+ factor: 1024 ** 4,
16205
+ offset: 0
16206
+ },
16207
+ kB: {
16208
+ dimension: "information",
16209
+ factor: 1e3,
16210
+ offset: 0
16211
+ },
16212
+ MB: {
16213
+ dimension: "information",
16214
+ factor: 1e6,
16215
+ offset: 0
16216
+ },
16217
+ GB: {
16218
+ dimension: "information",
16219
+ factor: 1e9,
16220
+ offset: 0
16221
+ },
16222
+ "°": {
16223
+ dimension: "angle",
16224
+ factor: 1,
16225
+ offset: 0
16226
+ },
16227
+ dBFS: {
16228
+ dimension: "sound-level",
16229
+ factor: 1,
16230
+ offset: 0
16231
+ },
16232
+ dBm: {
16233
+ dimension: "signal-level",
16234
+ factor: 1,
16235
+ offset: 0
16236
+ },
16237
+ mired: {
16238
+ dimension: "colour-temperature",
16239
+ factor: 1,
16240
+ offset: 0
16241
+ },
16242
+ kbps: {
16243
+ dimension: "bitrate",
16244
+ factor: 1,
16245
+ offset: 0
16246
+ },
16247
+ Mbps: {
16248
+ dimension: "bitrate",
16249
+ factor: 1e3,
16250
+ offset: 0
16251
+ },
16252
+ fps: {
16253
+ dimension: "rate",
16254
+ factor: 1,
16255
+ offset: 0
16256
+ }
16257
+ };
16258
+ /** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
16259
+ function specFor(unit) {
16260
+ return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
16261
+ }
16262
+ /** Value in `spec`'s unit → its dimension's canonical unit. */
16263
+ function toCanonical(value, spec) {
16264
+ return value * spec.factor + spec.offset;
16265
+ }
16266
+ /** Canonical-unit value → the unit described by `spec`. */
16267
+ function fromCanonical(canonical, spec) {
16268
+ return (canonical - spec.offset) / spec.factor;
16269
+ }
16270
+ /**
16271
+ * Graceful variant for the render path: returns the converted value, or
16272
+ * `undefined` when the conversion is refused (unknown unit / cross-dimension).
16273
+ * Never throws — a render caller falls back to the raw value + source unit.
16274
+ */
16275
+ function tryConvertUnit(value, from, to) {
16276
+ if (from === to) return value;
16277
+ const fromSpec = specFor(from);
16278
+ if (!fromSpec) return void 0;
16279
+ const toSpec = specFor(to);
16280
+ if (!toSpec) return void 0;
16281
+ if (fromSpec.dimension !== toSpec.dimension) return void 0;
16282
+ return fromCanonical(toCanonical(value, fromSpec), toSpec);
16283
+ }
16284
+ /**
16285
+ * A number a person types for a physical quantity — the input side of the
16286
+ * value + unit contract (D972).
16287
+ *
16288
+ * Readings are stored in the base unit of their quantity (D944); a cap method
16289
+ * param is stored in the unit its input schema DECLARES (`paramMeta`). The
16290
+ * wire pair {@link QuantityValue} says "this number is expressed in this
16291
+ * unit"; {@link convertQuantityInput} brings it to the stored unit and refuses,
16292
+ * with a typed {@link QuantityUnitError}, a unit that cannot be that quantity.
16293
+ */
16294
+ /** A unit that cannot be applied to the number it was given with. */
16295
+ var QuantityUnitError = class extends Error {
16296
+ code;
16297
+ constructor(code, message) {
16298
+ super(`[${code}] ${message}`);
16299
+ this.name = "QuantityUnitError";
16300
+ this.code = code;
16301
+ }
16302
+ };
16303
+ /** The wire pair: `value` is expressed in `unit`. */
16304
+ var QuantityValueSchema = object({
16305
+ value: number(),
16306
+ unit: string().min(1)
16307
+ });
16308
+ /**
16309
+ * Zod `.meta()` bag for a cap METHOD param that is a physical quantity — the
16310
+ * input-side twin of `readingMeta`. The value is carried in `unit` (a gram
16311
+ * portion stays in grams); the unit must belong to the quantity, checked once
16312
+ * when the cap is declared.
16313
+ */
16314
+ function paramMeta(declared) {
16315
+ const base = baseUnitOf(declared.quantity);
16316
+ if (base === void 0) throw new QuantityUnitError("unknown-unit", `quantity "${declared.quantity}" has no unit`);
16317
+ if (tryConvertUnit(1, declared.unit, base) === void 0) throw new QuantityUnitError("cross-dimension", `"${declared.unit}" is not a unit of ${declared.quantity}`);
16318
+ return {
16319
+ quantity: declared.quantity,
16320
+ unit: declared.unit
16321
+ };
16322
+ }
16323
+ object({
16324
+ quantity: ReadingQuantitySchema,
16325
+ unit: string().min(1)
16326
+ });
15855
16327
  /** How a leaf compares a device field to a value. Derived from the field's
15856
16328
  * `kind` in `deviceManager.getWireableFields`, never hand-maintained. */
15857
16329
  var AutomationConditionOperatorSchema = _enum([
@@ -15874,8 +16346,10 @@ var AutomationConditionLeafSchema = object({
15874
16346
  string(),
15875
16347
  number(),
15876
16348
  boolean(),
15877
- array(union([string(), number()]))
15878
- ])
16349
+ array(union([string(), number()])),
16350
+ QuantityValueSchema
16351
+ ]),
16352
+ unit: string().min(1).optional()
15879
16353
  });
15880
16354
  var AutomationConditionStationaryPresentSchema = object({
15881
16355
  kind: literal("stationary-present"),
@@ -16028,7 +16502,13 @@ var AutomationCapStepSchema = object({
16028
16502
  /** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
16029
16503
  * SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
16030
16504
  * the expression leaf. */
16031
- args: record(string(), unknown()).optional()
16505
+ args: record(string(), unknown()).optional(),
16506
+ /**
16507
+ * The unit the person picked per arg (display only). `args` always hold the
16508
+ * value in the unit the method's input DECLARES (`paramMeta`); on a write an
16509
+ * arg may be a {@link QuantityValue}, which the save boundary converts.
16510
+ */
16511
+ argUnits: record(string(), string().min(1)).optional()
16032
16512
  });
16033
16513
  /**
16034
16514
  * The steps an internal Action may contain: cap and wait, and nothing that can
@@ -16408,6 +16888,16 @@ object({
16408
16888
  lastRunAt: number().nullable(),
16409
16889
  lastError: string().nullable()
16410
16890
  });
16891
+ /** A bare number accepted as a base unit — the save succeeded, say so. */
16892
+ var UnitWarningSchema = object({
16893
+ /** Where in the saved record, e.g. `conditions.children.0` or `steps.2.args.grams`. */
16894
+ path: string(),
16895
+ deviceId: number().int().optional(),
16896
+ field: string(),
16897
+ value: number(),
16898
+ assumedUnit: string(),
16899
+ message: string()
16900
+ });
16411
16901
  /**
16412
16902
  * notification-output — canonical, capability-gated notification delivery.
16413
16903
  *
@@ -21752,56 +22242,6 @@ var DeviceAdminLinkSchema = object({
21752
22242
  });
21753
22243
  method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema.nullable(), { auth: "admin" });
21754
22244
  /**
21755
- * Identity envelope for a device's upstream-system metadata.
21756
- *
21757
- * Two jobs:
21758
- *
21759
- * 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
21760
- * uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
21761
- * WS-Discovery endpoint UUID, …). Provider code keeps a
21762
- * `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
21763
- * without round-tripping through `stableId` / `id` mappings.
21764
- *
21765
- * 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
21766
- * one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
21767
- * for vendors where MAC is the natural key). For systems where the
21768
- * live dispatch key can be renamed (HA `entity_id` can be edited),
21769
- * providers detect renames by matching `uniqueId` and patch `id`
21770
- * in-place so dispatch keeps working.
21771
- *
21772
- * **Display unit and precision are NOT stored here.** They are a read-time
21773
- * preference (D944). A polymorphic reading stores its `quantity` here once,
21774
- * at adopt, and a date/time value stores `dateTimeShape` the same way —
21775
- * neither is repeated on each sample. The `device_class` tag is an
21776
- * HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
21777
- * to derive the CamStack `DeviceRole`; it is never stored after that point.
21778
- *
21779
- * The `raw` escape hatch carries provider-specific attributes that don't
21780
- * fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
21781
- * details, …). Providers control what lands here.
21782
- */
21783
- var SourceInfoSchema = object({
21784
- /** Live dispatch key — mutable when the source system allows rename. */
21785
- id: string(),
21786
- /** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
21787
- system: string(),
21788
- /** Immutable upstream identifier when available (HA `unique_id`, … ).
21789
- * Used to detect rename when `id` changes. */
21790
- uniqueId: string().optional(),
21791
- /** Quantity of a polymorphic reading, written once at adopt (D944). */
21792
- quantity: ReadingQuantitySchema.optional(),
21793
- /** Date / time / datetime shape of a string reading, written once at adopt. */
21794
- dateTimeShape: _enum([
21795
- "date",
21796
- "time",
21797
- "datetime"
21798
- ]).optional(),
21799
- /** Provider-specific extras that don't fit the structured slots.
21800
- * Whitelist what goes here per provider — do NOT dump entire HA
21801
- * attribute blobs (would explode the meta JSON column). */
21802
- raw: record(string(), unknown()).optional()
21803
- });
21804
- /**
21805
22245
  * device-discovery — device-scoped capability for parents that host /
21806
22246
  * enumerate child devices (Reolink Hub / NVR, ONVIF gateway, future
21807
22247
  * integrations). The parent advertises a list of discoverable children,
@@ -54548,11 +54988,13 @@ var ImageContractSchema = object({
54548
54988
  * The shell verdict (see {@link WrapperKindSchema}) with the proofs that
54549
54989
  * produced it.
54550
54990
  *
54551
- * There is deliberately NO `canSelfUpdate` and no apply action: a wrapper
54552
- * update is an ANNOUNCEMENT. The notification body carries the exact command
54553
- * for a `docker` shell and says the app restarts into the new build for
54554
- * `electron`, and that sentence is chosen from `kind` alone — a boolean
54555
- * nothing reads is the defect this repo keeps paying for.
54991
+ * There is deliberately NO `canSelfUpdate` boolean: a wrapper update is an
54992
+ * ANNOUNCEMENT. The notification body carries the exact command for a `docker`
54993
+ * shell and says the app restarts into the new build for `electron`, and that
54994
+ * sentence is chosen from `kind` alone — a boolean nothing reads is the defect
54995
+ * this repo keeps paying for. The one shell that CAN be acted on is the
54996
+ * Electron app, and only through `installDesktopUpdate` (see
54997
+ * {@link DesktopAppStatusSchema} for what the node reads from the app first).
54556
54998
  */
54557
54999
  var WrapperIdentitySchema = object({
54558
55000
  kind: _enum([
@@ -54600,6 +55042,49 @@ var ServerRollbackInfoSchema = object({
54600
55042
  reason: string()
54601
55043
  });
54602
55044
  /**
55045
+ * What the native desktop app (Electron) that hosts this node says about
55046
+ * itself, read from `<dataDir>/server-root/desktop-app-state.json` (ADR-0971).
55047
+ * Absent on the status = no desktop app, or it never wrote the file.
55048
+ *
55049
+ * `stale` is the honest answer to an app that stopped writing (closed, hung,
55050
+ * crashed): the update facts are then the LAST ones known, not current ones,
55051
+ * and a consumer must not read `update.available: false` from a stale record
55052
+ * as "no update". `stateAtMs` is when the app last wrote.
55053
+ */
55054
+ var DesktopAppStatusSchema = object({
55055
+ /** The Electron app's own version (not the node closure's). */
55056
+ version: string(),
55057
+ update: object({
55058
+ available: boolean(),
55059
+ /** The new build is downloaded and `installDesktopUpdate` can apply it. */
55060
+ downloaded: boolean(),
55061
+ version: string().nullable(),
55062
+ checking: boolean(),
55063
+ /** Why the app's last update check produced no answer; `null` when it did. */
55064
+ error: string().nullable()
55065
+ }),
55066
+ stateAtMs: number(),
55067
+ stale: boolean()
55068
+ });
55069
+ /**
55070
+ * Why `installDesktopUpdate` did nothing. Stable names a UI maps to a sentence:
55071
+ * - `not-electron` — this node does not run inside the desktop app.
55072
+ * - `no-app-state` — the app never published its state (or the file is unreadable).
55073
+ * - `app-state-stale` — the app stopped writing; it is probably not running.
55074
+ * - `not-downloaded` — no update is downloaded yet; nothing to install.
55075
+ */
55076
+ var InstallDesktopUpdateReasonSchema = _enum([
55077
+ "not-electron",
55078
+ "no-app-state",
55079
+ "app-state-stale",
55080
+ "not-downloaded"
55081
+ ]);
55082
+ var InstallDesktopUpdateResultSchema = object({
55083
+ accepted: boolean(),
55084
+ /** Non-null exactly when `accepted` is false. */
55085
+ reason: InstallDesktopUpdateReasonSchema.nullable()
55086
+ });
55087
+ /**
54603
55088
  * The runner boot check (D877): the runners this node PLANNED (hub: one per
54604
55089
  * `resolveRunnerId` over its forked addons; agent: the runners its process
54605
55090
  * service holds, because only the hub plans) against the states the process
@@ -54703,7 +55188,12 @@ var ServerPackageStatusSchema = object({
54703
55188
  * on a provider that predates it. Absent is "not checked yet", never "all
54704
55189
  * well": a consumer that needs the answer treats it as pending.
54705
55190
  */
54706
- runners: RunnerBootCheckSchema.optional()
55191
+ runners: RunnerBootCheckSchema.optional(),
55192
+ /**
55193
+ * The desktop app hosting this node (see {@link DesktopAppStatusSchema}).
55194
+ * Optional for version skew AND because most nodes have no desktop app.
55195
+ */
55196
+ desktopApp: DesktopAppStatusSchema.optional()
54707
55197
  });
54708
55198
  var ServerUpdateCheckResultSchema = object({
54709
55199
  packageName: string(),
@@ -54808,6 +55298,9 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
54808
55298
  kind: "mutation",
54809
55299
  auth: "admin",
54810
55300
  timeoutMs: 16 * 6e4
55301
+ }), method(_void(), InstallDesktopUpdateResultSchema, {
55302
+ kind: "mutation",
55303
+ auth: "admin"
54811
55304
  }), method(_void(), ServerUpdateActionResultSchema, {
54812
55305
  kind: "mutation",
54813
55306
  auth: "admin"
@@ -57755,13 +58248,19 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
57755
58248
  }), method(ActionIdInput, _void(), {
57756
58249
  kind: "mutation",
57757
58250
  auth: "admin"
57758
- }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
58251
+ }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
58252
+ action: ActionEntrySchema,
58253
+ warnings: array(UnitWarningSchema).optional()
58254
+ }), {
57759
58255
  kind: "mutation",
57760
58256
  auth: "admin"
57761
58257
  }), method(object({
57762
58258
  actionId: string().min(1),
57763
58259
  action: ActionInputSchema.partial()
57764
- }), object({ action: ActionEntrySchema }), {
58260
+ }), object({
58261
+ action: ActionEntrySchema,
58262
+ warnings: array(UnitWarningSchema).optional()
58263
+ }), {
57765
58264
  kind: "mutation",
57766
58265
  auth: "admin"
57767
58266
  }), method(ActionIdInput, _void(), {
@@ -62408,6 +62907,14 @@ var PetFeederDeviceStatusSchema = _enum([
62408
62907
  "on_batteries"
62409
62908
  ]);
62410
62909
  var gramsPortion = number().int().min(4).max(200);
62910
+ /** A portion REQUESTED of the feeder is a mass the method takes in GRAMS (the
62911
+ * hardware's own unit). The bounds are grams; a caller entering another unit
62912
+ * converts to grams first (`paramMeta`, D972). The STATUS fields above stay
62913
+ * plain grams — they are not readings in the kilogram base. */
62914
+ var gramsParam = gramsPortion.meta(paramMeta({
62915
+ quantity: "mass",
62916
+ unit: "g"
62917
+ }));
62411
62918
  object({
62412
62919
  /** Food in the TANK (hopper), as the feeder's own sensor reports it
62413
62920
  * (`state.food`). A coarse level code, not grams — `0` is empty. The
@@ -62482,9 +62989,9 @@ object({
62482
62989
  });
62483
62990
  DeviceType.PetFeeder, method(object({
62484
62991
  deviceId: number().int().nonnegative(),
62485
- grams: gramsPortion.optional(),
62486
- hopper1: gramsPortion.optional(),
62487
- hopper2: gramsPortion.optional()
62992
+ grams: gramsParam.optional(),
62993
+ hopper1: gramsParam.optional(),
62994
+ hopper2: gramsParam.optional()
62488
62995
  }), _void(), {
62489
62996
  kind: "mutation",
62490
62997
  auth: "protected"
@@ -75268,6 +75775,13 @@ Object.freeze({
75268
75775
  access: "view",
75269
75776
  role: "admin"
75270
75777
  },
75778
+ "serverManagement.installDesktopUpdate": {
75779
+ capName: "server-management",
75780
+ capScope: "system",
75781
+ addonId: null,
75782
+ access: "create",
75783
+ role: "admin"
75784
+ },
75271
75785
  "serverManagement.restartServer": {
75272
75786
  capName: "server-management",
75273
75787
  capScope: "system",
@@ -79178,7 +79692,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79178
79692
  min: 4,
79179
79693
  max: 200,
79180
79694
  step: 1,
79181
- unit: "g"
79695
+ unit: "g",
79696
+ quantity: "mass"
79182
79697
  },
79183
79698
  optional: true
79184
79699
  }]
@@ -79197,7 +79712,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79197
79712
  min: 4,
79198
79713
  max: 200,
79199
79714
  step: 1,
79200
- unit: "g"
79715
+ unit: "g",
79716
+ quantity: "mass"
79201
79717
  },
79202
79718
  optional: true
79203
79719
  }, {
@@ -79208,7 +79724,8 @@ var APPLIANCE_CAP_VOCABULARY = {
79208
79724
  min: 4,
79209
79725
  max: 200,
79210
79726
  step: 1,
79211
- unit: "g"
79727
+ unit: "g",
79728
+ quantity: "mass"
79212
79729
  },
79213
79730
  optional: true
79214
79731
  }]