@camstack/addon-pipeline-orchestrator 1.2.645 → 1.2.646

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/dist/index.mjs CHANGED
@@ -5591,7 +5591,7 @@ var ZodIssueCode = {
5591
5591
  var ZodFirstPartyTypeKind;
5592
5592
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5593
5593
  //#endregion
5594
- //#region ../types/dist/sleep-CeyhrcOk.mjs
5594
+ //#region ../types/dist/sleep-DSVWZfJC.mjs
5595
5595
  /**
5596
5596
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5597
5597
  * window to float samples (D455).
@@ -7310,6 +7310,26 @@ var BaseAddon = class {
7310
7310
  * alternative — skip it — turns a rename into a surface that quietly
7311
7311
  * empties, which looks exactly like an addon with nothing to configure.
7312
7312
  */
7313
+ /**
7314
+ * The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
7315
+ *
7316
+ * Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
7317
+ * needs its connection fields, the default integration the addon's own sections. It is the
7318
+ * SHAPE of the form only — the values live in `integrations.getSettings`, and the write path is
7319
+ * unchanged (`integrations.setSettings` for an account integration).
7320
+ */
7321
+ async integrationSettingsSchema(_instance) {
7322
+ return null;
7323
+ }
7324
+ /**
7325
+ * What the create wizard and the integration edit page render for one instance: the addon's
7326
+ * per-instance schema when it declares one, else its global schema (what they always showed).
7327
+ */
7328
+ async getIntegrationFormSchema(instance, nodeId) {
7329
+ const scoped = await this.integrationSettingsSchema(instance);
7330
+ if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
7331
+ return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
7332
+ }
7313
7333
  async getIntegrationSettings(nodeId) {
7314
7334
  const declared = this.integrationSettingSections();
7315
7335
  if (declared.length === 0) return null;
@@ -9748,6 +9768,7 @@ var CAP_NAMES = Object.freeze([
9748
9768
  "remote-layout-components",
9749
9769
  "running-state",
9750
9770
  "scene-monitor",
9771
+ "schedulers",
9751
9772
  "script-runner",
9752
9773
  "server-management",
9753
9774
  "settings-store",
@@ -10693,7 +10714,8 @@ Object.freeze({
10693
10714
  "unlocked",
10694
10715
  "locking",
10695
10716
  "unlocking",
10696
- "jammed"
10717
+ "jammed",
10718
+ "door-open"
10697
10719
  ]
10698
10720
  }],
10699
10721
  "media-player": [
@@ -13373,6 +13395,25 @@ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
13373
13395
  /** The same list as a Zod enum, for the cap input that carries it. */
13374
13396
  var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
13375
13397
  new Set(EVENT_OWNER_TYPES);
13398
+ /**
13399
+ * Which integration instance a settings form is for. An addon that serves several instances
13400
+ * (`instanceMode: multiple`) can show a different form per instance — an NVR integration
13401
+ * needs its connection, the default integration needs the addon's own sections.
13402
+ *
13403
+ * - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
13404
+ * setting up a NEW instance.
13405
+ * - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
13406
+ * - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
13407
+ */
13408
+ var IntegrationInstanceRefSchema = object({
13409
+ integrationId: string().nullable(),
13410
+ mode: _enum([
13411
+ "standalone",
13412
+ "account",
13413
+ "broker"
13414
+ ]),
13415
+ candidateStableId: string().optional()
13416
+ });
13376
13417
  var EncodeProfileSchema = object({
13377
13418
  video: object({
13378
13419
  codec: _enum([
@@ -17624,6 +17665,11 @@ var ACTUATOR_CAP_VOCABULARY = {
17624
17665
  value: "jammed",
17625
17666
  label: t("Jammed", "Inceppata"),
17626
17667
  phrase: t("When {device} jams", "Quando {device} si inceppa")
17668
+ },
17669
+ {
17670
+ value: "door-open",
17671
+ label: t("Door open", "Porta aperta"),
17672
+ phrase: t("When the door of {device} opens", "Quando la porta di {device} si apre")
17627
17673
  }
17628
17674
  ],
17629
17675
  icon: "lock"
@@ -21114,6 +21160,7 @@ var SYSTEM_CAP_VOCABULARY = {
21114
21160
  records: system(INTERNAL),
21115
21161
  remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
21116
21162
  "remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
21163
+ schedulers: system("time schedulers — authored on their own page, not device actions"),
21117
21164
  "server-management": system(CLUSTER),
21118
21165
  "settings-store": system(INTERNAL),
21119
21166
  "smtp-provider": system(INTERNAL),
@@ -41977,6 +42024,122 @@ var AutomationWhenSchema = lazy(() => discriminatedUnion("kind", [
41977
42024
  StationaryPresentLeafSchema,
41978
42025
  ExpressionLeafSchema
41979
42026
  ]));
42027
+ var EVENT_KINDS = new Set([
42028
+ "device-becomes",
42029
+ "device-event",
42030
+ "schedule",
42031
+ "manual",
42032
+ "interval",
42033
+ "detection",
42034
+ "stationary"
42035
+ ]);
42036
+ function isEventLeaf(node) {
42037
+ return EVENT_KINDS.has(node.kind);
42038
+ }
42039
+ function isLeaf(node) {
42040
+ return node.kind !== "all" && node.kind !== "any" && node.kind !== "not";
42041
+ }
42042
+ /** Depth of a tree, root container = 1. A bare leaf is depth 1. */
42043
+ function whenDepth(node) {
42044
+ if (isLeaf(node)) return 1;
42045
+ if (node.kind === "not") return 1 + whenDepth(node.child);
42046
+ let deepest = 0;
42047
+ for (const child of node.children) deepest = Math.max(deepest, whenDepth(child));
42048
+ return 1 + deepest;
42049
+ }
42050
+ /** Leaves only — containers do not count toward the leaf budget. */
42051
+ function countWhenLeaves(node) {
42052
+ if (isLeaf(node)) return 1;
42053
+ if (node.kind === "not") return countWhenLeaves(node.child);
42054
+ let total = 0;
42055
+ for (const child of node.children) total += countWhenLeaves(child);
42056
+ return total;
42057
+ }
42058
+ /** Every leaf with its path (`when`, `when.0`, `when.0.1`, `when.0` under a `not`). */
42059
+ function forEachLeaf(node, visit, path = "when") {
42060
+ if (isLeaf(node)) {
42061
+ visit(node, path);
42062
+ return;
42063
+ }
42064
+ if (node.kind === "not") {
42065
+ forEachLeaf(node.child, visit, `${path}.0`);
42066
+ return;
42067
+ }
42068
+ node.children.forEach((child, i) => {
42069
+ forEachLeaf(child, visit, `${path}.${i}`);
42070
+ });
42071
+ }
42072
+ function hasEventLeaves(node) {
42073
+ let found = false;
42074
+ forEachLeaf(node, (leaf) => {
42075
+ if (isEventLeaf(leaf)) found = true;
42076
+ });
42077
+ return found;
42078
+ }
42079
+ function hasEmptyContainer(node) {
42080
+ if (isLeaf(node)) return false;
42081
+ if (node.kind === "not") return hasEmptyContainer(node.child);
42082
+ if (node.children.length === 0) return true;
42083
+ return node.children.some(hasEmptyContainer);
42084
+ }
42085
+ var LEAF_WORDS = {
42086
+ "device-becomes": "a device value that becomes",
42087
+ "device-event": "a device event",
42088
+ schedule: "a schedule",
42089
+ manual: "a manual run",
42090
+ interval: "an interval",
42091
+ detection: "a detection",
42092
+ stationary: "a parked object appearing or leaving"
42093
+ };
42094
+ function say(kind) {
42095
+ return LEAF_WORDS[kind] ?? kind;
42096
+ }
42097
+ /**
42098
+ * The cheapest set of event leaves that makes `node` true, with negation pushed
42099
+ * down to the leaves first (De Morgan), so `not(any(A, B))` and `all(not A,
42100
+ * not B)` are the same shape to the check. A negated event is its own error: an
42101
+ * event is an instant, "the event did not occur" is true at every other moment.
42102
+ */
42103
+ function eventNeed(node, path, negated) {
42104
+ if (isLeaf(node)) {
42105
+ if (!isEventLeaf(node)) return { paths: [] };
42106
+ if (negated) return { error: `"not" is applied to ${say(node.kind)} (${path}) — an event is an instant, so "it did not happen" is true at every other moment and can never start a run. Negate a state ("is") instead, or remove the "not"` };
42107
+ return { paths: [{
42108
+ path,
42109
+ kind: node.kind
42110
+ }] };
42111
+ }
42112
+ if (node.kind === "not") return eventNeed(node.child, `${path}.0`, !negated);
42113
+ const conjunctive = node.kind === "all" !== negated;
42114
+ const parts = [];
42115
+ for (let i = 0; i < node.children.length; i += 1) {
42116
+ const child = node.children[i];
42117
+ if (child === void 0) continue;
42118
+ const need = eventNeed(child, `${path}.${i}`, negated);
42119
+ if ("error" in need) return need;
42120
+ parts.push(need);
42121
+ }
42122
+ if (conjunctive) return { paths: parts.flatMap((p) => p.paths) };
42123
+ let best;
42124
+ for (const part of parts) if (best === void 0 || part.paths.length < best.paths.length) best = part;
42125
+ return best ?? { paths: [] };
42126
+ }
42127
+ /**
42128
+ * Author-time bounds and sense check of a `when` tree. Returns `null` when it
42129
+ * is legal, else a message the editor shows verbatim.
42130
+ */
42131
+ function validateWhenTree(when) {
42132
+ if (hasEmptyContainer(when)) return "a group is empty — group existing rows instead of leaving a container to fill";
42133
+ const depth = whenDepth(when);
42134
+ if (depth > 4) return `the rules nest ${depth} levels deep — the limit is 4. "not (any of …)" is the same as "all of (not …)", which is one level shallower`;
42135
+ const leaves = countWhenLeaves(when);
42136
+ if (leaves > 32) return `the rules use ${leaves} rows — the limit is 32`;
42137
+ const need = eventNeed(when, "when", false);
42138
+ if ("error" in need) return need.error;
42139
+ const [first, second] = need.paths;
42140
+ if (first !== void 0 && second !== void 0) return `${say(first.kind)} (${first.path}) and ${say(second.kind)} (${second.path}) would both have to happen at the same instant, and an event happens at one moment — this can never run. Use "any of" to start on either, or turn one of them into a state ("is") that must already hold`;
42141
+ return null;
42142
+ }
41980
42143
  /**
41981
42144
  * The recipe shape before the single `when` tree: a flat list of triggers
41982
42145
  * (OR'd, each an instant) and an optional condition tree. Stored recipes —
@@ -42332,6 +42495,187 @@ function convertLegacyRecipe(legacy) {
42332
42495
  var AutomationRecipeSchema = union([CurrentAutomationRecipeSchema, LegacyAutomationRecipeSchema.transform(convertLegacyRecipe)]);
42333
42496
  new Set(Object.values(COCO_TO_MACRO.mapping));
42334
42497
  /**
42498
+ * Schedulers (D983) — an entity that performs actions over the day.
42499
+ *
42500
+ * A scheduler has profiles; a profile has weekdays and a timeline of POINTS.
42501
+ * A point is an `edge` (run once at its time), a `hold` (from this point until
42502
+ * the next point of the profile, keep the steps' effects true) or a `release`
42503
+ * (end the current hold without acting). The scheduler AND each profile carry
42504
+ * a manual `enabled` flag and an optional `activeWhen`: a `when` STATE tree
42505
+ * (facts only — an event leaf is an instant and cannot be "in force").
42506
+ *
42507
+ * This file is the data half: the schemas, and the author-time rules that
42508
+ * decide whether a scheduler can be saved at all (a hold needs an action that
42509
+ * leads to a state; a sun point needs the site location). It holds no runtime.
42510
+ */
42511
+ /** A `when` tree that is a STATE: no event leaf, and legal as a tree. */
42512
+ var SchedulerStateTreeSchema = AutomationWhenSchema.superRefine((when, ctx) => {
42513
+ if (hasEventLeaves(when)) {
42514
+ ctx.addIssue({
42515
+ code: "custom",
42516
+ message: "a scheduler condition is a state — an event (\"becomes\", \"detects\", \"at a time\") is an instant and cannot be in force"
42517
+ });
42518
+ return;
42519
+ }
42520
+ const problem = validateWhenTree(when);
42521
+ if (problem !== null) ctx.addIssue({
42522
+ code: "custom",
42523
+ message: problem
42524
+ });
42525
+ });
42526
+ /** A point's moment: a clock time or a sun event. A one-shot date is not a position on a day. */
42527
+ var SchedulerTimeSpecSchema = TimeSpecSchema.refine((spec) => spec.kind !== "date", { message: "a scheduler point is a clock time or a sun event — a one-shot date has no place on a timeline" });
42528
+ var SchedulerPointModeSchema = _enum([
42529
+ "edge",
42530
+ "hold",
42531
+ "release"
42532
+ ]);
42533
+ /** What a hold does when someone changes the device by hand. */
42534
+ var HoldOverrideSchema = discriminatedUnion("mode", [object({ mode: literal("respect") }), object({
42535
+ mode: literal("reassert"),
42536
+ /** How long the manual state is left alone before the hold puts its own back. */
42537
+ graceMs: number().int().min(0).max(24 * 36e5)
42538
+ })]);
42539
+ /** A missed edge up to this late still runs. */
42540
+ var DEFAULT_MAX_LATE_MS = 10 * 6e4;
42541
+ var SchedulerPointSchema = object({
42542
+ id: string().min(1).max(64),
42543
+ at: SchedulerTimeSpecSchema,
42544
+ mode: SchedulerPointModeSchema,
42545
+ /** The actions of an `edge` or `hold`; a `release` has none. */
42546
+ steps: array(ActionStepSchema).max(20).default([]),
42547
+ /** Checked when the point runs (an edge) or is applied (a hold). */
42548
+ conditions: SchedulerStateTreeSchema.optional(),
42549
+ /** Hold only; absent means `respect`. */
42550
+ override: HoldOverrideSchema.optional(),
42551
+ /** Hold only: re-applications per window; absent means {@link DEFAULT_MAX_HOLD_ATTEMPTS}. */
42552
+ maxHoldAttempts: number().int().min(1).max(20).optional()
42553
+ });
42554
+ var SchedulerProfileSchema = object({
42555
+ id: string().min(1).max(64),
42556
+ name: string().min(1).max(120),
42557
+ enabled: boolean().default(true),
42558
+ activeWhen: SchedulerStateTreeSchema.optional(),
42559
+ days: array(WeekdayKeySchema).min(1).max(7),
42560
+ points: array(SchedulerPointSchema).max(50)
42561
+ });
42562
+ /** What an operator writes. */
42563
+ var SchedulerInputSchema = object({
42564
+ name: string().min(1).max(120),
42565
+ enabled: boolean().default(true),
42566
+ activeWhen: SchedulerStateTreeSchema.optional(),
42567
+ /** Higher wins when two holds want the same device in different states. */
42568
+ priority: number().int().min(0).max(100).default(0),
42569
+ maxLateMs: number().int().min(1e3).max(24 * 36e5).default(DEFAULT_MAX_LATE_MS),
42570
+ profiles: array(SchedulerProfileSchema).max(20)
42571
+ });
42572
+ var SchedulerSchema = SchedulerInputSchema.extend({
42573
+ id: string().min(1),
42574
+ createdAt: number(),
42575
+ updatedAt: number()
42576
+ });
42577
+ /** Every outcome a scheduler reports to the runs ledger (`AutomationRunTrace.scheduler`). */
42578
+ var SchedulerOutcomeSchema = _enum([
42579
+ "done",
42580
+ "missed",
42581
+ "inactive",
42582
+ "condition-false",
42583
+ "failed",
42584
+ "held",
42585
+ "gave-up",
42586
+ "overridden",
42587
+ "suspended-manual"
42588
+ ]);
42589
+ _enum([
42590
+ "not-found",
42591
+ "invalid-scheduler",
42592
+ "invalid-date"
42593
+ ]);
42594
+ var LOCAL_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
42595
+ /** One point of the day, placed. `at` is `null` when the sun never crosses that day. */
42596
+ var SchedulerPreviewPointSchema = object({
42597
+ pointId: string(),
42598
+ mode: SchedulerPointModeSchema,
42599
+ at: number().nullable(),
42600
+ /** A hold: when its window ends (the next point, else the end of the day). */
42601
+ until: number().nullable(),
42602
+ /** The point's steps are held on a different scheduler's claim at this time — see `conflicts`. */
42603
+ stepCount: number().int()
42604
+ });
42605
+ var SchedulerPreviewSchema = object({
42606
+ schedulerId: string(),
42607
+ /** The site-local day previewed. */
42608
+ date: string().regex(LOCAL_DATE_PATTERN),
42609
+ timeZone: string(),
42610
+ /** Why no profile is in force, or `null` when one is. */
42611
+ idleReason: string().nullable(),
42612
+ /** The profile in force that day: first in list order whose rules hold. */
42613
+ profileId: string().nullable(),
42614
+ points: array(SchedulerPreviewPointSchema)
42615
+ });
42616
+ /** Two holds that want the same device in different states at the same time. */
42617
+ var SchedulerConflictSchema = object({
42618
+ deviceId: number().int(),
42619
+ cap: string(),
42620
+ field: string(),
42621
+ mine: object({
42622
+ profileId: string(),
42623
+ pointId: string(),
42624
+ value: union([
42625
+ string(),
42626
+ number(),
42627
+ boolean()
42628
+ ]),
42629
+ priority: number().int()
42630
+ }),
42631
+ other: object({
42632
+ schedulerId: string(),
42633
+ schedulerName: string(),
42634
+ profileId: string(),
42635
+ pointId: string(),
42636
+ value: union([
42637
+ string(),
42638
+ number(),
42639
+ boolean()
42640
+ ]),
42641
+ priority: number().int()
42642
+ }),
42643
+ /** The overlapping stretch, as site-local minutes of the day. */
42644
+ fromMinute: number().int(),
42645
+ toMinute: number().int(),
42646
+ /** `mine` | `other` | `tie` — who holds when it happens (a tie: the one that started first). */
42647
+ winner: _enum([
42648
+ "mine",
42649
+ "other",
42650
+ "tie"
42651
+ ])
42652
+ });
42653
+ var HoldTargetStatusSchema = _enum([
42654
+ "pending",
42655
+ "held",
42656
+ "suspended-manual",
42657
+ "gave-up",
42658
+ "overridden"
42659
+ ]);
42660
+ var SchedulerStatusSchema = object({
42661
+ schedulerId: string(),
42662
+ profileId: string().nullable(),
42663
+ /** The hold in force right now, with where each target stands. */
42664
+ hold: object({
42665
+ pointId: string(),
42666
+ until: number(),
42667
+ /** `true` while the scheduler or profile `activeWhen` is false. */
42668
+ suspendedInactive: boolean(),
42669
+ targets: array(object({
42670
+ deviceId: number().int(),
42671
+ cap: string(),
42672
+ field: string(),
42673
+ status: HoldTargetStatusSchema,
42674
+ attempts: number().int()
42675
+ }))
42676
+ }).nullable()
42677
+ });
42678
+ /**
42335
42679
  * Run traces — what an automation (or, later, an Action run) DID, node by node,
42336
42680
  * so the editor can paint every block green or red with its reason.
42337
42681
  *
@@ -42467,7 +42811,13 @@ var AutomationRunTraceSchema = object({
42467
42811
  /** How many identical consecutive skips this trace stands for (>= 1). */
42468
42812
  repeat: number().int().min(1),
42469
42813
  /** When the latest of those repeats happened. */
42470
- lastAt: number()
42814
+ lastAt: number(),
42815
+ /**
42816
+ * A scheduler point's own outcome (D983). `outcome` carries the closest
42817
+ * automation outcome so a reader that does not know schedulers still reads
42818
+ * the trace; this field says exactly what happened.
42819
+ */
42820
+ scheduler: SchedulerOutcomeSchema.optional()
42471
42821
  });
42472
42822
  /**
42473
42823
  * What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
@@ -43196,6 +43546,10 @@ method(object({
43196
43546
  }), method(object({
43197
43547
  addonId: string(),
43198
43548
  nodeId: string().optional()
43549
+ }), SettingsSchemaWithValuesSchema.nullable()), method(object({
43550
+ addonId: string(),
43551
+ nodeId: string().optional(),
43552
+ instance: IntegrationInstanceRefSchema
43199
43553
  }), SettingsSchemaWithValuesSchema.nullable()), method(object({
43200
43554
  addonId: string(),
43201
43555
  nodeId: string().optional()
@@ -45914,6 +46268,7 @@ method(object({
45914
46268
  kind: "mutation",
45915
46269
  auth: "admin"
45916
46270
  }), method(object({ blockIds: array(string()) }), object({ states: array(CompositionBlockStateSchema) }), { auth: "admin" });
46271
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
45917
46272
  var NUMBER = {
45918
46273
  kind: "fixed",
45919
46274
  result: ["number"]
@@ -65561,6 +65916,43 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
65561
65916
  auth: "admin"
65562
65917
  });
65563
65918
  /**
65919
+ * schedulers — timelines of edge and hold points that perform actions over the
65920
+ * day (D983). Provided by the core-blocks builtin on the hub, beside `actions`:
65921
+ * the same runs ledger (owner `scheduler:<id>`), the same target resolver, the
65922
+ * same step runner.
65923
+ *
65924
+ * The hub runs ONE timer for the next point across every scheduler. A save is
65925
+ * refused with its reason (`[invalid-scheduler] …`) when a hold has a step that
65926
+ * leads to no state, or a sun point has no site location to read.
65927
+ */
65928
+ var SchedulerIdInput = object({ schedulerId: string().min(1) });
65929
+ method(object({}), array(SchedulerSchema), { auth: "admin" }), method(SchedulerIdInput, object({ scheduler: SchedulerSchema.nullable() }), { auth: "admin" }), method(object({ scheduler: SchedulerInputSchema }), object({ scheduler: SchedulerSchema }), {
65930
+ kind: "mutation",
65931
+ auth: "admin"
65932
+ }), method(object({
65933
+ schedulerId: string().min(1),
65934
+ scheduler: SchedulerInputSchema
65935
+ }), object({ scheduler: SchedulerSchema }), {
65936
+ kind: "mutation",
65937
+ auth: "admin"
65938
+ }), method(SchedulerIdInput, _void(), {
65939
+ kind: "mutation",
65940
+ auth: "admin"
65941
+ }), method(object({
65942
+ schedulerId: string().min(1),
65943
+ profileId: string().min(1).optional(),
65944
+ enabled: boolean()
65945
+ }), object({ scheduler: SchedulerSchema }), {
65946
+ kind: "mutation",
65947
+ auth: "admin"
65948
+ }), method(object({
65949
+ schedulerId: string().min(1),
65950
+ date: string().regex(LOCAL_DATE_PATTERN).optional()
65951
+ }), SchedulerPreviewSchema, { auth: "admin" }), method(object({
65952
+ scheduler: SchedulerInputSchema,
65953
+ schedulerId: string().min(1).optional()
65954
+ }), object({ conflicts: array(SchedulerConflictSchema) }), { auth: "admin" }), method(object({}), array(SchedulerStatusSchema), { auth: "admin" }), method(SchedulerIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" });
65955
+ /**
65564
65956
  * actions — the ONE surface for runnable actions, for the UI and for
65565
65957
  * automations. Provided by the core-blocks builtin on the hub.
65566
65958
  *
@@ -68315,6 +68707,8 @@ var IntegrationWithStateSchema = object({
68315
68707
  name: string(),
68316
68708
  enabled: boolean(),
68317
68709
  info: record(string(), unknown()).readonly(),
68710
+ /** The discovery candidate this integration was set up from (D984). */
68711
+ originStableId: string().optional(),
68318
68712
  createdAt: number(),
68319
68713
  updatedAt: number(),
68320
68714
  processState: string()
@@ -68325,6 +68719,8 @@ var IntegrationLiteSchema = object({
68325
68719
  name: string(),
68326
68720
  enabled: boolean(),
68327
68721
  info: record(string(), unknown()).readonly(),
68722
+ /** The discovery candidate this integration was set up from (D984). */
68723
+ originStableId: string().optional(),
68328
68724
  createdAt: number(),
68329
68725
  updatedAt: number()
68330
68726
  });
@@ -68422,6 +68818,8 @@ var CreateIntegrationInputSchema = object({
68422
68818
  name: string(),
68423
68819
  enabled: boolean().optional(),
68424
68820
  info: record(string(), unknown()).optional(),
68821
+ /** `stableId` of the discovery candidate the form was seeded from (D984). */
68822
+ originStableId: string().optional(),
68425
68823
  settings: record(string(), unknown()).optional(),
68426
68824
  /** Keys of `settings` the form's schema declares secret (by type) — kept in
68427
68825
  * the keychain, not the table (D787). */
@@ -69039,11 +69437,13 @@ object({
69039
69437
  "unlocked",
69040
69438
  "locking",
69041
69439
  "unlocking",
69042
- "jammed"
69440
+ "jammed",
69441
+ "door-open"
69043
69442
  ]),
69044
69443
  /** Ms epoch when the slice was last updated. */
69045
69444
  lastChangedAt: number()
69046
69445
  });
69446
+ DeviceType.Lock;
69047
69447
  DeviceType.Lock, method(object({
69048
69448
  deviceId: number().int().nonnegative(),
69049
69449
  /** Optional PIN code required by some keypad locks. NOT
@@ -76268,7 +76668,6 @@ discriminatedUnion("kind", [object({
76268
76668
  })]);
76269
76669
  DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
76270
76670
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
76271
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
76272
76671
  String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
76273
76672
  DeviceRole.BinarySensor, DeviceRole.MotionSensor;
76274
76673
  new Set(CAP_NAMES);
@@ -76730,6 +77129,13 @@ Object.freeze({
76730
77129
  access: "view",
76731
77130
  role: "admin"
76732
77131
  },
77132
+ "addonSettings.getIntegrationFormSchema": {
77133
+ capName: "addon-settings",
77134
+ capScope: "system",
77135
+ addonId: null,
77136
+ access: "view",
77137
+ role: "admin"
77138
+ },
76733
77139
  "addonSettings.getIntegrationSettings": {
76734
77140
  capName: "addon-settings",
76735
77141
  capScope: "system",
@@ -84262,6 +84668,76 @@ Object.freeze({
84262
84668
  access: "create",
84263
84669
  role: "feature:scenes"
84264
84670
  },
84671
+ "schedulers.conflicts": {
84672
+ capName: "schedulers",
84673
+ capScope: "system",
84674
+ addonId: null,
84675
+ access: "view",
84676
+ role: "admin"
84677
+ },
84678
+ "schedulers.create": {
84679
+ capName: "schedulers",
84680
+ capScope: "system",
84681
+ addonId: null,
84682
+ access: "create",
84683
+ role: "admin"
84684
+ },
84685
+ "schedulers.delete": {
84686
+ capName: "schedulers",
84687
+ capScope: "system",
84688
+ addonId: null,
84689
+ access: "delete",
84690
+ role: "admin"
84691
+ },
84692
+ "schedulers.get": {
84693
+ capName: "schedulers",
84694
+ capScope: "system",
84695
+ addonId: null,
84696
+ access: "view",
84697
+ role: "admin"
84698
+ },
84699
+ "schedulers.getStatus": {
84700
+ capName: "schedulers",
84701
+ capScope: "system",
84702
+ addonId: null,
84703
+ access: "view",
84704
+ role: "admin"
84705
+ },
84706
+ "schedulers.getTraces": {
84707
+ capName: "schedulers",
84708
+ capScope: "system",
84709
+ addonId: null,
84710
+ access: "view",
84711
+ role: "admin"
84712
+ },
84713
+ "schedulers.list": {
84714
+ capName: "schedulers",
84715
+ capScope: "system",
84716
+ addonId: null,
84717
+ access: "view",
84718
+ role: "admin"
84719
+ },
84720
+ "schedulers.preview": {
84721
+ capName: "schedulers",
84722
+ capScope: "system",
84723
+ addonId: null,
84724
+ access: "view",
84725
+ role: "admin"
84726
+ },
84727
+ "schedulers.setEnabled": {
84728
+ capName: "schedulers",
84729
+ capScope: "system",
84730
+ addonId: null,
84731
+ access: "create",
84732
+ role: "admin"
84733
+ },
84734
+ "schedulers.update": {
84735
+ capName: "schedulers",
84736
+ capScope: "system",
84737
+ addonId: null,
84738
+ access: "create",
84739
+ role: "admin"
84740
+ },
84265
84741
  "scriptRunner.getStatus": {
84266
84742
  capName: "script-runner",
84267
84743
  capScope: "device",
@@ -90319,6 +90795,7 @@ new Set([
90319
90795
  "locking",
90320
90796
  "unlocking",
90321
90797
  "jammed",
90798
+ "door-open",
90322
90799
  "on",
90323
90800
  "off",
90324
90801
  "home",
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CwuxFxDA.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DDVZFPsa.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline-orchestrator",
3
- "version": "1.2.645",
3
+ "version": "1.2.646",
4
4
  "description": "Hub-side camera-to-agent load balancer — tracks runner capacity and dispatches attachCamera calls to the optimal pipeline-runner instance",
5
5
  "keywords": [
6
6
  "camstack",