@camstack/addon-model-studio 1.1.309 → 1.1.311

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 (19) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{MotionZonesSettings-D9qlMn0i.mjs → MotionZonesSettings-CY7WW9zp.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-BgJSIubF.mjs → PrivacyMaskSettings-D4hM1OZ1.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-CZzBhOoI.mjs → SceneMonitorEditor-CYO0M61_.mjs} +3 -3
  5. package/dist/_stub.js +622 -620
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Ca8KtYYT.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-i6GpUg0g.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CGOQ_bPs.mjs +26 -0
  8. package/dist/{hostInit-C4p0TGqg.mjs → hostInit-DMdFkiuC.mjs} +2 -2
  9. package/dist/model-studio.addon.js +649 -70
  10. package/dist/model-studio.addon.mjs +649 -70
  11. package/dist/{player-overlays-C1od7kvL.mjs → player-overlays-_IUEss_N.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-IwU1xXrH.mjs → responsive-BipqhGVu.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-B_r_xdlw.mjs → scene-monitor-copy-ByM_3HsW.mjs} +1 -1
  15. package/dist/{square-cXunBHEd.mjs → square-ChGVX2QG.mjs} +1 -1
  16. package/dist/{trash-2-CZlLF-tK.mjs → trash-2-7FeqzbpL.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CGN2iLLF.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-mVC2N4ad.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CD8IeDkZ.mjs +0 -26
@@ -368,7 +368,7 @@ function buildPluginCatalogRegistryDescriptor(entry) {
368
368
  };
369
369
  }
370
370
  //#endregion
371
- //#region ../types/dist/event-category-CT-hz5Rb.mjs
371
+ //#region ../types/dist/event-category-hdMR7CTW.mjs
372
372
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
373
373
  EventCategory["SystemBoot"] = "system.boot";
374
374
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1133,6 +1133,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1133
1133
  */
1134
1134
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
1135
1135
  /**
1136
+ * An action run started or ended. Emitted by the `actions` surface.
1137
+ * Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
1138
+ */
1139
+ EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
1140
+ /**
1136
1141
  * Progress update from a running model conversion job.
1137
1142
  * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
1138
1143
  * Emitted by `addon-model-studio` on the converting node.
@@ -5811,7 +5816,7 @@ var ZodIssueCode = {
5811
5816
  var ZodFirstPartyTypeKind;
5812
5817
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5813
5818
  //#endregion
5814
- //#region ../types/dist/sleep-BE7IAR2p.mjs
5819
+ //#region ../types/dist/sleep-BHjNez61.mjs
5815
5820
  /**
5816
5821
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5817
5822
  * window to float samples (D455).
@@ -8941,6 +8946,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
8941
8946
  /** Every capability name, so addon code can check a name without the schema graph. */
8942
8947
  var CAP_NAMES = Object.freeze([
8943
8948
  "accessories",
8949
+ "action-source",
8950
+ "actions",
8944
8951
  "addon-pages",
8945
8952
  "addon-pages-source",
8946
8953
  "addon-routes",
@@ -15940,7 +15947,23 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
15940
15947
  kind: literal("schedule"),
15941
15948
  cron: string().min(1).max(120)
15942
15949
  }),
15943
- object({ kind: literal("manual") })
15950
+ object({ kind: literal("manual") }),
15951
+ object({
15952
+ kind: literal("detection"),
15953
+ /** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
15954
+ * matches every raw class that maps to it; any other name matches
15955
+ * exactly. */
15956
+ classes: array(string().min(1)).min(1),
15957
+ deviceIds: array(number().int().nonnegative()).min(1),
15958
+ /** The track must have visited at least one of these zones. */
15959
+ zones: array(string().min(1)).min(1).optional(),
15960
+ /** Best-so-far confidence the track must reach. */
15961
+ minScore: number().min(0).max(1).optional()
15962
+ }),
15963
+ object({
15964
+ kind: literal("interval"),
15965
+ minutes: number().int().min(1).max(1440)
15966
+ })
15944
15967
  ]);
15945
15968
  /**
15946
15969
  * One action step.
@@ -15960,28 +15983,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
15960
15983
  * is called. The runner still receives a number and is untouched; the
15961
15984
  * resolution is the recipe's job, not the runner's.
15962
15985
  */
15986
+ var AutomationWaitStepSchema = object({
15987
+ kind: literal("wait"),
15988
+ seconds: number().min(0).max(300)
15989
+ });
15990
+ var AutomationCapStepSchema = object({
15991
+ kind: literal("cap"),
15992
+ /**
15993
+ * One device, several same-family devices (locks / climate family / …),
15994
+ * or `{ $var }` for the device that triggered the run. An array is
15995
+ * fan-out at codegen — each id gets the same cap.method call.
15996
+ */
15997
+ deviceId: union([
15998
+ number().int(),
15999
+ array(number().int()).min(1),
16000
+ object({ $var: string().min(1) })
16001
+ ]),
16002
+ cap: string().min(1),
16003
+ method: string().min(1),
16004
+ /** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
16005
+ * SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
16006
+ * the expression leaf. */
16007
+ args: record(string(), unknown()).optional()
16008
+ });
16009
+ /**
16010
+ * The steps an internal Action may contain: cap and wait, and nothing that can
16011
+ * call back into an Action — so an Action can never reach itself (no cycles).
16012
+ */
16013
+ var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
15963
16014
  var AutomationActionSchema = discriminatedUnion("kind", [
16015
+ AutomationWaitStepSchema,
16016
+ AutomationCapStepSchema,
15964
16017
  object({
15965
- kind: literal("wait"),
15966
- seconds: number().min(0).max(300)
15967
- }),
15968
- object({
15969
- kind: literal("cap"),
15970
- /**
15971
- * One device, several same-family devices (locks / climate family / …),
15972
- * or `{ $var }` for the device that triggered the run. An array is
15973
- * fan-out at codegen — each id gets the same cap.method call.
15974
- */
15975
- deviceId: union([
15976
- number().int(),
15977
- array(number().int()).min(1),
15978
- object({ $var: string().min(1) })
15979
- ]),
15980
- cap: string().min(1),
15981
- method: string().min(1),
15982
- /** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
15983
- * evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
15984
- args: record(string(), unknown()).optional()
16018
+ kind: literal("action"),
16019
+ /** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
16020
+ actionId: string().min(1),
16021
+ /** Values for the action's declared variables; the others take their default. */
16022
+ variables: record(string(), union([
16023
+ string(),
16024
+ number(),
16025
+ boolean()
16026
+ ])).optional()
15985
16027
  }),
15986
16028
  object({
15987
16029
  kind: literal("code"),
@@ -15990,10 +16032,356 @@ var AutomationActionSchema = discriminatedUnion("kind", [
15990
16032
  code: string().min(1).max(2e4)
15991
16033
  })
15992
16034
  ]);
16035
+ /**
16036
+ * How a trigger that arrives while the automation is busy (or cooling down) is
16037
+ * handled. One of the automation's execution modes, never a property of its
16038
+ * actions. Absent means `single`.
16039
+ *
16040
+ * - `single` — drop the trigger while a run is in progress (traced + logged).
16041
+ * - `restart` — abort the run in progress (at its next step boundary), start fresh.
16042
+ * - `queued` — queue up to `max` triggers, drop the rest (traced).
16043
+ * - `parallel` — up to `max` runs at once, drop the rest (traced).
16044
+ * - `cooldown` — `single`, and no new run until `minutes` after the last run
16045
+ * STARTED; persisted across a restart. A manual trigger bypasses only this
16046
+ * wait, never the single/queued limits.
16047
+ */
16048
+ var AutomationRunModeSchema = discriminatedUnion("mode", [
16049
+ object({ mode: literal("single") }),
16050
+ object({ mode: literal("restart") }),
16051
+ object({
16052
+ mode: literal("queued"),
16053
+ max: number().int().min(1).max(10)
16054
+ }),
16055
+ object({
16056
+ mode: literal("parallel"),
16057
+ max: number().int().min(1).max(10)
16058
+ }),
16059
+ object({
16060
+ mode: literal("cooldown"),
16061
+ minutes: number().int().min(1).max(1440)
16062
+ })
16063
+ ]);
15993
16064
  var AutomationRecipeSchema = object({
15994
16065
  triggers: array(AutomationTriggerSchema),
15995
16066
  conditions: AutomationConditionSchema.optional(),
15996
- actions: array(AutomationActionSchema)
16067
+ actions: array(AutomationActionSchema),
16068
+ runMode: AutomationRunModeSchema.optional(),
16069
+ /** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
16070
+ keepTraces: number().int().min(1).max(100).optional()
16071
+ });
16072
+ new Set([
16073
+ {
16074
+ id: "person",
16075
+ name: "Person"
16076
+ },
16077
+ {
16078
+ id: "vehicle",
16079
+ name: "Vehicle"
16080
+ },
16081
+ {
16082
+ id: "animal",
16083
+ name: "Animal"
16084
+ },
16085
+ {
16086
+ id: "package",
16087
+ name: "Package"
16088
+ }
16089
+ ].map((l) => l.id));
16090
+ var COCO_TO_MACRO = {
16091
+ mapping: {
16092
+ person: "person",
16093
+ bicycle: "vehicle",
16094
+ car: "vehicle",
16095
+ motorcycle: "vehicle",
16096
+ airplane: "vehicle",
16097
+ bus: "vehicle",
16098
+ train: "vehicle",
16099
+ truck: "vehicle",
16100
+ boat: "vehicle",
16101
+ bird: "animal",
16102
+ cat: "animal",
16103
+ dog: "animal",
16104
+ horse: "animal",
16105
+ sheep: "animal",
16106
+ cow: "animal",
16107
+ elephant: "animal",
16108
+ bear: "animal",
16109
+ zebra: "animal",
16110
+ giraffe: "animal",
16111
+ suitcase: "package",
16112
+ backpack: "package",
16113
+ handbag: "package"
16114
+ },
16115
+ preserveOriginal: false
16116
+ };
16117
+ new Set(Object.values(COCO_TO_MACRO.mapping));
16118
+ /**
16119
+ * Run traces — what an automation (or, later, an Action run) DID, node by node,
16120
+ * so the editor can paint every block green or red with its reason.
16121
+ *
16122
+ * A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
16123
+ * every condition node (containers and leaves, including the ones a
16124
+ * short-circuit never reached), the run-mode verdict and every action step —
16125
+ * each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
16126
+ * for an Action run). Skipped
16127
+ * evaluations are traced too, and identical consecutive skips collapse into a
16128
+ * repeat count so a trigger that fails every 5 minutes cannot flush real runs.
16129
+ *
16130
+ * {@link AutomationStepTraceSchema} is deliberately free of automation
16131
+ * vocabulary so an Action run records the same step shape.
16132
+ */
16133
+ /** A value a trace may show: JSON primitives and short lists, nothing deeper. */
16134
+ var TraceValueSchema = union([
16135
+ string(),
16136
+ number(),
16137
+ boolean(),
16138
+ _null(),
16139
+ array(union([string(), number()]))
16140
+ ]);
16141
+ var AutomationRunOutcomeSchema = _enum([
16142
+ "ran",
16143
+ "skipped-trigger",
16144
+ "skipped-conditions",
16145
+ "skipped-cooldown",
16146
+ "skipped-overlap",
16147
+ "failed",
16148
+ "aborted"
16149
+ ]);
16150
+ /** `not-evaluated` = a short-circuit never reached the node. */
16151
+ var TraceNodeOutcomeSchema = _enum([
16152
+ "pass",
16153
+ "fail",
16154
+ "not-evaluated"
16155
+ ]);
16156
+ var AutomationTriggerTraceSchema = object({
16157
+ kind: string().min(1),
16158
+ outcome: _enum(["pass", "fail"]),
16159
+ /** Why an event was rejected ("class person not in [dog]") or what fired. */
16160
+ reason: string(),
16161
+ /** deviceId, className, trackId, score … — only what the trigger exposes. */
16162
+ vars: record(string(), TraceValueSchema)
16163
+ });
16164
+ var AutomationConditionTraceNodeSchema = object({
16165
+ /** `conditions` for the root, `conditions.<i>` for its i-th child, … */
16166
+ path: string().min(1),
16167
+ kind: _enum([
16168
+ "all",
16169
+ "any",
16170
+ "not",
16171
+ "condition",
16172
+ "expression"
16173
+ ]),
16174
+ outcome: TraceNodeOutcomeSchema,
16175
+ reason: string(),
16176
+ deviceId: number().int().optional(),
16177
+ cap: string().optional(),
16178
+ fieldPath: string().optional(),
16179
+ operator: string().optional(),
16180
+ expected: TraceValueSchema.optional(),
16181
+ /** What the mirror held; `null` when it held nothing (unknown). */
16182
+ observed: TraceValueSchema.optional()
16183
+ });
16184
+ var AutomationRunVerdictSchema = object({
16185
+ mode: AutomationRunModeSchema,
16186
+ decision: _enum([
16187
+ "run",
16188
+ "queued",
16189
+ "restart",
16190
+ "drop",
16191
+ "cooldown",
16192
+ "bypass"
16193
+ ]),
16194
+ reason: string()
16195
+ });
16196
+ /** One executed (or not-run) step — shared by automations and Action runs. */
16197
+ var AutomationStepTraceSchema = object({
16198
+ /** `actions.<i>` */
16199
+ path: string().min(1),
16200
+ kind: string().min(1),
16201
+ cap: string().optional(),
16202
+ method: string().optional(),
16203
+ deviceId: number().int().optional(),
16204
+ startedAt: number().optional(),
16205
+ endedAt: number().optional(),
16206
+ outcome: _enum([
16207
+ "ok",
16208
+ "error",
16209
+ "not-run"
16210
+ ]),
16211
+ message: string().optional()
16212
+ });
16213
+ var AutomationRunTraceSchema = object({
16214
+ runId: string().min(1),
16215
+ startedAt: number(),
16216
+ endedAt: number(),
16217
+ trigger: AutomationTriggerTraceSchema,
16218
+ conditions: array(AutomationConditionTraceNodeSchema),
16219
+ verdict: AutomationRunVerdictSchema.optional(),
16220
+ steps: array(AutomationStepTraceSchema),
16221
+ outcome: AutomationRunOutcomeSchema,
16222
+ /** How many identical consecutive skips this trace stands for (>= 1). */
16223
+ repeat: number().int().min(1),
16224
+ /** When the latest of those repeats happened. */
16225
+ lastAt: number()
16226
+ });
16227
+ /**
16228
+ * What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
16229
+ * `action:<actionId>`): the cooldown stamp and the trace ring.
16230
+ */
16231
+ var AutomationStateDocSchema = object({
16232
+ version: literal(1),
16233
+ lastRunStartedAt: number().nullable(),
16234
+ traces: array(AutomationRunTraceSchema)
16235
+ });
16236
+ /**
16237
+ * Actions — named, runnable things an operator (or an automation) can start,
16238
+ * declared as LIST ENTRIES, never as devices.
16239
+ *
16240
+ * An entry is either **internal** (a short list of cap/wait steps kept in the
16241
+ * hub's `actions` record kind) or declared by an addon through the
16242
+ * `action-source` collection (a Home Assistant script, a scene …). The one
16243
+ * surface the UI and automations talk to is the `actions` cap; it keeps no
16244
+ * catalog of its own (D3) — every `list` asks the providers live.
16245
+ *
16246
+ * This file is the data half: the entry schema, the variables an entry may
16247
+ * declare, and the pure resolution of the values a run was given. It holds no
16248
+ * runtime.
16249
+ */
16250
+ /** What a variable's value is. `select` takes one of `options`. */
16251
+ var ActionVariableTypeSchema = _enum([
16252
+ "string",
16253
+ "number",
16254
+ "boolean",
16255
+ "select"
16256
+ ]);
16257
+ var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
16258
+ var ActionVariableValueSchema = union([
16259
+ string(),
16260
+ number(),
16261
+ boolean()
16262
+ ]);
16263
+ /**
16264
+ * One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
16265
+ * value) or `{{vars.name}}` (inside a string) in their args.
16266
+ */
16267
+ var ActionVariableSchema = object({
16268
+ name: string().regex(ACTION_VARIABLE_NAME_RE),
16269
+ label: string().min(1).max(120).optional(),
16270
+ type: ActionVariableTypeSchema,
16271
+ required: boolean().optional(),
16272
+ default: ActionVariableValueSchema.optional(),
16273
+ /** The allowed values of a `select`. */
16274
+ options: array(string().min(1)).min(1).optional()
16275
+ }).superRefine((v, ctx) => {
16276
+ if (v.type === "select" && v.options === void 0) ctx.addIssue({
16277
+ code: "custom",
16278
+ message: "a select variable needs options",
16279
+ path: ["options"]
16280
+ });
16281
+ if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
16282
+ code: "custom",
16283
+ message: variableValueError(v, v.default) ?? "invalid default",
16284
+ path: ["default"]
16285
+ });
16286
+ });
16287
+ /** Why `value` is not a legal value for the variable, or null when it is. */
16288
+ function variableValueError(variable, value) {
16289
+ switch (variable.type) {
16290
+ case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
16291
+ case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
16292
+ case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
16293
+ case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
16294
+ }
16295
+ }
16296
+ var ActionSourceKindSchema = _enum(["internal", "addon"]);
16297
+ function isInternalActionId(actionId) {
16298
+ return actionId.startsWith("internal:") && actionId.length > 9;
16299
+ }
16300
+ /** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
16301
+ function addonIdOfActionId(actionId) {
16302
+ if (isInternalActionId(actionId)) return null;
16303
+ const at = actionId.indexOf(":");
16304
+ return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
16305
+ }
16306
+ var ActionStatusSchema = object({
16307
+ isRunning: boolean(),
16308
+ /** Ms epoch the latest run STARTED; null when it never ran. */
16309
+ lastRunAt: number().nullable(),
16310
+ /** The latest run's failure; null on success or when it never ran. */
16311
+ lastError: string().nullable()
16312
+ });
16313
+ var ActionEntrySchema = object({
16314
+ /** `internal:<uuid>` or `<addonId>:<localId>`. */
16315
+ id: string().min(3),
16316
+ name: string().min(1).max(120),
16317
+ /** The addon that declared it; `core-blocks` for an internal one. */
16318
+ addonId: string().min(1),
16319
+ source: ActionSourceKindSchema,
16320
+ /** An addon-declared entry is edited where it was declared. */
16321
+ readOnly: boolean(),
16322
+ /** Internal only: cap and wait steps. No action-in-action, so no cycles. */
16323
+ steps: array(ActionStepSchema).min(1).max(50).optional(),
16324
+ variables: array(ActionVariableSchema).max(20).optional(),
16325
+ status: ActionStatusSchema
16326
+ }).superRefine((entry, ctx) => {
16327
+ if (entry.source === "internal") {
16328
+ if (!isInternalActionId(entry.id)) ctx.addIssue({
16329
+ code: "custom",
16330
+ message: "an internal action id is internal:<uuid>",
16331
+ path: ["id"]
16332
+ });
16333
+ return;
16334
+ }
16335
+ if (entry.steps !== void 0) ctx.addIssue({
16336
+ code: "custom",
16337
+ message: "only an internal action carries steps",
16338
+ path: ["steps"]
16339
+ });
16340
+ if (!entry.readOnly) ctx.addIssue({
16341
+ code: "custom",
16342
+ message: "an addon action is read-only here",
16343
+ path: ["readOnly"]
16344
+ });
16345
+ if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
16346
+ code: "custom",
16347
+ message: "an addon action id is <addonId>:<localId>",
16348
+ path: ["id"]
16349
+ });
16350
+ });
16351
+ /** What an operator writes for an internal action. */
16352
+ var ActionInputSchema = object({
16353
+ name: string().min(1).max(120),
16354
+ steps: array(ActionStepSchema).min(1).max(50),
16355
+ variables: array(ActionVariableSchema).max(20).optional()
16356
+ });
16357
+ /** Who started a run. Absent = the operator pressed it. */
16358
+ var ActionRunOriginSchema = object({
16359
+ /** The automation block whose step started it. */
16360
+ blockId: string().min(1).optional() });
16361
+ /** `started` = the caller did not ask to wait. */
16362
+ var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
16363
+ var ActionRunResultSchema = object({
16364
+ runId: string().min(1),
16365
+ outcome: ActionRunOutcomeSchema,
16366
+ /** Why it did not run, or what failed. */
16367
+ message: string().optional()
16368
+ });
16369
+ _enum([
16370
+ "not-found",
16371
+ "read-only",
16372
+ "invalid-variables",
16373
+ "invalid-steps",
16374
+ "not-linked",
16375
+ "busy"
16376
+ ]);
16377
+ object({
16378
+ actionId: string(),
16379
+ runId: string(),
16380
+ isRunning: boolean(),
16381
+ /** Set when the run ended. */
16382
+ outcome: AutomationRunOutcomeSchema.optional(),
16383
+ lastRunAt: number().nullable(),
16384
+ lastError: string().nullable()
15997
16385
  });
15998
16386
  /**
15999
16387
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
@@ -19554,7 +19942,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
19554
19942
  kind: "mutation",
19555
19943
  auth: "admin",
19556
19944
  access: "view"
19557
- });
19945
+ }), method(object({
19946
+ blockId: string().min(1),
19947
+ trace: AutomationRunTraceSchema.optional(),
19948
+ runStartedAt: number().optional(),
19949
+ keepTraces: number().int().min(1).max(100).optional()
19950
+ }), _void(), {
19951
+ kind: "mutation",
19952
+ auth: "admin"
19953
+ }), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
19954
+ traces: array(AutomationRunTraceSchema),
19955
+ lastError: string().nullable()
19956
+ }), { auth: "admin" });
19558
19957
  /**
19559
19958
  * `custom-model-registry` — collection cap exposing operator-registered
19560
19959
  * custom detection models. Each provider (today: `addon-model-studio`)
@@ -44681,51 +45080,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
44681
45080
  kind: "mutation",
44682
45081
  auth: "admin"
44683
45082
  });
44684
- new Set([
44685
- {
44686
- id: "person",
44687
- name: "Person"
44688
- },
44689
- {
44690
- id: "vehicle",
44691
- name: "Vehicle"
44692
- },
44693
- {
44694
- id: "animal",
44695
- name: "Animal"
44696
- },
44697
- {
44698
- id: "package",
44699
- name: "Package"
44700
- }
44701
- ].map((l) => l.id));
44702
- var COCO_TO_MACRO = {
44703
- mapping: {
44704
- person: "person",
44705
- bicycle: "vehicle",
44706
- car: "vehicle",
44707
- motorcycle: "vehicle",
44708
- airplane: "vehicle",
44709
- bus: "vehicle",
44710
- train: "vehicle",
44711
- truck: "vehicle",
44712
- boat: "vehicle",
44713
- bird: "animal",
44714
- cat: "animal",
44715
- dog: "animal",
44716
- horse: "animal",
44717
- sheep: "animal",
44718
- cow: "animal",
44719
- elephant: "animal",
44720
- bear: "animal",
44721
- zebra: "animal",
44722
- giraffe: "animal",
44723
- suitcase: "package",
44724
- backpack: "package",
44725
- handbag: "package"
44726
- },
44727
- preserveOriginal: false
44728
- };
44729
45083
  var AUDIO_MACRO_LABELS = [
44730
45084
  {
44731
45085
  id: "speech",
@@ -57274,6 +57628,84 @@ DeviceType.Camera, method(object({ deviceId: number() }), AudioMetricsSnapshotSc
57274
57628
  * would produce more than `maxPoints` samples. */
57275
57629
  sampleEveryMs: number().int().positive().optional()
57276
57630
  }), AudioMetricsHistorySchema);
57631
+ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
57632
+ actionId: string().min(1),
57633
+ variables: record(string(), ActionVariableValueSchema).optional()
57634
+ }), _void(), {
57635
+ kind: "mutation",
57636
+ auth: "admin"
57637
+ }), method(object({ actionId: string().min(1) }), _void(), {
57638
+ kind: "mutation",
57639
+ auth: "admin"
57640
+ });
57641
+ /**
57642
+ * actions — the ONE surface for runnable actions, for the UI and for
57643
+ * automations. Provided by the core-blocks builtin on the hub.
57644
+ *
57645
+ * An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
57646
+ * steps, kept in the hub's `actions` record kind) or declared by an addon over
57647
+ * `action-source`. `list` asks every `action-source` provider LIVE and overlays
57648
+ * the run status from the hub's `runs` ledger; there is no catalog here to
57649
+ * drift (D3).
57650
+ *
57651
+ * **Permissions follow the camera, as linked devices do.** An action is linked
57652
+ * to cameras by the operator (`setLinks`, D356: nothing links itself). A
57653
+ * non-admin may `get` / `run` an action only through a camera they may see that
57654
+ * links it: they name the camera (`deviceId`, a top-level field so the scope
57655
+ * gate sees it) and the provider refuses an action that camera does not link.
57656
+ * An admin, and an in-process caller (an automation block), may run any action.
57657
+ * Every refusal is typed (`[not-linked] …`) and logged.
57658
+ *
57659
+ * A second `run` of an action that is already running is REFUSED — traced and
57660
+ * logged — never queued.
57661
+ */
57662
+ var ActionIdInput = object({ actionId: string().min(1) });
57663
+ var ActionLinksSchema = object({
57664
+ deviceId: number().int().nonnegative(),
57665
+ actionIds: array(string().min(1)).max(100)
57666
+ });
57667
+ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
57668
+ actionId: string().min(1),
57669
+ deviceId: number().int().nonnegative().optional()
57670
+ }), object({ action: ActionEntrySchema.nullable() }), {
57671
+ role: "viewer",
57672
+ auth: "protected",
57673
+ kind: "query",
57674
+ caller: "required"
57675
+ }), method(object({
57676
+ actionId: string().min(1),
57677
+ variables: record(string(), ActionVariableValueSchema).optional(),
57678
+ wait: boolean().optional(),
57679
+ origin: ActionRunOriginSchema.optional(),
57680
+ deviceId: number().int().nonnegative().optional()
57681
+ }), ActionRunResultSchema, {
57682
+ role: "viewer",
57683
+ auth: "protected",
57684
+ kind: "mutation",
57685
+ caller: "required"
57686
+ }), method(ActionIdInput, _void(), {
57687
+ kind: "mutation",
57688
+ auth: "admin"
57689
+ }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
57690
+ kind: "mutation",
57691
+ auth: "admin"
57692
+ }), method(object({
57693
+ actionId: string().min(1),
57694
+ action: ActionInputSchema.partial()
57695
+ }), object({ action: ActionEntrySchema }), {
57696
+ kind: "mutation",
57697
+ auth: "admin"
57698
+ }), method(ActionIdInput, _void(), {
57699
+ kind: "mutation",
57700
+ auth: "admin"
57701
+ }), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
57702
+ role: "viewer",
57703
+ auth: "protected",
57704
+ kind: "query"
57705
+ }), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
57706
+ kind: "mutation",
57707
+ auth: "admin"
57708
+ });
57277
57709
  object({
57278
57710
  /** Whether the automation is currently enabled. Disabled automations
57279
57711
  * ignore their trigger block — manual `trigger` still works. */
@@ -66387,6 +66819,104 @@ Object.freeze({
66387
66819
  access: "create",
66388
66820
  role: "admin"
66389
66821
  },
66822
+ "actions.create": {
66823
+ capName: "actions",
66824
+ capScope: "system",
66825
+ addonId: null,
66826
+ access: "create",
66827
+ role: "admin"
66828
+ },
66829
+ "actions.delete": {
66830
+ capName: "actions",
66831
+ capScope: "system",
66832
+ addonId: null,
66833
+ access: "delete",
66834
+ role: "admin"
66835
+ },
66836
+ "actions.get": {
66837
+ capName: "actions",
66838
+ capScope: "system",
66839
+ addonId: null,
66840
+ access: "view",
66841
+ role: "viewer"
66842
+ },
66843
+ "actions.getLinks": {
66844
+ capName: "actions",
66845
+ capScope: "system",
66846
+ addonId: null,
66847
+ access: "view",
66848
+ role: "admin"
66849
+ },
66850
+ "actions.getTraces": {
66851
+ capName: "actions",
66852
+ capScope: "system",
66853
+ addonId: null,
66854
+ access: "view",
66855
+ role: "admin"
66856
+ },
66857
+ "actions.list": {
66858
+ capName: "actions",
66859
+ capScope: "system",
66860
+ addonId: null,
66861
+ access: "view",
66862
+ role: "admin"
66863
+ },
66864
+ "actions.listForCamera": {
66865
+ capName: "actions",
66866
+ capScope: "system",
66867
+ addonId: null,
66868
+ access: "view",
66869
+ role: "viewer"
66870
+ },
66871
+ "actions.run": {
66872
+ capName: "actions",
66873
+ capScope: "system",
66874
+ addonId: null,
66875
+ access: "create",
66876
+ role: "viewer"
66877
+ },
66878
+ "actions.setLinks": {
66879
+ capName: "actions",
66880
+ capScope: "system",
66881
+ addonId: null,
66882
+ access: "create",
66883
+ role: "admin"
66884
+ },
66885
+ "actions.stop": {
66886
+ capName: "actions",
66887
+ capScope: "system",
66888
+ addonId: null,
66889
+ access: "create",
66890
+ role: "admin"
66891
+ },
66892
+ "actions.update": {
66893
+ capName: "actions",
66894
+ capScope: "system",
66895
+ addonId: null,
66896
+ access: "create",
66897
+ role: "admin"
66898
+ },
66899
+ "actionSource.listActions": {
66900
+ capName: "action-source",
66901
+ capScope: "system",
66902
+ addonId: null,
66903
+ access: "view",
66904
+ role: "admin"
66905
+ },
66906
+ "actionSource.runAction": {
66907
+ capName: "action-source",
66908
+ capScope: "system",
66909
+ addonId: null,
66910
+ access: "create",
66911
+ role: "admin"
66912
+ },
66913
+ "actionSource.stopAction": {
66914
+ capName: "action-source",
66915
+ capScope: "system",
66916
+ addonId: null,
66917
+ access: "create",
66918
+ role: "admin"
66919
+ },
66390
66920
  "addonPages.listPages": {
66391
66921
  capName: "addon-pages",
66392
66922
  capScope: "system",
@@ -67668,6 +68198,13 @@ Object.freeze({
67668
68198
  access: "view",
67669
68199
  role: "admin"
67670
68200
  },
68201
+ "coreBlocks.getAutomationRunState": {
68202
+ capName: "core-blocks",
68203
+ capScope: "system",
68204
+ addonId: null,
68205
+ access: "view",
68206
+ role: "admin"
68207
+ },
67671
68208
  "coreBlocks.getBlockSettings": {
67672
68209
  capName: "core-blocks",
67673
68210
  capScope: "system",
@@ -67689,6 +68226,13 @@ Object.freeze({
67689
68226
  access: "view",
67690
68227
  role: "admin"
67691
68228
  },
68229
+ "coreBlocks.getTraces": {
68230
+ capName: "core-blocks",
68231
+ capScope: "system",
68232
+ addonId: null,
68233
+ access: "view",
68234
+ role: "admin"
68235
+ },
67692
68236
  "coreBlocks.getTypeDefs": {
67693
68237
  capName: "core-blocks",
67694
68238
  capScope: "system",
@@ -67724,6 +68268,13 @@ Object.freeze({
67724
68268
  access: "create",
67725
68269
  role: "admin"
67726
68270
  },
68271
+ "coreBlocks.reportAutomationRun": {
68272
+ capName: "core-blocks",
68273
+ capScope: "system",
68274
+ addonId: null,
68275
+ access: "create",
68276
+ role: "admin"
68277
+ },
67727
68278
  "coreBlocks.restart": {
67728
68279
  capName: "core-blocks",
67729
68280
  capScope: "system",
@@ -79878,6 +80429,8 @@ var ML = "model and training machinery — no device action";
79878
80429
  var INTERNAL = "internal plumbing between addons — never operator-facing";
79879
80430
  /** Every system-scoped cap, with why it is not a device's vocabulary. */
79880
80431
  var SYSTEM_CAP_VOCABULARY = {
80432
+ "action-source": system(INTERNAL),
80433
+ actions: system("declared actions — run from the Actions page and from the cameras that link them"),
79881
80434
  "addon-pages": system(UI_PLUMBING),
79882
80435
  "addon-pages-source": system(UI_PLUMBING),
79883
80436
  "addon-routes": system(UI_PLUMBING),
@@ -80074,6 +80627,31 @@ Object.freeze({
80074
80627
  form: "single",
80075
80628
  optional: false
80076
80629
  }],
80630
+ "actions.get": [{
80631
+ name: "deviceId",
80632
+ form: "single",
80633
+ optional: true
80634
+ }],
80635
+ "actions.getLinks": [{
80636
+ name: "deviceId",
80637
+ form: "single",
80638
+ optional: false
80639
+ }],
80640
+ "actions.listForCamera": [{
80641
+ name: "deviceId",
80642
+ form: "single",
80643
+ optional: false
80644
+ }],
80645
+ "actions.run": [{
80646
+ name: "deviceId",
80647
+ form: "single",
80648
+ optional: true
80649
+ }],
80650
+ "actions.setLinks": [{
80651
+ name: "deviceId",
80652
+ form: "single",
80653
+ optional: false
80654
+ }],
80077
80655
  "addonSettings.getDeviceSettings": [{
80078
80656
  name: "deviceId",
80079
80657
  form: "single",
@@ -84155,6 +84733,7 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
84155
84733
  DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
84156
84734
  DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
84157
84735
  DEFAULT_NATIVE_LEASE_SETTINGS.admission;
84736
+ String.raw`(?<=^|["'(\s>,\[{])`;
84158
84737
  var MB = 1024 * 1024;
84159
84738
  1024 * MB, 3072 * MB;
84160
84739
  //#endregion