@camstack/types 1.2.428 → 1.2.430

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 (39) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/addon/session-health.d.ts +124 -0
  3. package/dist/addon.js +4 -3
  4. package/dist/addon.mjs +4 -3
  5. package/dist/automation/action.d.ts +210 -0
  6. package/dist/automation/condition-eval.d.ts +64 -0
  7. package/dist/automation/detection-trigger.d.ts +66 -0
  8. package/dist/automation/index.d.ts +12 -2
  9. package/dist/automation/recipe.d.ts +103 -1
  10. package/dist/automation/run-gate.d.ts +43 -0
  11. package/dist/automation/step-runner.d.ts +82 -0
  12. package/dist/automation/trace.d.ts +325 -0
  13. package/dist/capabilities/action-source.cap.d.ts +74 -0
  14. package/dist/capabilities/actions.cap.d.ts +459 -0
  15. package/dist/capabilities/core-blocks.cap.d.ts +761 -0
  16. package/dist/capabilities/index.d.ts +5 -1
  17. package/dist/capabilities/pet-feeder.cap.d.ts +15 -1
  18. package/dist/client.js +73 -49
  19. package/dist/client.mjs +73 -49
  20. package/dist/enums/event-category.d.ts +5 -0
  21. package/dist/enums.js +1 -1
  22. package/dist/enums.mjs +1 -1
  23. package/dist/{event-category-Ave2VSxY.js → event-category-BhzwWQCH.js} +5 -0
  24. package/dist/{event-category-CT-hz5Rb.mjs → event-category-hdMR7CTW.mjs} +5 -0
  25. package/dist/generated/addon-api.d.ts +135 -0
  26. package/dist/generated/addon-cap-facts.d.ts +1 -1
  27. package/dist/generated/capability-router-map.d.ts +10 -4
  28. package/dist/generated/collection-array-methods.d.ts +1 -1
  29. package/dist/generated/device-proxy.d.ts +2 -0
  30. package/dist/generated/history-catalog.d.ts +1 -1
  31. package/dist/generated/method-access-map.d.ts +1 -1
  32. package/dist/generated/method-device-selectors.d.ts +2 -2
  33. package/dist/generated/system-proxy.d.ts +5 -1
  34. package/dist/index.d.ts +6 -2
  35. package/dist/index.js +3211 -1093
  36. package/dist/index.mjs +3153 -1094
  37. package/dist/{sleep-edKiOXLo.js → sleep-5zRztaHa.js} +24 -2
  38. package/dist/{sleep--jXS9hWo.mjs → sleep-BHjNez61.mjs} +24 -2
  39. package/package.json +1 -1
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * Three vocabularies, each salvaged rather than invented:
13
13
  *
14
- * - **Triggers** — the only genuinely new surface. Four members, none of which
14
+ * - **Triggers** — the only genuinely new surface. Six members, none of which
15
15
  * touches notification delivery. The NC keeps its four *pipeline* triggers;
16
16
  * these are device/time triggers and the two sets do not overlap.
17
17
  * - **Conditions** — `ALL`/`ANY`/`NOT` over two leaf kinds, bounded. The
@@ -108,6 +108,15 @@ export declare const AutomationTriggerSchema: z.ZodDiscriminatedUnion<[z.ZodObje
108
108
  cron: z.ZodString;
109
109
  }, z.core.$strip>, z.ZodObject<{
110
110
  kind: z.ZodLiteral<"manual">;
111
+ }, z.core.$strip>, z.ZodObject<{
112
+ kind: z.ZodLiteral<"detection">;
113
+ classes: z.ZodArray<z.ZodString>;
114
+ deviceIds: z.ZodArray<z.ZodNumber>;
115
+ zones: z.ZodOptional<z.ZodArray<z.ZodString>>;
116
+ minScore: z.ZodOptional<z.ZodNumber>;
117
+ }, z.core.$strip>, z.ZodObject<{
118
+ kind: z.ZodLiteral<"interval">;
119
+ minutes: z.ZodNumber;
111
120
  }, z.core.$strip>], "kind">;
112
121
  export type AutomationTrigger = z.infer<typeof AutomationTriggerSchema>;
113
122
  /**
@@ -128,6 +137,36 @@ export type AutomationTrigger = z.infer<typeof AutomationTriggerSchema>;
128
137
  * is called. The runner still receives a number and is untouched; the
129
138
  * resolution is the recipe's job, not the runner's.
130
139
  */
140
+ export declare const AutomationWaitStepSchema: z.ZodObject<{
141
+ kind: z.ZodLiteral<"wait">;
142
+ seconds: z.ZodNumber;
143
+ }, z.core.$strip>;
144
+ export declare const AutomationCapStepSchema: z.ZodObject<{
145
+ kind: z.ZodLiteral<"cap">;
146
+ deviceId: z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>, z.ZodObject<{
147
+ $var: z.ZodString;
148
+ }, z.core.$strip>]>;
149
+ cap: z.ZodString;
150
+ method: z.ZodString;
151
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
152
+ }, z.core.$strip>;
153
+ /**
154
+ * The steps an internal Action may contain: cap and wait, and nothing that can
155
+ * call back into an Action — so an Action can never reach itself (no cycles).
156
+ */
157
+ export declare const ActionStepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
158
+ kind: z.ZodLiteral<"wait">;
159
+ seconds: z.ZodNumber;
160
+ }, z.core.$strip>, z.ZodObject<{
161
+ kind: z.ZodLiteral<"cap">;
162
+ deviceId: z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>, z.ZodObject<{
163
+ $var: z.ZodString;
164
+ }, z.core.$strip>]>;
165
+ cap: z.ZodString;
166
+ method: z.ZodString;
167
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
168
+ }, z.core.$strip>], "kind">;
169
+ export type ActionStep = z.infer<typeof ActionStepSchema>;
131
170
  export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
132
171
  kind: z.ZodLiteral<"wait">;
133
172
  seconds: z.ZodNumber;
@@ -139,11 +178,46 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
139
178
  cap: z.ZodString;
140
179
  method: z.ZodString;
141
180
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
181
+ }, z.core.$strip>, z.ZodObject<{
182
+ kind: z.ZodLiteral<"action">;
183
+ actionId: z.ZodString;
184
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
142
185
  }, z.core.$strip>, z.ZodObject<{
143
186
  kind: z.ZodLiteral<"code">;
144
187
  code: z.ZodString;
145
188
  }, z.core.$strip>], "kind">;
146
189
  export type AutomationAction = z.infer<typeof AutomationActionSchema>;
190
+ /**
191
+ * How a trigger that arrives while the automation is busy (or cooling down) is
192
+ * handled. One of the automation's execution modes, never a property of its
193
+ * actions. Absent means `single`.
194
+ *
195
+ * - `single` — drop the trigger while a run is in progress (traced + logged).
196
+ * - `restart` — abort the run in progress (at its next step boundary), start fresh.
197
+ * - `queued` — queue up to `max` triggers, drop the rest (traced).
198
+ * - `parallel` — up to `max` runs at once, drop the rest (traced).
199
+ * - `cooldown` — `single`, and no new run until `minutes` after the last run
200
+ * STARTED; persisted across a restart. A manual trigger bypasses only this
201
+ * wait, never the single/queued limits.
202
+ */
203
+ export declare const AutomationRunModeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
204
+ mode: z.ZodLiteral<"single">;
205
+ }, z.core.$strip>, z.ZodObject<{
206
+ mode: z.ZodLiteral<"restart">;
207
+ }, z.core.$strip>, z.ZodObject<{
208
+ mode: z.ZodLiteral<"queued">;
209
+ max: z.ZodNumber;
210
+ }, z.core.$strip>, z.ZodObject<{
211
+ mode: z.ZodLiteral<"parallel">;
212
+ max: z.ZodNumber;
213
+ }, z.core.$strip>, z.ZodObject<{
214
+ mode: z.ZodLiteral<"cooldown">;
215
+ minutes: z.ZodNumber;
216
+ }, z.core.$strip>], "mode">;
217
+ export type AutomationRunMode = z.infer<typeof AutomationRunModeSchema>;
218
+ /** Run traces kept per automation when the recipe does not say. */
219
+ export declare const DEFAULT_TRACE_KEEP = 20;
220
+ export declare const MAX_TRACE_KEEP = 100;
147
221
  export declare const AutomationRecipeSchema: z.ZodObject<{
148
222
  triggers: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
149
223
  kind: z.ZodLiteral<"device-state">;
@@ -163,6 +237,15 @@ export declare const AutomationRecipeSchema: z.ZodObject<{
163
237
  cron: z.ZodString;
164
238
  }, z.core.$strip>, z.ZodObject<{
165
239
  kind: z.ZodLiteral<"manual">;
240
+ }, z.core.$strip>, z.ZodObject<{
241
+ kind: z.ZodLiteral<"detection">;
242
+ classes: z.ZodArray<z.ZodString>;
243
+ deviceIds: z.ZodArray<z.ZodNumber>;
244
+ zones: z.ZodOptional<z.ZodArray<z.ZodString>>;
245
+ minScore: z.ZodOptional<z.ZodNumber>;
246
+ }, z.core.$strip>, z.ZodObject<{
247
+ kind: z.ZodLiteral<"interval">;
248
+ minutes: z.ZodNumber;
166
249
  }, z.core.$strip>], "kind">>;
167
250
  conditions: z.ZodOptional<z.ZodType<AutomationCondition, unknown, z.core.$ZodTypeInternals<AutomationCondition, unknown>>>;
168
251
  actions: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -176,10 +259,29 @@ export declare const AutomationRecipeSchema: z.ZodObject<{
176
259
  cap: z.ZodString;
177
260
  method: z.ZodString;
178
261
  args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
262
+ }, z.core.$strip>, z.ZodObject<{
263
+ kind: z.ZodLiteral<"action">;
264
+ actionId: z.ZodString;
265
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
179
266
  }, z.core.$strip>, z.ZodObject<{
180
267
  kind: z.ZodLiteral<"code">;
181
268
  code: z.ZodString;
182
269
  }, z.core.$strip>], "kind">>;
270
+ runMode: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
271
+ mode: z.ZodLiteral<"single">;
272
+ }, z.core.$strip>, z.ZodObject<{
273
+ mode: z.ZodLiteral<"restart">;
274
+ }, z.core.$strip>, z.ZodObject<{
275
+ mode: z.ZodLiteral<"queued">;
276
+ max: z.ZodNumber;
277
+ }, z.core.$strip>, z.ZodObject<{
278
+ mode: z.ZodLiteral<"parallel">;
279
+ max: z.ZodNumber;
280
+ }, z.core.$strip>, z.ZodObject<{
281
+ mode: z.ZodLiteral<"cooldown">;
282
+ minutes: z.ZodNumber;
283
+ }, z.core.$strip>], "mode">>;
284
+ keepTraces: z.ZodOptional<z.ZodNumber>;
183
285
  }, z.core.$strip>;
184
286
  export type AutomationRecipe = z.infer<typeof AutomationRecipeSchema>;
185
287
  /** Depth of a tree, root container = 1. A bare leaf is depth 1. */
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The admission gate of an automation — what its execution mode decides when a
3
+ * trigger arrives while a run is in progress, and (for `cooldown`) when the
4
+ * last run is too recent.
5
+ *
6
+ * In memory by design (D49): the decision is taken off in-process counters and
7
+ * never off a read that can fail. Only the cooldown's `lastRunStartedAt` is
8
+ * persisted (by the block, through `ctx.storage`) so a restart cannot re-fire
9
+ * inside the window; it is handed in, not read here.
10
+ *
11
+ * Usage: `admit()` once per trigger; every admitted run (`run` / `restart`, or
12
+ * a queued one when it is dequeued) ends with exactly one `release()`, which
13
+ * says whether a queued trigger now owns the freed slot.
14
+ */
15
+ import type { AutomationRunMode } from './recipe.js';
16
+ export interface RunGateAdmission {
17
+ readonly decision: 'run' | 'queued' | 'restart' | 'drop';
18
+ readonly reason: string;
19
+ }
20
+ export interface CooldownInput {
21
+ /** A manual trigger is operator intent: it skips the cooldown wait only. */
22
+ readonly manual: boolean;
23
+ readonly now: number;
24
+ readonly lastRunStartedAt: number | null;
25
+ }
26
+ export interface CooldownVerdict {
27
+ readonly ok: boolean;
28
+ readonly bypassed: boolean;
29
+ readonly reason: string;
30
+ }
31
+ export declare class RunGate {
32
+ private readonly mode;
33
+ private active;
34
+ private pending;
35
+ constructor(mode: AutomationRunMode);
36
+ get activeRuns(): number;
37
+ get queuedTriggers(): number;
38
+ admit(): RunGateAdmission;
39
+ /** The run holding a slot ended (any outcome). True = a queued trigger took the slot. */
40
+ release(): boolean;
41
+ /** Checked AFTER the conditions pass. Always `ok` outside `cooldown` mode. */
42
+ cooldown(input: CooldownInput): CooldownVerdict;
43
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The ONE step runner — shared by an internal Action and by the block an
3
+ * automation recipe compiles to. It is pure: it knows nothing about `ctx`, the
4
+ * hub or a clock beyond the functions it is handed.
5
+ *
6
+ * Contract (the one the NC runner it mirrors set): steps run in order, the
7
+ * sequence STOPS at the first failure (continuing past a failed step executes
8
+ * an intent the operator never expressed), and every step is traced — the ones
9
+ * after a failure, or after an abort, are `not-run` with the reason.
10
+ */
11
+ import type { ActionStep } from './recipe.js';
12
+ import type { AutomationStepTrace } from './trace.js';
13
+ /** Static facts about a step, known before it runs. */
14
+ export interface StepMeta {
15
+ readonly kind: string;
16
+ readonly cap?: string;
17
+ readonly method?: string;
18
+ readonly deviceId?: number;
19
+ }
20
+ /** What a running step can tell the runner (the device a fan-out is on right now). */
21
+ export interface StepScope {
22
+ setDeviceId(deviceId: number): void;
23
+ }
24
+ /** One step as the runner sees it: its meta and a closure that does the work. */
25
+ export interface RunnableStep {
26
+ readonly meta: StepMeta;
27
+ run(scope: StepScope): Promise<void>;
28
+ }
29
+ export interface StepFailure {
30
+ readonly index: number;
31
+ readonly path: string;
32
+ readonly message: string;
33
+ readonly deviceId: number | undefined;
34
+ }
35
+ export interface RunStepsOptions {
36
+ /** `actions` for an automation, `steps` for an Action run. */
37
+ readonly pathPrefix: string;
38
+ /** True once the run was cut short (a restart, a stop). Checked between steps. */
39
+ readonly isAborted: () => boolean;
40
+ readonly abortReason: string;
41
+ readonly now: () => number;
42
+ /** Called once, for the step that failed. */
43
+ readonly onFailure: (failure: StepFailure) => void;
44
+ }
45
+ export interface RunStepsResult {
46
+ readonly steps: readonly AutomationStepTrace[];
47
+ readonly failed: boolean;
48
+ readonly aborted: boolean;
49
+ }
50
+ export declare function runSteps(steps: readonly RunnableStep[], options: RunStepsOptions): Promise<RunStepsResult>;
51
+ /** The bag of values `{ $var }` and `{{vars.x}}` read from. */
52
+ export type StepVars = Readonly<Record<string, unknown>>;
53
+ /**
54
+ * Substitute a step's args from the run's variables. SUBSTITUTION only, never
55
+ * evaluation:
56
+ * - a value that is exactly `{ $var: 'name' }` becomes the variable's value,
57
+ * keeping its type (a number stays a number);
58
+ * - `{{vars.name}}` inside a string becomes its text.
59
+ * A variable that is not set THROWS — a step must not run with a hole where
60
+ * the operator meant a value. (`{{vars.x}}` keeps the automation behaviour:
61
+ * the hole is reported through `onMissing` and rendered empty.)
62
+ */
63
+ export declare function resolveStepArgs(value: unknown, vars: StepVars, onMissing: (name: string) => void): unknown;
64
+ /** A `{ $var }` device target, resolved from the bag BEFORE dispatch. */
65
+ export declare function resolveDeviceTarget(vars: StepVars, name: string): number;
66
+ export interface CapCall {
67
+ readonly deviceId: number;
68
+ readonly cap: string;
69
+ readonly method: string;
70
+ readonly args: Readonly<Record<string, unknown>>;
71
+ }
72
+ export interface ActionStepDeps {
73
+ invokeCap(call: CapCall): Promise<void>;
74
+ sleep(ms: number): Promise<void>;
75
+ onMissingVar(name: string): void;
76
+ }
77
+ /**
78
+ * The runnable form of an internal Action's steps, bound to one run's
79
+ * variables. Variables are substituted per step, at the moment it runs, so a
80
+ * missing one fails THAT step (traced) and leaves the later ones not-run.
81
+ */
82
+ export declare function buildActionSteps(steps: readonly ActionStep[], vars: StepVars, deps: ActionStepDeps): RunnableStep[];
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Run traces — what an automation (or, later, an Action run) DID, node by node,
3
+ * so the editor can paint every block green or red with its reason.
4
+ *
5
+ * A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
6
+ * every condition node (containers and leaves, including the ones a
7
+ * short-circuit never reached), the run-mode verdict and every action step —
8
+ * each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
9
+ * for an Action run). Skipped
10
+ * evaluations are traced too, and identical consecutive skips collapse into a
11
+ * repeat count so a trigger that fails every 5 minutes cannot flush real runs.
12
+ *
13
+ * {@link AutomationStepTraceSchema} is deliberately free of automation
14
+ * vocabulary so an Action run records the same step shape.
15
+ */
16
+ import { z } from 'zod';
17
+ /** A value a trace may show: JSON primitives and short lists, nothing deeper. */
18
+ export declare const TraceValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>;
19
+ export type TraceValue = z.infer<typeof TraceValueSchema>;
20
+ export declare const AutomationRunOutcomeSchema: z.ZodEnum<{
21
+ aborted: "aborted";
22
+ failed: "failed";
23
+ ran: "ran";
24
+ "skipped-conditions": "skipped-conditions";
25
+ "skipped-cooldown": "skipped-cooldown";
26
+ "skipped-overlap": "skipped-overlap";
27
+ "skipped-trigger": "skipped-trigger";
28
+ }>;
29
+ export type AutomationRunOutcome = z.infer<typeof AutomationRunOutcomeSchema>;
30
+ /** `not-evaluated` = a short-circuit never reached the node. */
31
+ export declare const TraceNodeOutcomeSchema: z.ZodEnum<{
32
+ fail: "fail";
33
+ "not-evaluated": "not-evaluated";
34
+ pass: "pass";
35
+ }>;
36
+ export type TraceNodeOutcome = z.infer<typeof TraceNodeOutcomeSchema>;
37
+ export declare const AutomationTriggerTraceSchema: z.ZodObject<{
38
+ kind: z.ZodString;
39
+ outcome: z.ZodEnum<{
40
+ fail: "fail";
41
+ pass: "pass";
42
+ }>;
43
+ reason: z.ZodString;
44
+ vars: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
45
+ }, z.core.$strip>;
46
+ export type AutomationTriggerTrace = z.infer<typeof AutomationTriggerTraceSchema>;
47
+ export declare const AutomationConditionTraceNodeSchema: z.ZodObject<{
48
+ path: z.ZodString;
49
+ kind: z.ZodEnum<{
50
+ all: "all";
51
+ any: "any";
52
+ condition: "condition";
53
+ expression: "expression";
54
+ not: "not";
55
+ }>;
56
+ outcome: z.ZodEnum<{
57
+ fail: "fail";
58
+ "not-evaluated": "not-evaluated";
59
+ pass: "pass";
60
+ }>;
61
+ reason: z.ZodString;
62
+ deviceId: z.ZodOptional<z.ZodNumber>;
63
+ cap: z.ZodOptional<z.ZodString>;
64
+ fieldPath: z.ZodOptional<z.ZodString>;
65
+ operator: z.ZodOptional<z.ZodString>;
66
+ expected: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
67
+ observed: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
68
+ }, z.core.$strip>;
69
+ export type AutomationConditionTraceNode = z.infer<typeof AutomationConditionTraceNodeSchema>;
70
+ export declare const AutomationRunVerdictSchema: z.ZodObject<{
71
+ mode: z.ZodDiscriminatedUnion<[z.ZodObject<{
72
+ mode: z.ZodLiteral<"single">;
73
+ }, z.core.$strip>, z.ZodObject<{
74
+ mode: z.ZodLiteral<"restart">;
75
+ }, z.core.$strip>, z.ZodObject<{
76
+ mode: z.ZodLiteral<"queued">;
77
+ max: z.ZodNumber;
78
+ }, z.core.$strip>, z.ZodObject<{
79
+ mode: z.ZodLiteral<"parallel">;
80
+ max: z.ZodNumber;
81
+ }, z.core.$strip>, z.ZodObject<{
82
+ mode: z.ZodLiteral<"cooldown">;
83
+ minutes: z.ZodNumber;
84
+ }, z.core.$strip>], "mode">;
85
+ decision: z.ZodEnum<{
86
+ bypass: "bypass";
87
+ cooldown: "cooldown";
88
+ drop: "drop";
89
+ queued: "queued";
90
+ restart: "restart";
91
+ run: "run";
92
+ }>;
93
+ reason: z.ZodString;
94
+ }, z.core.$strip>;
95
+ export type AutomationRunVerdict = z.infer<typeof AutomationRunVerdictSchema>;
96
+ /** One executed (or not-run) step — shared by automations and Action runs. */
97
+ export declare const AutomationStepTraceSchema: z.ZodObject<{
98
+ path: z.ZodString;
99
+ kind: z.ZodString;
100
+ cap: z.ZodOptional<z.ZodString>;
101
+ method: z.ZodOptional<z.ZodString>;
102
+ deviceId: z.ZodOptional<z.ZodNumber>;
103
+ startedAt: z.ZodOptional<z.ZodNumber>;
104
+ endedAt: z.ZodOptional<z.ZodNumber>;
105
+ outcome: z.ZodEnum<{
106
+ error: "error";
107
+ "not-run": "not-run";
108
+ ok: "ok";
109
+ }>;
110
+ message: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>;
112
+ export type AutomationStepTrace = z.infer<typeof AutomationStepTraceSchema>;
113
+ export declare const AutomationRunTraceSchema: z.ZodObject<{
114
+ runId: z.ZodString;
115
+ startedAt: z.ZodNumber;
116
+ endedAt: z.ZodNumber;
117
+ trigger: z.ZodObject<{
118
+ kind: z.ZodString;
119
+ outcome: z.ZodEnum<{
120
+ fail: "fail";
121
+ pass: "pass";
122
+ }>;
123
+ reason: z.ZodString;
124
+ vars: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
125
+ }, z.core.$strip>;
126
+ conditions: z.ZodArray<z.ZodObject<{
127
+ path: z.ZodString;
128
+ kind: z.ZodEnum<{
129
+ all: "all";
130
+ any: "any";
131
+ condition: "condition";
132
+ expression: "expression";
133
+ not: "not";
134
+ }>;
135
+ outcome: z.ZodEnum<{
136
+ fail: "fail";
137
+ "not-evaluated": "not-evaluated";
138
+ pass: "pass";
139
+ }>;
140
+ reason: z.ZodString;
141
+ deviceId: z.ZodOptional<z.ZodNumber>;
142
+ cap: z.ZodOptional<z.ZodString>;
143
+ fieldPath: z.ZodOptional<z.ZodString>;
144
+ operator: z.ZodOptional<z.ZodString>;
145
+ expected: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
146
+ observed: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
147
+ }, z.core.$strip>>;
148
+ verdict: z.ZodOptional<z.ZodObject<{
149
+ mode: z.ZodDiscriminatedUnion<[z.ZodObject<{
150
+ mode: z.ZodLiteral<"single">;
151
+ }, z.core.$strip>, z.ZodObject<{
152
+ mode: z.ZodLiteral<"restart">;
153
+ }, z.core.$strip>, z.ZodObject<{
154
+ mode: z.ZodLiteral<"queued">;
155
+ max: z.ZodNumber;
156
+ }, z.core.$strip>, z.ZodObject<{
157
+ mode: z.ZodLiteral<"parallel">;
158
+ max: z.ZodNumber;
159
+ }, z.core.$strip>, z.ZodObject<{
160
+ mode: z.ZodLiteral<"cooldown">;
161
+ minutes: z.ZodNumber;
162
+ }, z.core.$strip>], "mode">;
163
+ decision: z.ZodEnum<{
164
+ bypass: "bypass";
165
+ cooldown: "cooldown";
166
+ drop: "drop";
167
+ queued: "queued";
168
+ restart: "restart";
169
+ run: "run";
170
+ }>;
171
+ reason: z.ZodString;
172
+ }, z.core.$strip>>;
173
+ steps: z.ZodArray<z.ZodObject<{
174
+ path: z.ZodString;
175
+ kind: z.ZodString;
176
+ cap: z.ZodOptional<z.ZodString>;
177
+ method: z.ZodOptional<z.ZodString>;
178
+ deviceId: z.ZodOptional<z.ZodNumber>;
179
+ startedAt: z.ZodOptional<z.ZodNumber>;
180
+ endedAt: z.ZodOptional<z.ZodNumber>;
181
+ outcome: z.ZodEnum<{
182
+ error: "error";
183
+ "not-run": "not-run";
184
+ ok: "ok";
185
+ }>;
186
+ message: z.ZodOptional<z.ZodString>;
187
+ }, z.core.$strip>>;
188
+ outcome: z.ZodEnum<{
189
+ aborted: "aborted";
190
+ failed: "failed";
191
+ ran: "ran";
192
+ "skipped-conditions": "skipped-conditions";
193
+ "skipped-cooldown": "skipped-cooldown";
194
+ "skipped-overlap": "skipped-overlap";
195
+ "skipped-trigger": "skipped-trigger";
196
+ }>;
197
+ repeat: z.ZodNumber;
198
+ lastAt: z.ZodNumber;
199
+ }, z.core.$strip>;
200
+ export type AutomationRunTrace = z.infer<typeof AutomationRunTraceSchema>;
201
+ /**
202
+ * What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
203
+ * `action:<actionId>`): the cooldown stamp and the trace ring.
204
+ */
205
+ export declare const AutomationStateDocSchema: z.ZodObject<{
206
+ version: z.ZodLiteral<1>;
207
+ lastRunStartedAt: z.ZodNullable<z.ZodNumber>;
208
+ traces: z.ZodArray<z.ZodObject<{
209
+ runId: z.ZodString;
210
+ startedAt: z.ZodNumber;
211
+ endedAt: z.ZodNumber;
212
+ trigger: z.ZodObject<{
213
+ kind: z.ZodString;
214
+ outcome: z.ZodEnum<{
215
+ fail: "fail";
216
+ pass: "pass";
217
+ }>;
218
+ reason: z.ZodString;
219
+ vars: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
220
+ }, z.core.$strip>;
221
+ conditions: z.ZodArray<z.ZodObject<{
222
+ path: z.ZodString;
223
+ kind: z.ZodEnum<{
224
+ all: "all";
225
+ any: "any";
226
+ condition: "condition";
227
+ expression: "expression";
228
+ not: "not";
229
+ }>;
230
+ outcome: z.ZodEnum<{
231
+ fail: "fail";
232
+ "not-evaluated": "not-evaluated";
233
+ pass: "pass";
234
+ }>;
235
+ reason: z.ZodString;
236
+ deviceId: z.ZodOptional<z.ZodNumber>;
237
+ cap: z.ZodOptional<z.ZodString>;
238
+ fieldPath: z.ZodOptional<z.ZodString>;
239
+ operator: z.ZodOptional<z.ZodString>;
240
+ expected: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
241
+ observed: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>]>>;
242
+ }, z.core.$strip>>;
243
+ verdict: z.ZodOptional<z.ZodObject<{
244
+ mode: z.ZodDiscriminatedUnion<[z.ZodObject<{
245
+ mode: z.ZodLiteral<"single">;
246
+ }, z.core.$strip>, z.ZodObject<{
247
+ mode: z.ZodLiteral<"restart">;
248
+ }, z.core.$strip>, z.ZodObject<{
249
+ mode: z.ZodLiteral<"queued">;
250
+ max: z.ZodNumber;
251
+ }, z.core.$strip>, z.ZodObject<{
252
+ mode: z.ZodLiteral<"parallel">;
253
+ max: z.ZodNumber;
254
+ }, z.core.$strip>, z.ZodObject<{
255
+ mode: z.ZodLiteral<"cooldown">;
256
+ minutes: z.ZodNumber;
257
+ }, z.core.$strip>], "mode">;
258
+ decision: z.ZodEnum<{
259
+ bypass: "bypass";
260
+ cooldown: "cooldown";
261
+ drop: "drop";
262
+ queued: "queued";
263
+ restart: "restart";
264
+ run: "run";
265
+ }>;
266
+ reason: z.ZodString;
267
+ }, z.core.$strip>>;
268
+ steps: z.ZodArray<z.ZodObject<{
269
+ path: z.ZodString;
270
+ kind: z.ZodString;
271
+ cap: z.ZodOptional<z.ZodString>;
272
+ method: z.ZodOptional<z.ZodString>;
273
+ deviceId: z.ZodOptional<z.ZodNumber>;
274
+ startedAt: z.ZodOptional<z.ZodNumber>;
275
+ endedAt: z.ZodOptional<z.ZodNumber>;
276
+ outcome: z.ZodEnum<{
277
+ error: "error";
278
+ "not-run": "not-run";
279
+ ok: "ok";
280
+ }>;
281
+ message: z.ZodOptional<z.ZodString>;
282
+ }, z.core.$strip>>;
283
+ outcome: z.ZodEnum<{
284
+ aborted: "aborted";
285
+ failed: "failed";
286
+ ran: "ran";
287
+ "skipped-conditions": "skipped-conditions";
288
+ "skipped-cooldown": "skipped-cooldown";
289
+ "skipped-overlap": "skipped-overlap";
290
+ "skipped-trigger": "skipped-trigger";
291
+ }>;
292
+ repeat: z.ZodNumber;
293
+ lastAt: z.ZodNumber;
294
+ }, z.core.$strip>>;
295
+ }, z.core.$strip>;
296
+ export type AutomationStateDoc = z.infer<typeof AutomationStateDocSchema>;
297
+ /** The state of an owner that never reported. */
298
+ export declare const EMPTY_AUTOMATION_STATE: AutomationStateDoc;
299
+ export declare function isSkippedTrace(trace: AutomationRunTrace): boolean;
300
+ /** Two skips with the same signature are the same event repeating. */
301
+ export declare function skipSignature(trace: AutomationRunTrace): string;
302
+ /**
303
+ * `next` folded into `prev` when both are skips of the same signature (the
304
+ * repeat count and the latest time move on), else null. Used by the block
305
+ * BEFORE it sends, so a trigger that fails every few seconds costs one RPC per
306
+ * flush, not one per skip; the ledger applies the same rule through
307
+ * {@link appendTrace}.
308
+ */
309
+ export declare function mergeSkipTraces(prev: AutomationRunTrace, next: AutomationRunTrace): AutomationRunTrace | null;
310
+ /**
311
+ * Append a trace to a ring of at most `keep` entries, without mutating it.
312
+ *
313
+ * - A skip identical to the previous trace is counted on that trace
314
+ * (`repeat`, `lastAt`), not appended.
315
+ * - When the ring is full, the oldest SKIPPED trace goes first; a real run is
316
+ * evicted only when every trace is a run. A noisy skip stream therefore
317
+ * cannot push the runs the operator is looking for out of the ring.
318
+ */
319
+ export declare function appendTrace(ring: readonly AutomationRunTrace[], trace: AutomationRunTrace, keep: number): AutomationRunTrace[];
320
+ /**
321
+ * The trigger stage of a trace from the bag a trigger handed to `run()`:
322
+ * primitives only (a device-state `to` that is an object is left out), minus the
323
+ * bookkeeping keys `kind` and `at`.
324
+ */
325
+ export declare function buildTriggerTrace(trigger: Readonly<Record<string, unknown>>, outcome: 'pass' | 'fail', reason: string): AutomationTriggerTrace;
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ import { type InferProvider } from './capability-definition.js';
3
+ /**
4
+ * action-source — an addon DECLARES runnable actions (a Home Assistant script,
5
+ * a scene, a vendor routine) as list entries. Never as devices.
6
+ *
7
+ * It mirrors `notification-output`: `listActions` returns an array, so the
8
+ * generated cap mount concat-fans it across every provider; `runAction` and
9
+ * `stopAction` route to ONE provider by the `addonId` the generated collection
10
+ * router extracts from the call input.
11
+ *
12
+ * Nobody but the `actions` surface (the core-blocks builtin) calls this cap.
13
+ * The UI and automations talk to `actions`, which fans out here LIVE on every
14
+ * `list` and keeps no catalog of its own (D3: no shadow registry).
15
+ *
16
+ * `listActions` entries carry `source: 'addon'`, `readOnly: true`, an id of
17
+ * `<addonId>:<localId>` and an idle `status` (the provider may fill what it
18
+ * knows). `actionId` on `runAction` / `stopAction` is the full entry id.
19
+ */
20
+ export declare const actionSourceCapability: {
21
+ readonly name: 'action-source';
22
+ readonly scope: 'system';
23
+ readonly mode: 'collection';
24
+ readonly methods: {
25
+ readonly listActions: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
26
+ id: z.ZodString;
27
+ name: z.ZodString;
28
+ addonId: z.ZodString;
29
+ source: z.ZodEnum<{
30
+ addon: "addon";
31
+ internal: "internal";
32
+ }>;
33
+ readOnly: z.ZodBoolean;
34
+ steps: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
35
+ kind: z.ZodLiteral<"wait">;
36
+ seconds: z.ZodNumber;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ kind: z.ZodLiteral<"cap">;
39
+ deviceId: z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>, z.ZodObject<{
40
+ $var: z.ZodString;
41
+ }, z.core.$strip>]>;
42
+ cap: z.ZodString;
43
+ method: z.ZodString;
44
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
+ }, z.core.$strip>], "kind">>>;
46
+ variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
47
+ name: z.ZodString;
48
+ label: z.ZodOptional<z.ZodString>;
49
+ type: z.ZodEnum<{
50
+ boolean: "boolean";
51
+ number: "number";
52
+ select: "select";
53
+ string: "string";
54
+ }>;
55
+ required: z.ZodOptional<z.ZodBoolean>;
56
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
57
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
58
+ }, z.core.$strip>>>;
59
+ status: z.ZodObject<{
60
+ isRunning: z.ZodBoolean;
61
+ lastRunAt: z.ZodNullable<z.ZodNumber>;
62
+ lastError: z.ZodNullable<z.ZodString>;
63
+ }, z.core.$strip>;
64
+ }, z.core.$strip>>, import("./capability-definition.js").CapabilityMethodKind>;
65
+ readonly runAction: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
66
+ actionId: z.ZodString;
67
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
68
+ }, z.core.$strip>, z.ZodVoid, "mutation">;
69
+ readonly stopAction: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
70
+ actionId: z.ZodString;
71
+ }, z.core.$strip>, z.ZodVoid, "mutation">;
72
+ };
73
+ };
74
+ export type IActionSourceProvider = InferProvider<typeof actionSourceCapability>;