@camstack/types 1.2.445 → 1.2.447

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/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.447] - 2026-10-29
11
+
12
+ ### Changed
13
+
14
+ - Numbers tied to a physical quantity can be entered in a unit you pick: automation conditions and steps accept { value, unit }, converted to the stored unit, and a bare API number is accepted with a warning
15
+
16
+ ## [1.2.446] - 2026-10-29
17
+
18
+ ### Changed
19
+
20
+ - The server-management capability reports the desktop app's version and update state and can ask it to install a downloaded update.
21
+
10
22
  ## [1.2.445] - 2026-10-29
11
23
 
12
24
  ### Added
@@ -92,6 +92,7 @@ export declare const ActionEntrySchema: z.ZodObject<{
92
92
  cap: z.ZodString;
93
93
  method: z.ZodString;
94
94
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
95
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
95
96
  }, z.core.$strip>], "kind">>>;
96
97
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
97
98
  name: z.ZodString;
@@ -127,6 +128,7 @@ export declare const ActionInputSchema: z.ZodObject<{
127
128
  cap: z.ZodString;
128
129
  method: z.ZodString;
129
130
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
131
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
130
132
  }, z.core.$strip>], "kind">>;
131
133
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
132
134
  name: z.ZodString;
@@ -20,7 +20,9 @@ export type { CooldownInput, CooldownVerdict, RunGateAdmission } from './run-gat
20
20
  export { RunGate } from './run-gate.js';
21
21
  export type { AutomationConditionTraceNode, AutomationRunOutcome, AutomationRunTrace, AutomationRunVerdict, AutomationStateDoc, AutomationStepTrace, AutomationTriggerTrace, TraceNodeOutcome, TraceValue, } from './trace.js';
22
22
  export { AutomationConditionTraceNodeSchema, EMPTY_AUTOMATION_STATE, mergeSkipTraces, AutomationRunOutcomeSchema, AutomationRunTraceSchema, AutomationRunVerdictSchema, AutomationStateDocSchema, AutomationStepTraceSchema, AutomationTriggerTraceSchema, appendTrace, buildTriggerTrace, isSkippedTrace, skipSignature, TraceNodeOutcomeSchema, TraceValueSchema, } from './trace.js';
23
- export type { ActionStep, AutomationAction, AutomationCondition, AutomationConditionAll, AutomationConditionAny, AutomationConditionExpression, AutomationConditionLeaf, AutomationConditionNot, AutomationConditionOperator, AutomationConditionStationaryPresent, AutomationRecipe, AutomationRunMode, AutomationTrigger, } from './recipe.js';
23
+ export type { ActionStep, AutomationAction, AutomationCapStep, AutomationCondition, AutomationConditionAll, AutomationConditionAny, AutomationConditionExpression, AutomationConditionLeaf, AutomationConditionNot, AutomationConditionOperator, AutomationConditionStationaryPresent, AutomationRecipe, AutomationRunMode, AutomationTrigger, } from './recipe.js';
24
24
  export { ActionStepSchema, AutomationActionSchema, AutomationCapStepSchema, AutomationWaitStepSchema, AutomationConditionOperatorSchema, AutomationConditionSchema, AutomationRecipeSchema, AutomationRunModeSchema, AutomationTriggerSchema, conditionDepth, countConditionLeaves, DEFAULT_TRACE_KEEP, MAX_TRACE_KEEP, MAX_CONDITION_DEPTH, MAX_CONDITION_LEAVES, validateRecipeBounds, } from './recipe.js';
25
25
  export * from './action.js';
26
26
  export * from './step-runner.js';
27
+ export { UnitWarningSchema, capUnitResolver, normalizeActionUnits, normalizeConditionUnits, normalizeRecipeUnits, } from './normalize-units.js';
28
+ export type { UnitResolver, UnitWarning, UnitsNormalized } from './normalize-units.js';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The save boundary of the value + unit contract (D972).
3
+ *
4
+ * A number tied to a physical quantity is ENTERED in a unit the person picks
5
+ * and STORED in a fixed one:
6
+ *
7
+ * - a condition leaf on a device field → the field's base unit (D944);
8
+ * - a cap step arg → the unit the method's input declares (`paramMeta`).
9
+ *
10
+ * The write form of a number is {@link QuantityValue} (`{ value, unit }`,
11
+ * "this number is in this unit"). Normalising converts it, stores the bare
12
+ * number and records the picked unit (`leaf.unit` / `step.argUnits[arg]`) so an
13
+ * editor can show the number the way it was typed. Normalising an already
14
+ * normalised record changes nothing: a stored bare number is never converted
15
+ * again, which is why the picked unit is a separate field.
16
+ *
17
+ * A bare number on a quantity field is ACCEPTED as the base / declared unit
18
+ * and reported as a {@link UnitWarning}; a unit that cannot belong to the
19
+ * quantity is a typed {@link QuantityUnitError}.
20
+ *
21
+ * Pure: the cap knowledge arrives as a {@link UnitResolver}.
22
+ */
23
+ import type { CapabilityDefinition } from '../capabilities/capability-definition.js';
24
+ import { type ParamMeta } from '../units/quantity-input.js';
25
+ import type { ReadingQuantity } from '../units/quantity.js';
26
+ import { z } from 'zod';
27
+ import type { AutomationAction, AutomationCapStep, AutomationCondition, AutomationRecipe } from './recipe.js';
28
+ /** What the boundary needs to know about caps. */
29
+ export interface UnitResolver {
30
+ /** The quantity of a status field, or `undefined` when it is not a quantity. */
31
+ fieldQuantity(cap: string, fieldPath: string): ReadingQuantity | undefined;
32
+ /** What a method input declares for `arg`, or `undefined` when it is not a quantity. */
33
+ paramMeta(cap: string, method: string, arg: string): ParamMeta | undefined;
34
+ }
35
+ /** A bare number accepted as a base unit — the save succeeded, say so. */
36
+ export declare const UnitWarningSchema: z.ZodObject<{
37
+ path: z.ZodString;
38
+ deviceId: z.ZodOptional<z.ZodNumber>;
39
+ field: z.ZodString;
40
+ value: z.ZodNumber;
41
+ assumedUnit: z.ZodString;
42
+ message: z.ZodString;
43
+ }, z.core.$strip>;
44
+ export type UnitWarning = z.infer<typeof UnitWarningSchema>;
45
+ export interface UnitsNormalized<T> {
46
+ readonly value: T;
47
+ readonly warnings: readonly UnitWarning[];
48
+ }
49
+ /** A resolver over capability definitions (the generated registry, or a fake). */
50
+ export declare function capUnitResolver(defs: readonly CapabilityDefinition[]): UnitResolver;
51
+ /** Normalise every leaf of a condition tree. Throws {@link QuantityUnitError}. */
52
+ export declare function normalizeConditionUnits(condition: AutomationCondition, resolver: UnitResolver, path?: string): UnitsNormalized<AutomationCondition>;
53
+ /**
54
+ * Normalise the cap steps of an action list (an internal Action's steps, or a
55
+ * recipe's actions). Other step kinds pass through. Throws {@link QuantityUnitError}.
56
+ */
57
+ export declare function normalizeActionUnits<A extends AutomationAction>(actions: readonly A[], resolver: UnitResolver, path?: string): UnitsNormalized<(A | AutomationCapStep)[]>;
58
+ /** Normalise a whole recipe: its condition tree and its actions. */
59
+ export declare function normalizeRecipeUnits(recipe: AutomationRecipe, resolver: UnitResolver): UnitsNormalized<AutomationRecipe>;
@@ -27,6 +27,7 @@
27
27
  */
28
28
  import { z } from 'zod';
29
29
  import { type ExpressionBindingSource } from '../expression/binding-source.js';
30
+ import { type QuantityValue } from '../units/quantity-input.js';
30
31
  /**
31
32
  * Depth of a condition tree, counting the root container as level 1.
32
33
  *
@@ -58,7 +59,15 @@ export interface AutomationConditionLeaf {
58
59
  readonly cap: string;
59
60
  readonly fieldPath: string;
60
61
  readonly operator: AutomationConditionOperator;
61
- readonly value: string | number | boolean | readonly (string | number)[];
62
+ /**
63
+ * The value. A number on a quantity field is stored in the field's base unit
64
+ * (D944); {@link QuantityValue} is the WRITE form — "this number is in this
65
+ * unit" — which the save boundary replaces with the converted number and
66
+ * `unit`. A leaf that still carries one is never evaluated (it fails).
67
+ */
68
+ readonly value: string | number | boolean | readonly (string | number)[] | QuantityValue;
69
+ /** The unit the person picked for `value` (display only; `value` is in the base unit). */
70
+ readonly unit?: string;
62
71
  }
63
72
  /** The escape hatch: the bounded expression engine over named device bindings. */
64
73
  export interface AutomationConditionExpression {
@@ -170,7 +179,9 @@ export declare const AutomationCapStepSchema: z.ZodObject<{
170
179
  cap: z.ZodString;
171
180
  method: z.ZodString;
172
181
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
182
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
173
183
  }, z.core.$strip>;
184
+ export type AutomationCapStep = z.infer<typeof AutomationCapStepSchema>;
174
185
  /**
175
186
  * The steps an internal Action may contain: cap and wait, and nothing that can
176
187
  * call back into an Action — so an Action can never reach itself (no cycles).
@@ -186,6 +197,7 @@ export declare const ActionStepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
186
197
  cap: z.ZodString;
187
198
  method: z.ZodString;
188
199
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
200
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
189
201
  }, z.core.$strip>], "kind">;
190
202
  export type ActionStep = z.infer<typeof ActionStepSchema>;
191
203
  export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -199,6 +211,7 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
199
211
  cap: z.ZodString;
200
212
  method: z.ZodString;
201
213
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
214
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
202
215
  }, z.core.$strip>, z.ZodObject<{
203
216
  kind: z.ZodLiteral<"action">;
204
217
  actionId: z.ZodString;
@@ -289,6 +302,7 @@ export declare const AutomationRecipeSchema: z.ZodObject<{
289
302
  cap: z.ZodString;
290
303
  method: z.ZodString;
291
304
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
305
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
292
306
  }, z.core.$strip>, z.ZodObject<{
293
307
  kind: z.ZodLiteral<"action">;
294
308
  actionId: z.ZodString;
@@ -42,6 +42,7 @@ export declare const actionSourceCapability: {
42
42
  cap: z.ZodString;
43
43
  method: z.ZodString;
44
44
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
45
46
  }, z.core.$strip>], "kind">>>;
46
47
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
47
48
  name: z.ZodString;
@@ -31,6 +31,7 @@ export declare const actionsCapability: {
31
31
  cap: z.ZodString;
32
32
  method: z.ZodString;
33
33
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
34
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
34
35
  }, z.core.$strip>], "kind">>>;
35
36
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
36
37
  name: z.ZodString;
@@ -79,6 +80,7 @@ export declare const actionsCapability: {
79
80
  cap: z.ZodString;
80
81
  method: z.ZodString;
81
82
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
83
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
82
84
  }, z.core.$strip>], "kind">>>;
83
85
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
84
86
  name: z.ZodString;
@@ -225,7 +227,15 @@ export declare const actionsCapability: {
225
227
  lastAt: z.ZodNumber;
226
228
  }, z.core.$strip>>;
227
229
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
228
- /** Internal actions only. A read-only (addon) entry is refused with `[read-only]`. */
230
+ /**
231
+ * Internal actions only; a read-only (addon) entry is refused with `[read-only]`.
232
+ * Create an internal action. A cap step arg that is a physical quantity may
233
+ * be sent as `{ value, unit }` ("value expressed in unit"); the server
234
+ * converts it to the unit the method's input declares, stores the bare
235
+ * number plus the picked unit in `argUnits`, and refuses a unit of another
236
+ * dimension (`[invalid-steps]`). A bare number is taken as the declared
237
+ * unit and answered as a `warnings` entry (D972).
238
+ */
229
239
  readonly create: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
230
240
  action: z.ZodObject<{
231
241
  name: z.ZodString;
@@ -240,6 +250,7 @@ export declare const actionsCapability: {
240
250
  cap: z.ZodString;
241
251
  method: z.ZodString;
242
252
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
253
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
243
254
  }, z.core.$strip>], "kind">>;
244
255
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
245
256
  name: z.ZodString;
@@ -276,6 +287,7 @@ export declare const actionsCapability: {
276
287
  cap: z.ZodString;
277
288
  method: z.ZodString;
278
289
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
290
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
279
291
  }, z.core.$strip>], "kind">>>;
280
292
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
281
293
  name: z.ZodString;
@@ -296,6 +308,14 @@ export declare const actionsCapability: {
296
308
  lastError: z.ZodNullable<z.ZodString>;
297
309
  }, z.core.$strip>;
298
310
  }, z.core.$strip>;
311
+ warnings: z.ZodOptional<z.ZodArray<z.ZodObject<{
312
+ path: z.ZodString;
313
+ deviceId: z.ZodOptional<z.ZodNumber>;
314
+ field: z.ZodString;
315
+ value: z.ZodNumber;
316
+ assumedUnit: z.ZodString;
317
+ message: z.ZodString;
318
+ }, z.core.$strip>>>;
299
319
  }, z.core.$strip>, "mutation">;
300
320
  readonly update: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
301
321
  actionId: z.ZodString;
@@ -312,6 +332,7 @@ export declare const actionsCapability: {
312
332
  cap: z.ZodString;
313
333
  method: z.ZodString;
314
334
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
335
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
315
336
  }, z.core.$strip>], "kind">>>;
316
337
  variables: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
317
338
  name: z.ZodString;
@@ -348,6 +369,7 @@ export declare const actionsCapability: {
348
369
  cap: z.ZodString;
349
370
  method: z.ZodString;
350
371
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
372
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
351
373
  }, z.core.$strip>], "kind">>>;
352
374
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
353
375
  name: z.ZodString;
@@ -368,6 +390,14 @@ export declare const actionsCapability: {
368
390
  lastError: z.ZodNullable<z.ZodString>;
369
391
  }, z.core.$strip>;
370
392
  }, z.core.$strip>;
393
+ warnings: z.ZodOptional<z.ZodArray<z.ZodObject<{
394
+ path: z.ZodString;
395
+ deviceId: z.ZodOptional<z.ZodNumber>;
396
+ field: z.ZodString;
397
+ value: z.ZodNumber;
398
+ assumedUnit: z.ZodString;
399
+ message: z.ZodString;
400
+ }, z.core.$strip>>>;
371
401
  }, z.core.$strip>, "mutation">;
372
402
  readonly delete: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
373
403
  actionId: z.ZodString;
@@ -399,6 +429,7 @@ export declare const actionsCapability: {
399
429
  cap: z.ZodString;
400
430
  method: z.ZodString;
401
431
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
432
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
402
433
  }, z.core.$strip>], "kind">>>;
403
434
  variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
404
435
  name: z.ZodString;
@@ -188,6 +188,7 @@ export declare const CoreBlockSourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject
188
188
  cap: z.ZodString;
189
189
  method: z.ZodString;
190
190
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
191
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
191
192
  }, z.core.$strip>, z.ZodObject<{
192
193
  kind: z.ZodLiteral<"action">;
193
194
  actionId: z.ZodString;
@@ -731,6 +732,7 @@ export declare const CoreBlockSchema: z.ZodObject<{
731
732
  cap: z.ZodString;
732
733
  method: z.ZodString;
733
734
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
735
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
734
736
  }, z.core.$strip>, z.ZodObject<{
735
737
  kind: z.ZodLiteral<"action">;
736
738
  actionId: z.ZodString;
@@ -1090,6 +1092,7 @@ export declare const CompositionViewSchema: z.ZodObject<{
1090
1092
  cap: z.ZodString;
1091
1093
  method: z.ZodString;
1092
1094
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1095
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1093
1096
  }, z.core.$strip>, z.ZodObject<{
1094
1097
  kind: z.ZodLiteral<"action">;
1095
1098
  actionId: z.ZodString;
@@ -1447,6 +1450,7 @@ export declare const CompositionListReadSchema: z.ZodDiscriminatedUnion<[z.ZodOb
1447
1450
  cap: z.ZodString;
1448
1451
  method: z.ZodString;
1449
1452
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1453
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1450
1454
  }, z.core.$strip>, z.ZodObject<{
1451
1455
  kind: z.ZodLiteral<"action">;
1452
1456
  actionId: z.ZodString;
@@ -1808,6 +1812,7 @@ export declare const CompositionGetReadSchema: z.ZodDiscriminatedUnion<[z.ZodObj
1808
1812
  cap: z.ZodString;
1809
1813
  method: z.ZodString;
1810
1814
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1815
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1811
1816
  }, z.core.$strip>, z.ZodObject<{
1812
1817
  kind: z.ZodLiteral<"action">;
1813
1818
  actionId: z.ZodString;
@@ -2170,6 +2175,7 @@ export declare const CompositionCustomizationReadSchema: z.ZodDiscriminatedUnion
2170
2175
  cap: z.ZodString;
2171
2176
  method: z.ZodString;
2172
2177
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2178
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2173
2179
  }, z.core.$strip>, z.ZodObject<{
2174
2180
  kind: z.ZodLiteral<"action">;
2175
2181
  actionId: z.ZodString;
@@ -2552,6 +2558,7 @@ export declare const coreBlocksCapability: {
2552
2558
  cap: z.ZodString;
2553
2559
  method: z.ZodString;
2554
2560
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2561
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2555
2562
  }, z.core.$strip>, z.ZodObject<{
2556
2563
  kind: z.ZodLiteral<"action">;
2557
2564
  actionId: z.ZodString;
@@ -2872,6 +2879,7 @@ export declare const coreBlocksCapability: {
2872
2879
  cap: z.ZodString;
2873
2880
  method: z.ZodString;
2874
2881
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2882
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2875
2883
  }, z.core.$strip>, z.ZodObject<{
2876
2884
  kind: z.ZodLiteral<"action">;
2877
2885
  actionId: z.ZodString;
@@ -3206,6 +3214,7 @@ export declare const coreBlocksCapability: {
3206
3214
  cap: z.ZodString;
3207
3215
  method: z.ZodString;
3208
3216
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3217
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3209
3218
  }, z.core.$strip>, z.ZodObject<{
3210
3219
  kind: z.ZodLiteral<"action">;
3211
3220
  actionId: z.ZodString;
@@ -3538,6 +3547,7 @@ export declare const coreBlocksCapability: {
3538
3547
  cap: z.ZodString;
3539
3548
  method: z.ZodString;
3540
3549
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3550
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3541
3551
  }, z.core.$strip>, z.ZodObject<{
3542
3552
  kind: z.ZodLiteral<"action">;
3543
3553
  actionId: z.ZodString;
@@ -3866,6 +3876,7 @@ export declare const coreBlocksCapability: {
3866
3876
  cap: z.ZodString;
3867
3877
  method: z.ZodString;
3868
3878
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3879
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3869
3880
  }, z.core.$strip>, z.ZodObject<{
3870
3881
  kind: z.ZodLiteral<"action">;
3871
3882
  actionId: z.ZodString;
@@ -4199,6 +4210,7 @@ export declare const coreBlocksCapability: {
4199
4210
  cap: z.ZodString;
4200
4211
  method: z.ZodString;
4201
4212
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
4213
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4202
4214
  }, z.core.$strip>, z.ZodObject<{
4203
4215
  kind: z.ZodLiteral<"action">;
4204
4216
  actionId: z.ZodString;
@@ -4838,6 +4850,7 @@ export declare const coreBlocksCapability: {
4838
4850
  cap: z.ZodString;
4839
4851
  method: z.ZodString;
4840
4852
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
4853
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4841
4854
  }, z.core.$strip>, z.ZodObject<{
4842
4855
  kind: z.ZodLiteral<"action">;
4843
4856
  actionId: z.ZodString;
@@ -5381,6 +5394,7 @@ export declare const coreBlocksCapability: {
5381
5394
  cap: z.ZodString;
5382
5395
  method: z.ZodString;
5383
5396
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5397
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
5384
5398
  }, z.core.$strip>, z.ZodObject<{
5385
5399
  kind: z.ZodLiteral<"action">;
5386
5400
  actionId: z.ZodString;
@@ -5706,6 +5720,7 @@ export declare const coreBlocksCapability: {
5706
5720
  cap: z.ZodString;
5707
5721
  method: z.ZodString;
5708
5722
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5723
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
5709
5724
  }, z.core.$strip>, z.ZodObject<{
5710
5725
  kind: z.ZodLiteral<"action">;
5711
5726
  actionId: z.ZodString;
@@ -6066,6 +6081,7 @@ export declare const coreBlocksCapability: {
6066
6081
  cap: z.ZodString;
6067
6082
  method: z.ZodString;
6068
6083
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
6084
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
6069
6085
  }, z.core.$strip>, z.ZodObject<{
6070
6086
  kind: z.ZodLiteral<"action">;
6071
6087
  actionId: z.ZodString;
@@ -6433,6 +6449,7 @@ export declare const coreBlocksCapability: {
6433
6449
  cap: z.ZodString;
6434
6450
  method: z.ZodString;
6435
6451
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
6452
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
6436
6453
  }, z.core.$strip>, z.ZodObject<{
6437
6454
  kind: z.ZodLiteral<"action">;
6438
6455
  actionId: z.ZodString;
@@ -119,7 +119,7 @@ export { CameraMetricsSchema, CameraMetricsWithDeviceIdSchema, OrchestratorMetri
119
119
  export type { AudioStreamPick, CameraStream, CamProfile, CamStreamKind, DecodedAudioChunkWire, ProfileRtspEntry, ProfileSlot, ProfileSlotStatus, SubscribeAudioChunksInput, SubscribeAudioChunksResult, } from './schemas/streaming-shared.js';
120
120
  export { AudioChunkFormatSchema, AudioStreamPickSchema, BrokerStatsSchema, BrokerStatusSchema, CAM_PROFILE_ORDER, CameraStreamSchema, CamProfileSchema, CamStreamKindSchema, CamStreamResolutionSchema, DecodedAudioChunkSchema, FrameHandleSchema, makeProfileBrokerId, makeSourceBrokerId, ProfileRtspEntrySchema, ProfileSlotSchema, ProfileSlotStatusSchema, parseProfileBrokerId, StreamSourceEntrySchema, StreamSourceSchema, SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, selectAssignedProfileSlots, } from './schemas/streaming-shared.js';
121
121
  export { buildEventKindDescriptor, EVENT_KIND_BY_CAP, EVENTFUL_CAP_NAMES, type SensorEventKindDescriptor, } from './sensor-event-kinds.js';
122
- export { type ImageContract, ImageContractSchema, type ImageContractState, ImageContractStateSchema, type IServerManagementProvider, type RunnerBootCheck, RunnerBootCheckSchema, type RunnerRefusal, RunnerRefusalSchema, type ServerBootMode, ServerBootModeSchema, type ServerPackageStatus, ServerPackageStatusSchema, type ServerRollbackInfo, ServerRollbackInfoSchema, type LaunchOverrides, type SetLaunchOverridesResult, type ServerUpdateActionResult, ServerUpdateActionResultSchema, type ServerUpdateCheckResult, ServerUpdateCheckResultSchema, type ServerUpdateOutcome, ServerUpdateOutcomeSchema, type ServerUpdateState, ServerUpdateStateSchema, serverManagementCapability, type UpdateBlocker, UpdateBlockerSchema, type WrapperEvidence, WrapperEvidenceSchema, type WrapperIdentity, WrapperIdentitySchema, type WrapperKind, WrapperKindSchema, } from './server-management.cap.js';
122
+ export { type ImageContract, ImageContractSchema, type ImageContractState, ImageContractStateSchema, type IServerManagementProvider, type RunnerBootCheck, RunnerBootCheckSchema, type RunnerRefusal, RunnerRefusalSchema, type ServerBootMode, ServerBootModeSchema, type ServerPackageStatus, ServerPackageStatusSchema, type ServerRollbackInfo, ServerRollbackInfoSchema, type LaunchOverrides, type SetLaunchOverridesResult, type ServerUpdateActionResult, ServerUpdateActionResultSchema, type ServerUpdateCheckResult, ServerUpdateCheckResultSchema, type ServerUpdateOutcome, ServerUpdateOutcomeSchema, type ServerUpdateState, ServerUpdateStateSchema, serverManagementCapability, type UpdateBlocker, UpdateBlockerSchema, type DesktopAppStatus, DesktopAppStatusSchema, type InstallDesktopUpdateReason, InstallDesktopUpdateReasonSchema, type InstallDesktopUpdateResult, InstallDesktopUpdateResultSchema, type WrapperEvidence, WrapperEvidenceSchema, type WrapperIdentity, WrapperIdentitySchema, type WrapperKind, WrapperKindSchema, } from './server-management.cap.js';
123
123
  export { type BulkRecord, BulkRecordSchema, type CollectionColumn, CollectionColumnSchema, type CollectionIndex, CollectionIndexSchema, DATA_STORE_DATABASES, type DataStoreDatabase, DataStoreDatabaseSchema, type DeclareCollectionInput, DeclareCollectionInputSchema, type ISettingsStoreProvider, type MutationFilter, MutationFilterSchema, QueryFilterSchema, SettingsRecordSchema, type SettingsStoreClient, settingsStoreCapability, } from './settings-store.cap.js';
124
124
  export type { ISmtpProvider } from './smtp-provider.cap.js';
125
125
  export { SendEmailInputSchema, SendEmailResultSchema, SmtpStatusSchema, smtpProviderCapability, } from './smtp-provider.cap.js';
@@ -124,6 +124,7 @@ export declare const remoteCapability: {
124
124
  cap: z.ZodString;
125
125
  method: z.ZodString;
126
126
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
127
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
127
128
  deviceId: z.ZodNumber;
128
129
  }, z.core.$strip>;
129
130
  }, z.core.$strip>>;
@@ -149,6 +150,7 @@ export declare const remoteCapability: {
149
150
  cap: z.ZodString;
150
151
  method: z.ZodString;
151
152
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
153
+ argUnits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
152
154
  deviceId: z.ZodNumber;
153
155
  }, z.core.$strip>;
154
156
  }, z.core.$strip>>;
@@ -167,11 +167,13 @@ declare const WrapperEvidenceSchema: z.ZodObject<{
167
167
  * The shell verdict (see {@link WrapperKindSchema}) with the proofs that
168
168
  * produced it.
169
169
  *
170
- * There is deliberately NO `canSelfUpdate` and no apply action: a wrapper
171
- * update is an ANNOUNCEMENT. The notification body carries the exact command
172
- * for a `docker` shell and says the app restarts into the new build for
173
- * `electron`, and that sentence is chosen from `kind` alone — a boolean
174
- * nothing reads is the defect this repo keeps paying for.
170
+ * There is deliberately NO `canSelfUpdate` boolean: a wrapper update is an
171
+ * ANNOUNCEMENT. The notification body carries the exact command for a `docker`
172
+ * shell and says the app restarts into the new build for `electron`, and that
173
+ * sentence is chosen from `kind` alone — a boolean nothing reads is the defect
174
+ * this repo keeps paying for. The one shell that CAN be acted on is the
175
+ * Electron app, and only through `installDesktopUpdate` (see
176
+ * {@link DesktopAppStatusSchema} for what the node reads from the app first).
175
177
  */
176
178
  declare const WrapperIdentitySchema: z.ZodObject<{
177
179
  kind: z.ZodEnum<{
@@ -203,6 +205,50 @@ declare const ServerRollbackInfoSchema: z.ZodObject<{
203
205
  atMs: z.ZodNumber;
204
206
  reason: z.ZodString;
205
207
  }, z.core.$strip>;
208
+ /**
209
+ * What the native desktop app (Electron) that hosts this node says about
210
+ * itself, read from `<dataDir>/server-root/desktop-app-state.json` (ADR-0971).
211
+ * Absent on the status = no desktop app, or it never wrote the file.
212
+ *
213
+ * `stale` is the honest answer to an app that stopped writing (closed, hung,
214
+ * crashed): the update facts are then the LAST ones known, not current ones,
215
+ * and a consumer must not read `update.available: false` from a stale record
216
+ * as "no update". `stateAtMs` is when the app last wrote.
217
+ */
218
+ declare const DesktopAppStatusSchema: z.ZodObject<{
219
+ version: z.ZodString;
220
+ update: z.ZodObject<{
221
+ available: z.ZodBoolean;
222
+ downloaded: z.ZodBoolean;
223
+ version: z.ZodNullable<z.ZodString>;
224
+ checking: z.ZodBoolean;
225
+ error: z.ZodNullable<z.ZodString>;
226
+ }, z.core.$strip>;
227
+ stateAtMs: z.ZodNumber;
228
+ stale: z.ZodBoolean;
229
+ }, z.core.$strip>;
230
+ /**
231
+ * Why `installDesktopUpdate` did nothing. Stable names a UI maps to a sentence:
232
+ * - `not-electron` — this node does not run inside the desktop app.
233
+ * - `no-app-state` — the app never published its state (or the file is unreadable).
234
+ * - `app-state-stale` — the app stopped writing; it is probably not running.
235
+ * - `not-downloaded` — no update is downloaded yet; nothing to install.
236
+ */
237
+ declare const InstallDesktopUpdateReasonSchema: z.ZodEnum<{
238
+ "app-state-stale": "app-state-stale";
239
+ "no-app-state": "no-app-state";
240
+ "not-downloaded": "not-downloaded";
241
+ "not-electron": "not-electron";
242
+ }>;
243
+ declare const InstallDesktopUpdateResultSchema: z.ZodObject<{
244
+ accepted: z.ZodBoolean;
245
+ reason: z.ZodNullable<z.ZodEnum<{
246
+ "app-state-stale": "app-state-stale";
247
+ "no-app-state": "no-app-state";
248
+ "not-downloaded": "not-downloaded";
249
+ "not-electron": "not-electron";
250
+ }>>;
251
+ }, z.core.$strip>;
206
252
  /**
207
253
  * The runner boot check (D877): the runners this node PLANNED (hub: one per
208
254
  * `resolveRunnerId` over its forked addons; agent: the runners its process
@@ -319,6 +365,18 @@ declare const ServerPackageStatusSchema: z.ZodObject<{
319
365
  pending: z.ZodOptional<z.ZodArray<z.ZodString>>;
320
366
  planKnown: z.ZodBoolean;
321
367
  }, z.core.$strip>>;
368
+ desktopApp: z.ZodOptional<z.ZodObject<{
369
+ version: z.ZodString;
370
+ update: z.ZodObject<{
371
+ available: z.ZodBoolean;
372
+ downloaded: z.ZodBoolean;
373
+ version: z.ZodNullable<z.ZodString>;
374
+ checking: z.ZodBoolean;
375
+ error: z.ZodNullable<z.ZodString>;
376
+ }, z.core.$strip>;
377
+ stateAtMs: z.ZodNumber;
378
+ stale: z.ZodBoolean;
379
+ }, z.core.$strip>>;
322
380
  }, z.core.$strip>;
323
381
  declare const ServerUpdateCheckResultSchema: z.ZodObject<{
324
382
  packageName: z.ZodString;
@@ -477,6 +535,18 @@ export declare const serverManagementCapability: {
477
535
  pending: z.ZodOptional<z.ZodArray<z.ZodString>>;
478
536
  planKnown: z.ZodBoolean;
479
537
  }, z.core.$strip>>;
538
+ desktopApp: z.ZodOptional<z.ZodObject<{
539
+ version: z.ZodString;
540
+ update: z.ZodObject<{
541
+ available: z.ZodBoolean;
542
+ downloaded: z.ZodBoolean;
543
+ version: z.ZodNullable<z.ZodString>;
544
+ checking: z.ZodBoolean;
545
+ error: z.ZodNullable<z.ZodString>;
546
+ }, z.core.$strip>;
547
+ stateAtMs: z.ZodNumber;
548
+ stale: z.ZodBoolean;
549
+ }, z.core.$strip>>;
480
550
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
481
551
  readonly checkServerUpdate: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
482
552
  packageName: z.ZodString;
@@ -511,6 +581,24 @@ export declare const serverManagementCapability: {
511
581
  remedy: z.ZodString;
512
582
  }, z.core.$strip>>>;
513
583
  }, z.core.$strip>, "mutation">;
584
+ /**
585
+ * Ask the desktop app hosting this node to install its DOWNLOADED update
586
+ * and restart. The request is a file in the node's data dir (the node may
587
+ * be a Windows service, not Electron's child); the app consumes it once.
588
+ * `accepted: true` means the request was WRITTEN — the app restarting is
589
+ * observed afterwards on `desktopApp.version`, not promised here. Refused
590
+ * with a named `reason` when not an electron shell, the app's state is
591
+ * absent or stale, or nothing is downloaded.
592
+ */
593
+ readonly installDesktopUpdate: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
594
+ accepted: z.ZodBoolean;
595
+ reason: z.ZodNullable<z.ZodEnum<{
596
+ "app-state-stale": "app-state-stale";
597
+ "no-app-state": "no-app-state";
598
+ "not-downloaded": "not-downloaded";
599
+ "not-electron": "not-electron";
600
+ }>>;
601
+ }, z.core.$strip>, "mutation">;
514
602
  readonly rollbackServerUpdate: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
515
603
  accepted: z.ZodBoolean;
516
604
  targetVersion: z.ZodNullable<z.ZodString>;
@@ -591,6 +679,9 @@ export type ImageContract = z.infer<typeof ImageContractSchema>;
591
679
  export type WrapperKind = z.infer<typeof WrapperKindSchema>;
592
680
  export type WrapperEvidence = z.infer<typeof WrapperEvidenceSchema>;
593
681
  export type WrapperIdentity = z.infer<typeof WrapperIdentitySchema>;
682
+ export type DesktopAppStatus = z.infer<typeof DesktopAppStatusSchema>;
683
+ export type InstallDesktopUpdateReason = z.infer<typeof InstallDesktopUpdateReasonSchema>;
684
+ export type InstallDesktopUpdateResult = z.infer<typeof InstallDesktopUpdateResultSchema>;
594
685
  export type ServerRollbackInfo = z.infer<typeof ServerRollbackInfoSchema>;
595
686
  export type ServerPackageStatus = z.infer<typeof ServerPackageStatusSchema>;
596
687
  export type ServerUpdateCheckResult = z.infer<typeof ServerUpdateCheckResultSchema>;
@@ -601,4 +692,4 @@ export type SetLaunchOverridesResult = z.infer<typeof SetLaunchOverridesResultSc
601
692
  export type RunnerBootCheck = z.infer<typeof RunnerBootCheckSchema>;
602
693
  export type RunnerRefusal = z.infer<typeof RunnerRefusalSchema>;
603
694
  export type UpdateBlocker = z.infer<typeof UpdateBlockerSchema>;
604
- export { RunnerBootCheckSchema, RunnerRefusalSchema, UpdateBlockerSchema, ServerBootModeSchema, ServerUpdateStateSchema, ImageContractStateSchema, ImageContractSchema, WrapperKindSchema, WrapperEvidenceSchema, WrapperIdentitySchema, ServerRollbackInfoSchema, ServerPackageStatusSchema, ServerUpdateCheckResultSchema, ServerUpdateOutcomeSchema, ServerUpdateActionResultSchema, };
695
+ export { RunnerBootCheckSchema, RunnerRefusalSchema, UpdateBlockerSchema, ServerBootModeSchema, ServerUpdateStateSchema, ImageContractStateSchema, ImageContractSchema, WrapperKindSchema, WrapperEvidenceSchema, WrapperIdentitySchema, DesktopAppStatusSchema, InstallDesktopUpdateReasonSchema, InstallDesktopUpdateResultSchema, ServerRollbackInfoSchema, ServerPackageStatusSchema, ServerUpdateCheckResultSchema, ServerUpdateOutcomeSchema, ServerUpdateActionResultSchema, };
package/dist/client.js CHANGED
@@ -28969,6 +28969,7 @@ function createSystemProxy(api) {
28969
28969
  getServerPackageStatus: (input) => dispatch("serverManagement", "getServerPackageStatus", "query", input),
28970
28970
  checkServerUpdate: (input) => dispatch("serverManagement", "checkServerUpdate", "mutation", input),
28971
28971
  applyServerUpdate: (input) => dispatch("serverManagement", "applyServerUpdate", "mutation", input),
28972
+ installDesktopUpdate: (input) => dispatch("serverManagement", "installDesktopUpdate", "mutation", input),
28972
28973
  rollbackServerUpdate: (input) => dispatch("serverManagement", "rollbackServerUpdate", "mutation", input),
28973
28974
  restartServer: (input) => dispatch("serverManagement", "restartServer", "mutation", input),
28974
28975
  getLaunchOverrides: (input) => dispatch("serverManagement", "getLaunchOverrides", "query", input),
package/dist/client.mjs CHANGED
@@ -28968,6 +28968,7 @@ function createSystemProxy(api) {
28968
28968
  getServerPackageStatus: (input) => dispatch("serverManagement", "getServerPackageStatus", "query", input),
28969
28969
  checkServerUpdate: (input) => dispatch("serverManagement", "checkServerUpdate", "mutation", input),
28970
28970
  applyServerUpdate: (input) => dispatch("serverManagement", "applyServerUpdate", "mutation", input),
28971
+ installDesktopUpdate: (input) => dispatch("serverManagement", "installDesktopUpdate", "mutation", input),
28971
28972
  rollbackServerUpdate: (input) => dispatch("serverManagement", "rollbackServerUpdate", "mutation", input),
28972
28973
  restartServer: (input) => dispatch("serverManagement", "restartServer", "mutation", input),
28973
28974
  getLaunchOverrides: (input) => dispatch("serverManagement", "getLaunchOverrides", "query", input),
@@ -20,6 +20,7 @@ import type * as CapRegistry from '../../generated/capability-router-map.js';
20
20
  import type { EventCategory } from '../../enums/event-category.js';
21
21
  import type { ICON_KEYS } from '../icon-catalog.generated.js';
22
22
  import type { DeviceRole, DeviceType } from '../device-type.js';
23
+ import type { ReadingQuantity } from '../../units/quantity.js';
23
24
  /** One catalog icon key (lucide id) — the same vocabulary as `IconKey`. */
24
25
  export type VocabIcon = (typeof ICON_KEYS)[number];
25
26
  /** A human string in every language the map carries. */
@@ -82,13 +83,20 @@ export interface EnumOffer {
82
83
  readonly kind: 'enum';
83
84
  readonly values: readonly VocabChoice[];
84
85
  }
85
- /** A number, within the Zod input's bounds. `unit` is a display suffix. */
86
+ /**
87
+ * A number, within the Zod input's bounds. With `quantity` the number is a
88
+ * physical quantity: `unit` is the unit the METHOD expects (what its input
89
+ * declares with `paramMeta`) and a client lets the person pick any unit of
90
+ * that quantity (`unitsForQuantity`), converting to `unit` before the call.
91
+ * Without `quantity`, `unit` is only a display suffix.
92
+ */
86
93
  export interface NumberOffer {
87
94
  readonly kind: 'number';
88
95
  readonly min?: number;
89
96
  readonly max?: number;
90
97
  readonly step?: number;
91
98
  readonly unit?: string;
99
+ readonly quantity?: ReadingQuantity;
92
100
  }
93
101
  /** Free text. */
94
102
  export interface TextOffer {