@camstack/addon-import-alexa 0.2.174 → 0.2.176

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/addon.js CHANGED
@@ -48,7 +48,7 @@ node_os = __toESM(node_os, 1);
48
48
  let node_child_process = require("node:child_process");
49
49
  require("node:zlib");
50
50
  let node_url = require("node:url");
51
- //#region ../types/dist/event-category-CaURIwQA.mjs
51
+ //#region ../types/dist/event-category-BmPm98n0.mjs
52
52
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
53
53
  EventCategory["SystemBoot"] = "system.boot";
54
54
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -532,6 +532,10 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
532
532
  EventCategory["RunningStarted"] = "running.started";
533
533
  /** Mirrors `runningStateCapability.events.onFinished`. */
534
534
  EventCategory["RunningFinished"] = "running.finished";
535
+ /** Mirrors `deviceRunsCapability.events.onRunOpened` - a durable run record opened. */
536
+ EventCategory["DeviceRunOpened"] = "device-run.opened";
537
+ /** Mirrors `deviceRunsCapability.events.onRunClosed` - a durable run record closed. */
538
+ EventCategory["DeviceRunClosed"] = "device-run.closed";
535
539
  /**
536
540
  * Cap event fired by every device that registers the `event-emitter`
537
541
  * capability. Mirrors `eventEmitterCapability.events.onEvent`. Carries
@@ -6027,7 +6031,7 @@ function number(params) {
6027
6031
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
6028
6032
  }
6029
6033
  //#endregion
6030
- //#region ../types/dist/sleep-CSYuxssh.mjs
6034
+ //#region ../types/dist/sleep-BKzhQTSm.mjs
6031
6035
  /**
6032
6036
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6033
6037
  * window to float samples (D455).
@@ -9706,6 +9710,7 @@ var CAP_NAMES = Object.freeze([
9706
9710
  "device-ops",
9707
9711
  "device-provider",
9708
9712
  "device-removal-hook",
9713
+ "device-runs",
9709
9714
  "device-state",
9710
9715
  "device-status",
9711
9716
  "dishwasher",
@@ -11650,7 +11655,7 @@ object({
11650
11655
  params: record(string(), union([string(), number$1()])).optional()
11651
11656
  });
11652
11657
  //#endregion
11653
- //#region ../types/dist/composition-BBzVf2xd.mjs
11658
+ //#region ../types/dist/composition-BiKWlUCc.mjs
11654
11659
  /**
11655
11660
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11656
11661
  *
@@ -12583,7 +12588,15 @@ var HelperSpecSchema = discriminatedUnion("kind", [
12583
12588
  thresholdWatts: number$1().positive(),
12584
12589
  startDwellMs: number$1().int().nonnegative(),
12585
12590
  stopDwellMs: number$1().int().nonnegative(),
12586
- member: HelperMemberSchema
12591
+ member: HelperMemberSchema,
12592
+ /**
12593
+ * The plug that powers the appliance (`switch.on`). Optional: when set, the
12594
+ * composition carries a `power-source` feature, so the hub can cut and restore
12595
+ * that plug (power-source link of a NEW-target composition).
12596
+ */
12597
+ powerSwitch: HelperMemberSchema.optional(),
12598
+ /** How long a forced restart keeps the plug off; the cap's default when unset. */
12599
+ offSeconds: number$1().optional()
12587
12600
  }),
12588
12601
  object({
12589
12602
  kind: literal("statistic"),
@@ -14098,7 +14111,13 @@ var MigrationLedgerEntrySchema = object({
14098
14111
  /** Why it is `blocked` or `held` (`dependency-failed`, `snapshot-refused`, …). */
14099
14112
  reason: string().nullable(),
14100
14113
  nodeId: string().nullable(),
14101
- bootId: string().nullable()
14114
+ bootId: string().nullable(),
14115
+ /**
14116
+ * The catalogued meta of this id (description, body kind, store, `dependsOn`…),
14117
+ * joined by the engine from the catalogues it knows this boot. Absent when no
14118
+ * catalogue lists the id (a newer database).
14119
+ */
14120
+ meta: MigrationMetaSchema.optional()
14102
14121
  });
14103
14122
  /** A catalogued migration that is not applied, with where it stands. */
14104
14123
  var MigrationPendingEntrySchema = object({
@@ -19905,6 +19924,14 @@ var APPLIANCE_CAP_VOCABULARY = {
19905
19924
  }
19906
19925
  } }
19907
19926
  },
19927
+ "device-runs": {
19928
+ scope: "device",
19929
+ noun: t("Runs", "Esecuzioni"),
19930
+ events: {
19931
+ onRunOpened: { notOperatorFacing: "the durable record of a run that the running-state start flip already announces" },
19932
+ onRunClosed: { notOperatorFacing: "the durable record of a run that the running-state finish flip already announces" }
19933
+ }
19934
+ },
19908
19935
  update: {
19909
19936
  scope: "device",
19910
19937
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -46577,6 +46604,117 @@ function actuator(input) {
46577
46604
  };
46578
46605
  }
46579
46606
  new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
46607
+ var PowerSourceRefusalReasonSchema = _enum([
46608
+ "no-power-source",
46609
+ "switch-missing",
46610
+ "switch-offline",
46611
+ "switch-unknown",
46612
+ "restart-in-progress",
46613
+ "switch-call-failed"
46614
+ ]);
46615
+ var PowerSourceActionResultSchema = discriminatedUnion("accepted", [object({ accepted: literal(true) }), object({
46616
+ accepted: literal(false),
46617
+ reason: PowerSourceRefusalReasonSchema,
46618
+ /** One line for the operator, naming the switch. */
46619
+ message: string()
46620
+ })]);
46621
+ var PowerSourceInfoSchema = object({
46622
+ /** False when the device has no power source linked; the rest is then empty. */
46623
+ linked: boolean(),
46624
+ switchDeviceId: number$1().nullable(),
46625
+ switchName: string().nullable(),
46626
+ /** The switch's on/off state, or null when it is unknown. Never false for unknown (D393). */
46627
+ switchOn: boolean().nullable(),
46628
+ switchOnline: boolean().nullable(),
46629
+ restartInProgress: boolean(),
46630
+ offSeconds: number$1().int()
46631
+ });
46632
+ /** The composed slice: the switch state the link mirrors, plus the stored off time. */
46633
+ var PowerSourceStateSchema = object({
46634
+ /** Null while the switch has not reported: unknown is never `false` (D393). */
46635
+ switchOn: boolean().nullable(),
46636
+ offSeconds: number$1().int(),
46637
+ lastFetchedAt: number$1()
46638
+ });
46639
+ var POWER_SOURCE_DEVICE_TYPES = [
46640
+ DeviceType.Gateway,
46641
+ DeviceType.Hub,
46642
+ DeviceType.Camera,
46643
+ DeviceType.Sensor,
46644
+ DeviceType.MediaPlayer,
46645
+ DeviceType.Vacuum,
46646
+ DeviceType.Generic,
46647
+ DeviceType.Washer,
46648
+ DeviceType.Dryer,
46649
+ DeviceType.Dishwasher,
46650
+ DeviceType.PetFountain,
46651
+ DeviceType.Fan,
46652
+ DeviceType.Humidifier,
46653
+ DeviceType.Climate,
46654
+ DeviceType.WaterHeater
46655
+ ];
46656
+ var powerSourceCustomize = {
46657
+ version: 1,
46658
+ targets: [{
46659
+ id: "switch",
46660
+ cardinality: "scalar",
46661
+ vocabulary: {
46662
+ cap: "power-source",
46663
+ stateField: "switchOn"
46664
+ },
46665
+ deviceTypes: POWER_SOURCE_DEVICE_TYPES,
46666
+ apply: "add",
46667
+ path: "switchOn",
46668
+ sources: [{
46669
+ kind: "switch",
46670
+ transforms: [{ kind: "identity" }]
46671
+ }],
46672
+ companions: [{
46673
+ kind: "constant",
46674
+ path: "offSeconds",
46675
+ value: 10,
46676
+ when: "add"
46677
+ }, {
46678
+ kind: "clock",
46679
+ path: "lastFetchedAt",
46680
+ when: "always"
46681
+ }],
46682
+ sourceReport: { status: "assignment-status" }
46683
+ }]
46684
+ };
46685
+ var deviceInput$1 = object({ deviceId: number$1().int().nonnegative() });
46686
+ var powerSourceCapability = {
46687
+ name: "power-source",
46688
+ scope: "device",
46689
+ mode: "singleton",
46690
+ deviceTypes: POWER_SOURCE_DEVICE_TYPES,
46691
+ methods: {
46692
+ getStatus: systemMethod(deviceInput$1, PowerSourceInfoSchema, { auth: "admin" }),
46693
+ powerOn: systemMethod(deviceInput$1, PowerSourceActionResultSchema, {
46694
+ kind: "mutation",
46695
+ auth: "admin"
46696
+ }),
46697
+ powerOff: systemMethod(deviceInput$1, PowerSourceActionResultSchema, {
46698
+ kind: "mutation",
46699
+ auth: "admin"
46700
+ }),
46701
+ forceRestart: systemMethod(deviceInput$1, PowerSourceActionResultSchema, {
46702
+ kind: "mutation",
46703
+ auth: "admin"
46704
+ })
46705
+ },
46706
+ runtimeState: PowerSourceStateSchema,
46707
+ customize: powerSourceCustomize,
46708
+ /**
46709
+ * Runtime-state durability: **session** — mirrored from the linked switch on
46710
+ * its next report; a restored value would outlive the reading it names.
46711
+ *
46712
+ * See `RuntimeStateDurability`. Enforced by
46713
+ * `scripts/check-runtime-state-durability.ts`.
46714
+ */
46715
+ durability: "session",
46716
+ history: "none"
46717
+ };
46580
46718
  DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
46581
46719
  DeviceType.Camera;
46582
46720
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
@@ -48002,6 +48140,101 @@ method(object({ deviceId: number$1().int() }), array(SeriesInfoSchema).readonly(
48002
48140
  kind: "mutation",
48003
48141
  auth: "admin"
48004
48142
  });
48143
+ /**
48144
+ * device-runs - the durable record of ONE run of a device: a washing cycle, a
48145
+ * dishwasher cycle, later a mow or a clean (D992).
48146
+ *
48147
+ * A run is a DOCUMENT (opened at one instant, closed at another, carrying what
48148
+ * was measured over it), never a sample - device-history keeps the numbers over
48149
+ * time and its `device-runs` provider keeps these documents beside them, because
48150
+ * the energy of a run is a question about device-history's own series. The
48151
+ * record is written from the `running-state` flip on `DeviceStateChanged`; it
48152
+ * survives a restart (the open row is on disk) and a missed flip (boot compares
48153
+ * the open rows against the live snapshots).
48154
+ *
48155
+ * Every measurement is `number | null` and `null` means "could not be
48156
+ * measured", never `0` (D393). A run closed by the boot reconcile because the
48157
+ * device stopped while nobody was watching has `outcome: 'unknown'`.
48158
+ */
48159
+ var DeviceRunKindSchema = _enum([
48160
+ "appliance",
48161
+ "mower",
48162
+ "vacuum"
48163
+ ]);
48164
+ var DeviceRunStateSchema = _enum(["open", "closed"]);
48165
+ var DeviceRunOutcomeSchema = _enum([
48166
+ "completed",
48167
+ "aborted",
48168
+ "error",
48169
+ "unknown"
48170
+ ]);
48171
+ /** What opened or closed the run. `reconcile` is the boot comparison against live state. */
48172
+ var DeviceRunSourceSchema = _enum([
48173
+ "running-state",
48174
+ "activity",
48175
+ "reconcile"
48176
+ ]);
48177
+ /** How the energy of a run was obtained; `null` when it could not be. */
48178
+ var DeviceRunEnergyMethodSchema = _enum(["counter-delta", "history-integral"]);
48179
+ var DeviceRunPhaseSchema = object({
48180
+ phase: string(),
48181
+ at: number$1()
48182
+ });
48183
+ /** The kind-specific block; a later phase adds a branch, nothing else changes. */
48184
+ var DeviceRunDetailSchema = discriminatedUnion("kind", [object({
48185
+ kind: literal("appliance"),
48186
+ /** kWh used over the run. */
48187
+ energyKwh: number$1().nullable().meta(readingMeta("energy")),
48188
+ energyMethod: DeviceRunEnergyMethodSchema.nullable(),
48189
+ /** Highest power seen while the run was open. */
48190
+ peakW: number$1().nullable().meta(readingMeta("power")),
48191
+ /** Time-weighted mean power while the run was open. */
48192
+ avgW: number$1().nullable().meta(readingMeta("power")),
48193
+ /** The program the appliance said it ran when the run opened. */
48194
+ program: string().nullable(),
48195
+ remainingAtStartSec: number$1().nullable().meta(readingMeta("duration")),
48196
+ /** The last phase the device reported before the run closed. */
48197
+ finalPhase: string().nullable(),
48198
+ /**
48199
+ * The meter's energy counter when the run opened; `null` when the meter had
48200
+ * not said (or the run was opened late, by the boot reconcile). It lives in
48201
+ * the row so a run that outlives a restart still ends with `end - start`.
48202
+ */
48203
+ energyStartKwh: number$1().nullable().meta(readingMeta("energy")),
48204
+ /** Milliseconds of power readings behind `avgW` - the weight a restart resumes the mean with. */
48205
+ powerObservedMs: number$1()
48206
+ })]);
48207
+ var DeviceRunSchema = object({
48208
+ /** `${deviceId}:${startedAt}`. */
48209
+ runId: string(),
48210
+ deviceId: number$1().int(),
48211
+ kind: DeviceRunKindSchema,
48212
+ state: DeviceRunStateSchema,
48213
+ startedAt: number$1(),
48214
+ endedAt: number$1().nullable(),
48215
+ durationMs: number$1().nullable(),
48216
+ outcome: DeviceRunOutcomeSchema.nullable(),
48217
+ startSource: DeviceRunSourceSchema,
48218
+ endSource: DeviceRunSourceSchema.nullable(),
48219
+ /** Where the device's running bit came from (`running-state.source`); `null` when it did not say. */
48220
+ runningSource: _enum(["native", "assigned"]).nullable(),
48221
+ phases: array(DeviceRunPhaseSchema),
48222
+ detail: DeviceRunDetailSchema
48223
+ });
48224
+ DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, method(object({
48225
+ deviceId: number$1().int(),
48226
+ outcome: DeviceRunOutcomeSchema.optional(),
48227
+ atFrom: number$1().optional(),
48228
+ atTo: number$1().optional(),
48229
+ limit: number$1().int().positive().max(200).default(50),
48230
+ cursor: string().optional()
48231
+ }), object({
48232
+ runs: array(DeviceRunSchema).readonly(),
48233
+ nextCursor: string().nullable()
48234
+ })), method(object({
48235
+ deviceId: number$1().int(),
48236
+ runId: string()
48237
+ }), DeviceRunSchema.nullable()), method(object({ deviceId: number$1().int() }), DeviceRunSchema.nullable());
48005
48238
  var DeviceCaStatusSchema = discriminatedUnion("state", [
48006
48239
  object({ state: literal("absent") }),
48007
48240
  object({
@@ -48137,8 +48370,8 @@ method(object({}), object({
48137
48370
  });
48138
48371
  var KeychainKeySourceSchema = object({
48139
48372
  kind: _enum([
48140
- "config-file",
48141
- "previous-config-file",
48373
+ "mounted-file",
48374
+ "previous-mounted-file",
48142
48375
  "platform",
48143
48376
  "default-file"
48144
48377
  ]),
@@ -52521,7 +52754,8 @@ var PALETTE_ENTRY_IDS = [
52521
52754
  "switch",
52522
52755
  "siren",
52523
52756
  "button",
52524
- "doorbell"
52757
+ "doorbell",
52758
+ "appliance-cycle"
52525
52759
  ];
52526
52760
  var AUDIO_ENTRY_ID = "audio";
52527
52761
  /** Six rungs, quiet → loud. The opaque end is the entry's hex. */
@@ -52592,7 +52826,8 @@ var CAMSTACK_HEX = {
52592
52826
  switch: "#7a812a",
52593
52827
  siren: "#ac5d7f",
52594
52828
  button: "#b276cd",
52595
- doorbell: "#0087ab"
52829
+ doorbell: "#0087ab",
52830
+ "appliance-cycle": "#2a8c8c"
52596
52831
  };
52597
52832
  var CAMSTACK_FALLBACK = [
52598
52833
  "#b34dc7",
@@ -52657,7 +52892,8 @@ var HIGH_CONTRAST_HEX = {
52657
52892
  switch: "#d05259",
52658
52893
  siren: "#cd67b3",
52659
52894
  button: "#c9746a",
52660
- doorbell: "#338eeb"
52895
+ doorbell: "#338eeb",
52896
+ "appliance-cycle": "#00848a"
52661
52897
  };
52662
52898
  var HIGH_CONTRAST_FALLBACK = [
52663
52899
  "#817f3b",
@@ -52722,7 +52958,8 @@ var OKABE_ITO_HEX = {
52722
52958
  switch: "#ad2c4e",
52723
52959
  siren: "#348e08",
52724
52960
  button: "#d27303",
52725
- doorbell: "#55770f"
52961
+ doorbell: "#55770f",
52962
+ "appliance-cycle": "#00737d"
52726
52963
  };
52727
52964
  var OKABE_ITO_FALLBACK = [
52728
52965
  "#9a3784",
@@ -52931,6 +53168,7 @@ sub("switch", "control", "control", "switch", "Switch");
52931
53168
  sub("siren", "control", "control", "siren", "Siren");
52932
53169
  sub("button", "control", "control", "button", "Button");
52933
53170
  sub("doorbell", "control", "control", "doorbell", "Doorbell");
53171
+ sub("appliance-cycle", "control", "control", "switch", "Appliance cycle");
52934
53172
  for (const l of AUDIO_MACRO_LABELS) {
52935
53173
  const kind = `audio-${l.id}`;
52936
53174
  if (entries.has(kind)) continue;
@@ -61562,7 +61800,8 @@ var CAP_TO_KIND = {
61562
61800
  cover: "cover",
61563
61801
  switch: "switch",
61564
61802
  button: "button",
61565
- doorbell: "doorbell"
61803
+ doorbell: "doorbell",
61804
+ "running-state": "appliance-cycle"
61566
61805
  };
61567
61806
  function buildDescriptor(capName, kind) {
61568
61807
  const t = EVENT_TAXONOMY[kind];
@@ -64692,10 +64931,7 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
64692
64931
  }), InstallPackageResultSchema, {
64693
64932
  kind: "mutation",
64694
64933
  auth: "admin"
64695
- }), method(object({ packageName: string() }), InstallPackageResultSchema, {
64696
- kind: "mutation",
64697
- auth: "admin"
64698
- }), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
64934
+ }), method(object({
64699
64935
  packageName: string().min(1),
64700
64936
  nodeId: string().optional(),
64701
64937
  everywhere: boolean().optional()
@@ -65956,19 +66192,19 @@ var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status:
65956
66192
  reason: _enum(["unknown-template", "not-a-media-player"]),
65957
66193
  detail: string()
65958
66194
  })]);
65959
- var deviceInput$1 = object({ deviceId: number$1().int().nonnegative() });
66195
+ var deviceInput = object({ deviceId: number$1().int().nonnegative() });
65960
66196
  DeviceType.MediaPlayer;
65961
- method(deviceInput$1, RemoteConfigSchema, { auth: "admin" }), method(deviceInput$1.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
66197
+ method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
65962
66198
  kind: "mutation",
65963
66199
  auth: "admin"
65964
- }), method(deviceInput$1, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput$1.extend({
66200
+ }), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
65965
66201
  role: RemoteRoleSchema,
65966
66202
  /** Sends in a row (volume steps). */
65967
66203
  repeat: number$1().int().min(1).max(50).default(1)
65968
66204
  }), RemoteSendResultSchema, {
65969
66205
  kind: "mutation",
65970
66206
  auth: "protected"
65971
- }), method(deviceInput$1.extend({
66207
+ }), method(deviceInput.extend({
65972
66208
  command: RemoteMediaCommandSchema,
65973
66209
  muted: boolean().optional(),
65974
66210
  source: string().optional(),
@@ -70297,117 +70533,6 @@ var lockControlCapability = {
70297
70533
  * whether persisting is worth a SQLite commit. */
70298
70534
  volatileStateFields: ["lastChangedAt"]
70299
70535
  };
70300
- var PowerSourceRefusalReasonSchema = _enum([
70301
- "no-power-source",
70302
- "switch-missing",
70303
- "switch-offline",
70304
- "switch-unknown",
70305
- "restart-in-progress",
70306
- "switch-call-failed"
70307
- ]);
70308
- var PowerSourceActionResultSchema = discriminatedUnion("accepted", [object({ accepted: literal(true) }), object({
70309
- accepted: literal(false),
70310
- reason: PowerSourceRefusalReasonSchema,
70311
- /** One line for the operator, naming the switch. */
70312
- message: string()
70313
- })]);
70314
- var PowerSourceInfoSchema = object({
70315
- /** False when the device has no power source linked; the rest is then empty. */
70316
- linked: boolean(),
70317
- switchDeviceId: number$1().nullable(),
70318
- switchName: string().nullable(),
70319
- /** The switch's on/off state, or null when it is unknown. Never false for unknown (D393). */
70320
- switchOn: boolean().nullable(),
70321
- switchOnline: boolean().nullable(),
70322
- restartInProgress: boolean(),
70323
- offSeconds: number$1().int()
70324
- });
70325
- /** The composed slice: the switch state the link mirrors, plus the stored off time. */
70326
- var PowerSourceStateSchema = object({
70327
- /** Null while the switch has not reported: unknown is never `false` (D393). */
70328
- switchOn: boolean().nullable(),
70329
- offSeconds: number$1().int(),
70330
- lastFetchedAt: number$1()
70331
- });
70332
- var POWER_SOURCE_DEVICE_TYPES = [
70333
- DeviceType.Gateway,
70334
- DeviceType.Hub,
70335
- DeviceType.Camera,
70336
- DeviceType.Sensor,
70337
- DeviceType.MediaPlayer,
70338
- DeviceType.Vacuum,
70339
- DeviceType.Generic,
70340
- DeviceType.Washer,
70341
- DeviceType.Dryer,
70342
- DeviceType.Dishwasher,
70343
- DeviceType.PetFountain,
70344
- DeviceType.Fan,
70345
- DeviceType.Humidifier,
70346
- DeviceType.Climate,
70347
- DeviceType.WaterHeater
70348
- ];
70349
- var powerSourceCustomize = {
70350
- version: 1,
70351
- targets: [{
70352
- id: "switch",
70353
- cardinality: "scalar",
70354
- vocabulary: {
70355
- cap: "power-source",
70356
- stateField: "switchOn"
70357
- },
70358
- deviceTypes: POWER_SOURCE_DEVICE_TYPES,
70359
- apply: "add",
70360
- path: "switchOn",
70361
- sources: [{
70362
- kind: "switch",
70363
- transforms: [{ kind: "identity" }]
70364
- }],
70365
- companions: [{
70366
- kind: "constant",
70367
- path: "offSeconds",
70368
- value: 10,
70369
- when: "add"
70370
- }, {
70371
- kind: "clock",
70372
- path: "lastFetchedAt",
70373
- when: "always"
70374
- }],
70375
- sourceReport: { status: "assignment-status" }
70376
- }]
70377
- };
70378
- var deviceInput = object({ deviceId: number$1().int().nonnegative() });
70379
- var powerSourceCapability = {
70380
- name: "power-source",
70381
- scope: "device",
70382
- mode: "singleton",
70383
- deviceTypes: POWER_SOURCE_DEVICE_TYPES,
70384
- methods: {
70385
- getStatus: systemMethod(deviceInput, PowerSourceInfoSchema, { auth: "admin" }),
70386
- powerOn: systemMethod(deviceInput, PowerSourceActionResultSchema, {
70387
- kind: "mutation",
70388
- auth: "admin"
70389
- }),
70390
- powerOff: systemMethod(deviceInput, PowerSourceActionResultSchema, {
70391
- kind: "mutation",
70392
- auth: "admin"
70393
- }),
70394
- forceRestart: systemMethod(deviceInput, PowerSourceActionResultSchema, {
70395
- kind: "mutation",
70396
- auth: "admin"
70397
- })
70398
- },
70399
- runtimeState: PowerSourceStateSchema,
70400
- customize: powerSourceCustomize,
70401
- /**
70402
- * Runtime-state durability: **session** — mirrored from the linked switch on
70403
- * its next report; a restored value would outlive the reading it names.
70404
- *
70405
- * See `RuntimeStateDurability`. Enforced by
70406
- * `scripts/check-runtime-state-durability.ts`.
70407
- */
70408
- durability: "session",
70409
- history: "none"
70410
- };
70411
70536
  /**
70412
70537
  * A monotonic total between resets (D944). Energy uses `power-meter.energy`
70413
70538
  * so dashboards keep one series; every other instantaneous reading lands here.
@@ -73949,6 +74074,10 @@ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
73949
74074
  /** Generic Customize target for the running boolean (D936). */
73950
74075
  var runningCustomize = {
73951
74076
  version: 1,
74077
+ overridable: [{
74078
+ path: "running",
74079
+ by: "running"
74080
+ }],
73952
74081
  targets: [{
73953
74082
  id: "running",
73954
74083
  cardinality: "scalar",
@@ -74006,7 +74135,7 @@ var runningCustomize = {
74006
74135
  kind: "constant",
74007
74136
  path: "phase",
74008
74137
  value: null,
74009
- when: "always"
74138
+ when: "add"
74010
74139
  },
74011
74140
  {
74012
74141
  kind: "clock",
@@ -77290,7 +77419,7 @@ var ExternalIdentityKeySchema = object({
77290
77419
  provider: string().min(1),
77291
77420
  subject: string().min(1)
77292
77421
  });
77293
- method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
77422
+ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(_void(), object({ defaultPasswordInUse: boolean() }), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
77294
77423
  kind: "mutation",
77295
77424
  auth: "admin",
77296
77425
  access: "create"
@@ -80629,13 +80758,6 @@ Object.freeze({
80629
80758
  access: "view",
80630
80759
  role: "admin"
80631
80760
  },
80632
- "addons.installFromWorkspace": {
80633
- capName: "addons",
80634
- capScope: "system",
80635
- addonId: null,
80636
- access: "create",
80637
- role: "admin"
80638
- },
80639
80761
  "addons.installPackage": {
80640
80762
  capName: "addons",
80641
80763
  capScope: "system",
@@ -80643,13 +80765,6 @@ Object.freeze({
80643
80765
  access: "create",
80644
80766
  role: "admin"
80645
80767
  },
80646
- "addons.isWorkspaceAvailable": {
80647
- capName: "addons",
80648
- capScope: "system",
80649
- addonId: null,
80650
- access: "view",
80651
- role: "admin"
80652
- },
80653
80768
  "addons.list": {
80654
80769
  capName: "addons",
80655
80770
  capScope: "system",
@@ -80699,13 +80814,6 @@ Object.freeze({
80699
80814
  access: "view",
80700
80815
  role: "admin"
80701
80816
  },
80702
- "addons.listWorkspacePackages": {
80703
- capName: "addons",
80704
- capScope: "system",
80705
- addonId: null,
80706
- access: "view",
80707
- role: "admin"
80708
- },
80709
80817
  "addons.onAddonLogs": {
80710
80818
  capName: "addons",
80711
80819
  capScope: "system",
@@ -83373,6 +83481,27 @@ Object.freeze({
83373
83481
  access: "create",
83374
83482
  role: "admin"
83375
83483
  },
83484
+ "deviceRuns.getCurrentRun": {
83485
+ capName: "device-runs",
83486
+ capScope: "device",
83487
+ addonId: null,
83488
+ access: "view",
83489
+ role: "viewer"
83490
+ },
83491
+ "deviceRuns.getRun": {
83492
+ capName: "device-runs",
83493
+ capScope: "device",
83494
+ addonId: null,
83495
+ access: "view",
83496
+ role: "viewer"
83497
+ },
83498
+ "deviceRuns.listRuns": {
83499
+ capName: "device-runs",
83500
+ capScope: "device",
83501
+ addonId: null,
83502
+ access: "view",
83503
+ role: "viewer"
83504
+ },
83376
83505
  "deviceState.claimFields": {
83377
83506
  capName: "device-state",
83378
83507
  capScope: "system",
@@ -90086,6 +90215,13 @@ Object.freeze({
90086
90215
  access: "view",
90087
90216
  role: "admin"
90088
90217
  },
90218
+ "userManagement.getAdminBootstrapStatus": {
90219
+ capName: "user-management",
90220
+ capScope: "system",
90221
+ addonId: null,
90222
+ access: "view",
90223
+ role: "admin"
90224
+ },
90089
90225
  "userManagement.getTotpStatus": {
90090
90226
  capName: "user-management",
90091
90227
  capScope: "system",
@@ -91571,6 +91707,21 @@ Object.freeze({
91571
91707
  form: "single",
91572
91708
  optional: false
91573
91709
  }],
91710
+ "deviceRuns.getCurrentRun": [{
91711
+ name: "deviceId",
91712
+ form: "single",
91713
+ optional: false
91714
+ }],
91715
+ "deviceRuns.getRun": [{
91716
+ name: "deviceId",
91717
+ form: "single",
91718
+ optional: false
91719
+ }],
91720
+ "deviceRuns.listRuns": [{
91721
+ name: "deviceId",
91722
+ form: "single",
91723
+ optional: false
91724
+ }],
91574
91725
  "deviceState.claimFields": [{
91575
91726
  name: "deviceId",
91576
91727
  form: "single",
@@ -94260,13 +94411,114 @@ NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
94260
94411
  *
94261
94412
  * Pure, RN-safe: the viewer imports the support rule from here.
94262
94413
  */
94414
+ /**
94415
+ * Control caps that still have a raise and a clear an operator names: an
94416
+ * appliance cycle raises when it STARTS and clears when it FINISHES. Kept out
94417
+ * of `SOURCE_CAP_ACTIVE_FIELD` on purpose — that table also makes a device a
94418
+ * camera-sensor / recorder-trigger source, and a dishwasher is neither.
94419
+ */
94420
+ var CYCLE_RAISED_FIELD_BY_CAP = { "running-state": "running" };
94263
94421
  /** Event kind → the boolean field of its cap slice that means "raised". */
94264
94422
  var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
94423
+ const cycleField = CYCLE_RAISED_FIELD_BY_CAP[capName];
94424
+ if (cycleField !== void 0) return [[descriptor.kind, cycleField]];
94265
94425
  const field = SOURCE_CAP_ACTIVE_FIELD[capName];
94266
94426
  if (field === void 0 || descriptor.category !== "sensor") return [];
94267
94427
  return [[descriptor.kind, field]];
94268
94428
  })));
94269
94429
  Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
94430
+ Object.freeze({
94431
+ contact: {
94432
+ starts: {
94433
+ en: "opened",
94434
+ it: "si apre"
94435
+ },
94436
+ finishes: {
94437
+ en: "closed",
94438
+ it: "si chiude"
94439
+ }
94440
+ },
94441
+ "motion-sensor": {
94442
+ starts: {
94443
+ en: "motion detected",
94444
+ it: "movimento rilevato"
94445
+ },
94446
+ finishes: {
94447
+ en: "motion stopped",
94448
+ it: "movimento terminato"
94449
+ }
94450
+ },
94451
+ smoke: {
94452
+ starts: {
94453
+ en: "smoke detected",
94454
+ it: "fumo rilevato"
94455
+ },
94456
+ finishes: {
94457
+ en: "smoke gone",
94458
+ it: "fumo scomparso"
94459
+ }
94460
+ },
94461
+ flood: {
94462
+ starts: {
94463
+ en: "water detected",
94464
+ it: "acqua rilevata"
94465
+ },
94466
+ finishes: {
94467
+ en: "dry again",
94468
+ it: "di nuovo asciutto"
94469
+ }
94470
+ },
94471
+ gas: {
94472
+ starts: {
94473
+ en: "gas detected",
94474
+ it: "gas rilevato"
94475
+ },
94476
+ finishes: {
94477
+ en: "gas gone",
94478
+ it: "gas scomparso"
94479
+ }
94480
+ },
94481
+ "carbon-monoxide": {
94482
+ starts: {
94483
+ en: "carbon monoxide detected",
94484
+ it: "monossido rilevato"
94485
+ },
94486
+ finishes: {
94487
+ en: "carbon monoxide gone",
94488
+ it: "monossido scomparso"
94489
+ }
94490
+ },
94491
+ vibration: {
94492
+ starts: {
94493
+ en: "vibration detected",
94494
+ it: "vibrazione rilevata"
94495
+ },
94496
+ finishes: {
94497
+ en: "vibration stopped",
94498
+ it: "vibrazione terminata"
94499
+ }
94500
+ },
94501
+ tamper: {
94502
+ starts: {
94503
+ en: "tampered with",
94504
+ it: "manomesso"
94505
+ },
94506
+ finishes: {
94507
+ en: "tamper cleared",
94508
+ it: "manomissione rientrata"
94509
+ }
94510
+ },
94511
+ "appliance-cycle": {
94512
+ starts: {
94513
+ en: "the cycle started",
94514
+ it: "il ciclo parte"
94515
+ },
94516
+ finishes: {
94517
+ en: "the cycle finished",
94518
+ it: "il ciclo è terminato"
94519
+ }
94520
+ }
94521
+ });
94270
94522
  object({
94271
94523
  phase: _enum(["raised", "resolved"]),
94272
94524
  episodeId: string().min(1),
@@ -94473,6 +94725,10 @@ var STATE_SUMMARY_VARS = [
94473
94725
  [...RULE_TEXT],
94474
94726
  [...RULE_TEXT],
94475
94727
  [...RULE_TEXT],
94728
+ [...RULE_TEXT],
94729
+ [...RULE_TEXT],
94730
+ [...RULE_TEXT],
94731
+ [...RULE_TEXT],
94476
94732
  [...RULE_BODY_ONLY],
94477
94733
  [...RULE_TEXT],
94478
94734
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
@@ -94490,6 +94746,7 @@ var STATE_SUMMARY_VARS = [
94490
94746
  [...RULE_TEXT],
94491
94747
  [...RULE_TEXT],
94492
94748
  [...RULE_TEXT],
94749
+ [...RULE_TEXT],
94493
94750
  ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
94494
94751
  [...RULE_TEXT],
94495
94752
  [...RULE_TEXT],
@@ -94734,6 +94991,7 @@ new Set([
94734
94991
  "siren",
94735
94992
  "button",
94736
94993
  "doorbell",
94994
+ "appliance-cycle",
94737
94995
  "audio-speech",
94738
94996
  "audio-scream",
94739
94997
  "audio-crying",
@@ -133240,6 +133498,7 @@ var require_proxy = /* @__PURE__ */ __commonJSMin(((exports, module) => {
133240
133498
  _options.proxyLogLevel === "debug" && _options.logger && _options.logger(`Alexa-Cookie: Proxy-Request: (modified:${modified})${customStringify(proxyReq, null, 2)}`);
133241
133499
  }
133242
133500
  function onProxyRes(proxyRes, req, res) {
133501
+ stripUpgradeInsecureRequestsHeaders(proxyRes);
133243
133502
  const url = req.originalUrl || req.url;
133244
133503
  if (url.endsWith(".ico") || url.endsWith(".js") || url.endsWith(".ttf") || url.endsWith(".svg") || url.endsWith(".png") || url.endsWith(".appcache")) return;
133245
133504
  if (url.startsWith("/ap/uedata")) return;
@@ -133332,7 +133591,18 @@ var require_proxy = /* @__PURE__ */ __commonJSMin(((exports, module) => {
133332
133591
  callbackListening = null;
133333
133592
  });
133334
133593
  }
133594
+ function stripUpgradeInsecureRequestsHeaders(proxyRes) {
133595
+ const headers = proxyRes && proxyRes.headers;
133596
+ if (!headers) return;
133597
+ for (const name of ["content-security-policy", "content-security-policy-report-only"]) {
133598
+ if (headers[name] === void 0) continue;
133599
+ const kept = (Array.isArray(headers[name]) ? headers[name] : [headers[name]]).map((v) => String(v).split(";").map((d) => d.trim()).filter((d) => d && !/^upgrade-insecure-requests$/i.test(d)).join("; ")).filter((v) => v);
133600
+ if (kept.length) headers[name] = kept.length === 1 ? kept[0] : kept;
133601
+ else delete headers[name];
133602
+ }
133603
+ }
133335
133604
  module.exports.initAmazonProxy = initAmazonProxy;
133605
+ module.exports.stripUpgradeInsecureRequestsHeaders = stripUpgradeInsecureRequestsHeaders;
133336
133606
  }));
133337
133607
  //#endregion
133338
133608
  //#region ../../node_modules/alexa-cookie2/alexa-cookie.js
@@ -138960,7 +139230,30 @@ var AlexaRemoteClient = class {
138960
139230
  async pollStates(applianceIds) {
138961
139231
  if (applianceIds.length === 0) return [];
138962
139232
  const remote = this.#requireRemote();
138963
- return decodeSmarthomeStates(await this.#withBackoff("querySmarthomeDevices", () => this.#querySmarthomeDevices(remote, applianceIds)));
139233
+ const values = [];
139234
+ let failedChunks = 0;
139235
+ let lastError = null;
139236
+ let chunks = 0;
139237
+ for (let start = 0; start < applianceIds.length; start += 50) {
139238
+ const chunk = applianceIds.slice(start, start + 50);
139239
+ chunks += 1;
139240
+ try {
139241
+ const body = await this.#withBackoff("querySmarthomeDevices", () => this.#querySmarthomeDevices(remote, chunk));
139242
+ values.push(...decodeSmarthomeStates(body));
139243
+ } catch (err) {
139244
+ if (err instanceof AlexaAuthError) throw err;
139245
+ failedChunks += 1;
139246
+ lastError = err;
139247
+ this.#logger?.warn("AlexaRemoteClient: state query chunk failed", { meta: {
139248
+ brokerId: this.#options.brokerId,
139249
+ chunkSize: chunk.length,
139250
+ firstId: chunk[0],
139251
+ error: errMsg(err)
139252
+ } });
139253
+ }
139254
+ }
139255
+ if (failedChunks === chunks) throw lastError instanceof Error ? lastError : /* @__PURE__ */ new Error("AlexaRemoteClient: state poll failed");
139256
+ return values;
138964
139257
  }
138965
139258
  async sendCommand(command) {
138966
139259
  const remote = this.#requireRemote();
@@ -139423,7 +139716,7 @@ var AlexaIntegrationManager = class {
139423
139716
  httpStatus
139424
139717
  }
139425
139718
  });
139426
- if (this.#pollFailures >= 3 && this.#status !== "disconnected") this.#transition(err instanceof AlexaAuthError ? "auth-failed" : "error");
139719
+ if (err instanceof AlexaAuthError && this.#pollFailures >= 3 && this.#status !== "disconnected") this.#transition("auth-failed");
139427
139720
  }
139428
139721
  }
139429
139722
  #transition(next) {
@@ -140954,7 +141247,7 @@ var BrokerEcho = class {
140954
141247
  try {
140955
141248
  this.currentDevices = [...parseDevices(await this.deps.worker.request({ op: "devices" }))];
140956
141249
  } catch (err) {
140957
- this.deps.logger.warn("alexa speak: device refresh failed", {
141250
+ this.deps.logger.warn("alexa speak: step 3 of 3, device list failed after a good sign-in", {
140958
141251
  tags: { brokerId: this.deps.brokerId },
140959
141252
  meta: { error: err instanceof Error ? err.message : String(err) }
140960
141253
  });
@@ -141484,6 +141777,7 @@ function createAlexaNotificationProvider(ports) {
141484
141777
  return found;
141485
141778
  },
141486
141779
  async discoverTargets(input) {
141780
+ for (const broker of ports.brokers()) if (!broker.ready) ports.logger.warn(`alexa echo discovery: no Echo listed for '${broker.name}', the Amazon account is not signed in for this broker`, { tags: { brokerId: broker.id } });
141487
141781
  const named = readString(input.config ?? {}, "brokerId");
141488
141782
  if (named.length > 0) {
141489
141783
  const owner = ports.brokers().find((broker) => broker.id === named);