@camstack/addon-agent-ui 1.2.289 → 1.2.291
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/addon.js +491 -12
- package/dist/assets/{MotionZonesSettings-DnGHT5t2.js → MotionZonesSettings-CZjGn6Tv.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-BM6ayl_M.js → PrivacyMaskSettings-C6bKBK8X.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-oFV44WN9.js → SceneMonitorEditor-i5kjOwvb.js} +1 -1
- package/dist/assets/index-DnGUjzQE.js +112 -0
- package/dist/assets/index-omoTnqTC.css +2 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/assets/index-DpdEPBa7.js +0 -112
- package/dist/assets/index-So27-K6L.css +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.291] - 2026-10-29
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Rebuilt against updated dependencies.
|
|
15
|
+
|
|
16
|
+
## [1.2.290] - 2026-10-29
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Rebuilt against updated dependencies.
|
|
21
|
+
|
|
10
22
|
## [1.2.289] - 2026-10-28
|
|
11
23
|
|
|
12
24
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -5448,7 +5448,7 @@ var ZodIssueCode = {
|
|
|
5448
5448
|
var ZodFirstPartyTypeKind;
|
|
5449
5449
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5450
5450
|
//#endregion
|
|
5451
|
-
//#region ../types/dist/sleep-
|
|
5451
|
+
//#region ../types/dist/sleep-C_u6cEAJ.mjs
|
|
5452
5452
|
/**
|
|
5453
5453
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5454
5454
|
* window to float samples (D455).
|
|
@@ -8629,6 +8629,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8629
8629
|
"network-link",
|
|
8630
8630
|
"network-quality",
|
|
8631
8631
|
"node-certificates",
|
|
8632
|
+
"node-removal-hook",
|
|
8632
8633
|
"nodes",
|
|
8633
8634
|
"notification-output",
|
|
8634
8635
|
"notification-rules",
|
|
@@ -8659,6 +8660,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8659
8660
|
"recording-onboard",
|
|
8660
8661
|
"recording-signal",
|
|
8661
8662
|
"records",
|
|
8663
|
+
"remote",
|
|
8662
8664
|
"running-state",
|
|
8663
8665
|
"scene-monitor",
|
|
8664
8666
|
"script-runner",
|
|
@@ -8682,6 +8684,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
8682
8684
|
"system",
|
|
8683
8685
|
"tamper",
|
|
8684
8686
|
"temperature-sensor",
|
|
8687
|
+
"template",
|
|
8685
8688
|
"terminal-session",
|
|
8686
8689
|
"toast",
|
|
8687
8690
|
"training",
|
|
@@ -9622,6 +9625,11 @@ Object.freeze({
|
|
|
9622
9625
|
"standby"
|
|
9623
9626
|
]
|
|
9624
9627
|
},
|
|
9628
|
+
{
|
|
9629
|
+
"path": "stateSource",
|
|
9630
|
+
"valueType": "enum",
|
|
9631
|
+
"enumValues": ["reported", "assumed"]
|
|
9632
|
+
},
|
|
9625
9633
|
{
|
|
9626
9634
|
"path": "volumeLevel",
|
|
9627
9635
|
"valueType": "number"
|
|
@@ -9897,6 +9905,18 @@ Object.freeze({
|
|
|
9897
9905
|
{
|
|
9898
9906
|
"path": "volume",
|
|
9899
9907
|
"valueType": "number"
|
|
9908
|
+
},
|
|
9909
|
+
{
|
|
9910
|
+
"path": "lastFeedGrams",
|
|
9911
|
+
"valueType": "number"
|
|
9912
|
+
},
|
|
9913
|
+
{
|
|
9914
|
+
"path": "lastFeedHopper1",
|
|
9915
|
+
"valueType": "number"
|
|
9916
|
+
},
|
|
9917
|
+
{
|
|
9918
|
+
"path": "lastFeedHopper2",
|
|
9919
|
+
"valueType": "number"
|
|
9900
9920
|
}
|
|
9901
9921
|
],
|
|
9902
9922
|
"power-meter": [
|
|
@@ -10788,7 +10808,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10788
10808
|
return DeviceRole;
|
|
10789
10809
|
}({});
|
|
10790
10810
|
//#endregion
|
|
10791
|
-
//#region ../types/dist/composition-
|
|
10811
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
10792
10812
|
/**
|
|
10793
10813
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10794
10814
|
*
|
|
@@ -42351,6 +42371,14 @@ method(object({
|
|
|
42351
42371
|
kind: "mutation",
|
|
42352
42372
|
auth: "admin"
|
|
42353
42373
|
});
|
|
42374
|
+
method(object({
|
|
42375
|
+
nodeId: string().min(1),
|
|
42376
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
42377
|
+
removedAt: number()
|
|
42378
|
+
}), object({ counts: record(string(), number().int().nonnegative()) }), {
|
|
42379
|
+
kind: "mutation",
|
|
42380
|
+
auth: "admin"
|
|
42381
|
+
});
|
|
42354
42382
|
/**
|
|
42355
42383
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
42356
42384
|
* so it can delete what it keeps for that device (D865).
|
|
@@ -57363,6 +57391,318 @@ DeviceType.Light, method(object({
|
|
|
57363
57391
|
level: number().min(0).max(100),
|
|
57364
57392
|
lastChangedAt: number()
|
|
57365
57393
|
});
|
|
57394
|
+
/**
|
|
57395
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
57396
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
57397
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
57398
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
57399
|
+
*
|
|
57400
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
57401
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
57402
|
+
*/
|
|
57403
|
+
var REMOTE_KNOWN_ROLES = [
|
|
57404
|
+
"power",
|
|
57405
|
+
"power_on",
|
|
57406
|
+
"power_off",
|
|
57407
|
+
"volume_up",
|
|
57408
|
+
"volume_down",
|
|
57409
|
+
"mute",
|
|
57410
|
+
"channel_up",
|
|
57411
|
+
"channel_down",
|
|
57412
|
+
"up",
|
|
57413
|
+
"down",
|
|
57414
|
+
"left",
|
|
57415
|
+
"right",
|
|
57416
|
+
"ok",
|
|
57417
|
+
"back",
|
|
57418
|
+
"home",
|
|
57419
|
+
"menu",
|
|
57420
|
+
"info",
|
|
57421
|
+
"guide",
|
|
57422
|
+
"exit",
|
|
57423
|
+
"input",
|
|
57424
|
+
"play",
|
|
57425
|
+
"pause",
|
|
57426
|
+
"play_pause",
|
|
57427
|
+
"stop",
|
|
57428
|
+
"next",
|
|
57429
|
+
"previous",
|
|
57430
|
+
"fast_forward",
|
|
57431
|
+
"rewind",
|
|
57432
|
+
"digit_0",
|
|
57433
|
+
"digit_1",
|
|
57434
|
+
"digit_2",
|
|
57435
|
+
"digit_3",
|
|
57436
|
+
"digit_4",
|
|
57437
|
+
"digit_5",
|
|
57438
|
+
"digit_6",
|
|
57439
|
+
"digit_7",
|
|
57440
|
+
"digit_8",
|
|
57441
|
+
"digit_9"
|
|
57442
|
+
];
|
|
57443
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
57444
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
57445
|
+
function isRemoteKnownRole(value) {
|
|
57446
|
+
return KNOWN_ROLES.has(value);
|
|
57447
|
+
}
|
|
57448
|
+
function isRemoteCustomKey(key) {
|
|
57449
|
+
return CUSTOM_KEY_RE.test(key);
|
|
57450
|
+
}
|
|
57451
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
57452
|
+
function customKeyOfRole(role) {
|
|
57453
|
+
if (!role.startsWith("custom:")) return null;
|
|
57454
|
+
const key = role.slice(7);
|
|
57455
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
57456
|
+
}
|
|
57457
|
+
function isRemoteRole(value) {
|
|
57458
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
57459
|
+
}
|
|
57460
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
57461
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
57462
|
+
var RemoteCustomButtonSchema = object({
|
|
57463
|
+
/** The slug after `custom:` in the role. */
|
|
57464
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
57465
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
57466
|
+
name: string().min(1).max(60)
|
|
57467
|
+
});
|
|
57468
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
57469
|
+
var RemoteConfigSchema = object({
|
|
57470
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
57471
|
+
/**
|
|
57472
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
57473
|
+
* names its own device, so one command may override it.
|
|
57474
|
+
*/
|
|
57475
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
57476
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
57477
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
57478
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
57479
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
57480
|
+
}).superRefine((config, ctx) => {
|
|
57481
|
+
const roles = Object.keys(config.bindings);
|
|
57482
|
+
if (roles.length > 200) ctx.addIssue({
|
|
57483
|
+
code: "custom",
|
|
57484
|
+
message: "too many bindings",
|
|
57485
|
+
path: ["bindings"]
|
|
57486
|
+
});
|
|
57487
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
57488
|
+
code: "custom",
|
|
57489
|
+
message: `"${role}" is not a role`,
|
|
57490
|
+
path: ["bindings", role]
|
|
57491
|
+
});
|
|
57492
|
+
const keys = /* @__PURE__ */ new Set();
|
|
57493
|
+
config.customButtons.forEach((button, index) => {
|
|
57494
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
57495
|
+
code: "custom",
|
|
57496
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
57497
|
+
path: [
|
|
57498
|
+
"customButtons",
|
|
57499
|
+
index,
|
|
57500
|
+
"key"
|
|
57501
|
+
]
|
|
57502
|
+
});
|
|
57503
|
+
keys.add(button.key);
|
|
57504
|
+
});
|
|
57505
|
+
for (const role of roles) {
|
|
57506
|
+
const key = customKeyOfRole(role);
|
|
57507
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
57508
|
+
code: "custom",
|
|
57509
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
57510
|
+
path: ["bindings", role]
|
|
57511
|
+
});
|
|
57512
|
+
}
|
|
57513
|
+
});
|
|
57514
|
+
object({
|
|
57515
|
+
power: object({
|
|
57516
|
+
state: _enum(["on", "off"]),
|
|
57517
|
+
at: number()
|
|
57518
|
+
}).nullable(),
|
|
57519
|
+
muted: object({
|
|
57520
|
+
value: boolean(),
|
|
57521
|
+
at: number()
|
|
57522
|
+
}).nullable()
|
|
57523
|
+
});
|
|
57524
|
+
var RemoteLayoutButtonSchema = object({
|
|
57525
|
+
id: string().min(1).max(40),
|
|
57526
|
+
/** 0-based grid position. */
|
|
57527
|
+
row: number().int().min(0).max(24),
|
|
57528
|
+
col: number().int().min(0).max(24),
|
|
57529
|
+
rowSpan: number().int().min(1).max(24),
|
|
57530
|
+
colSpan: number().int().min(1).max(24),
|
|
57531
|
+
icon: string().min(1).max(60).optional(),
|
|
57532
|
+
label: string().min(1).max(40).optional(),
|
|
57533
|
+
role: RemoteRoleSchema
|
|
57534
|
+
});
|
|
57535
|
+
object({
|
|
57536
|
+
columns: number().int().min(1).max(24),
|
|
57537
|
+
rows: number().int().min(1).max(24),
|
|
57538
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
57539
|
+
}).superRefine((grid, ctx) => {
|
|
57540
|
+
const ids = /* @__PURE__ */ new Set();
|
|
57541
|
+
const taken = /* @__PURE__ */ new Map();
|
|
57542
|
+
grid.buttons.forEach((button, index) => {
|
|
57543
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
57544
|
+
code: "custom",
|
|
57545
|
+
message: `button id "${button.id}" is used twice`,
|
|
57546
|
+
path: [
|
|
57547
|
+
"buttons",
|
|
57548
|
+
index,
|
|
57549
|
+
"id"
|
|
57550
|
+
]
|
|
57551
|
+
});
|
|
57552
|
+
ids.add(button.id);
|
|
57553
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
57554
|
+
ctx.addIssue({
|
|
57555
|
+
code: "custom",
|
|
57556
|
+
message: `button "${button.id}" leaves the grid`,
|
|
57557
|
+
path: ["buttons", index]
|
|
57558
|
+
});
|
|
57559
|
+
return;
|
|
57560
|
+
}
|
|
57561
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
57562
|
+
const cell = `${r}:${c}`;
|
|
57563
|
+
const other = taken.get(cell);
|
|
57564
|
+
if (other !== void 0) {
|
|
57565
|
+
ctx.addIssue({
|
|
57566
|
+
code: "custom",
|
|
57567
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
57568
|
+
path: ["buttons", index]
|
|
57569
|
+
});
|
|
57570
|
+
return;
|
|
57571
|
+
}
|
|
57572
|
+
taken.set(cell, button.id);
|
|
57573
|
+
}
|
|
57574
|
+
});
|
|
57575
|
+
});
|
|
57576
|
+
var RemoteBoundCommandSchema = object({
|
|
57577
|
+
role: RemoteRoleSchema,
|
|
57578
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
57579
|
+
label: string().optional(),
|
|
57580
|
+
custom: boolean()
|
|
57581
|
+
});
|
|
57582
|
+
var RemoteCommandListSchema = object({
|
|
57583
|
+
layoutTemplateId: string().nullable(),
|
|
57584
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
57585
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
57586
|
+
commands: array(RemoteBoundCommandSchema)
|
|
57587
|
+
});
|
|
57588
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
57589
|
+
"no-remote",
|
|
57590
|
+
"unbound-role",
|
|
57591
|
+
"action-failed"
|
|
57592
|
+
]);
|
|
57593
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
57594
|
+
object({
|
|
57595
|
+
status: literal("sent"),
|
|
57596
|
+
/** How many times the action ran. */
|
|
57597
|
+
sends: number().int().min(1)
|
|
57598
|
+
}),
|
|
57599
|
+
object({
|
|
57600
|
+
status: literal("skipped"),
|
|
57601
|
+
reason: literal("already-in-state")
|
|
57602
|
+
}),
|
|
57603
|
+
object({
|
|
57604
|
+
status: literal("refused"),
|
|
57605
|
+
reason: RemoteRefusalReasonSchema,
|
|
57606
|
+
detail: string().optional()
|
|
57607
|
+
})
|
|
57608
|
+
]);
|
|
57609
|
+
var RemoteMediaCommandSchema = _enum([
|
|
57610
|
+
"play",
|
|
57611
|
+
"pause",
|
|
57612
|
+
"stop",
|
|
57613
|
+
"next",
|
|
57614
|
+
"previous",
|
|
57615
|
+
"setMute",
|
|
57616
|
+
"selectSource"
|
|
57617
|
+
]);
|
|
57618
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
57619
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
57620
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
57621
|
+
status: literal("refused"),
|
|
57622
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
57623
|
+
detail: string()
|
|
57624
|
+
})]);
|
|
57625
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
57626
|
+
DeviceType.MediaPlayer;
|
|
57627
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
57628
|
+
kind: "mutation",
|
|
57629
|
+
auth: "admin"
|
|
57630
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
57631
|
+
role: RemoteRoleSchema,
|
|
57632
|
+
/** Sends in a row (volume steps). */
|
|
57633
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
57634
|
+
}), RemoteSendResultSchema, {
|
|
57635
|
+
kind: "mutation",
|
|
57636
|
+
auth: "protected"
|
|
57637
|
+
}), method(deviceInput.extend({
|
|
57638
|
+
command: RemoteMediaCommandSchema,
|
|
57639
|
+
muted: boolean().optional(),
|
|
57640
|
+
source: string().optional(),
|
|
57641
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
57642
|
+
}), RemoteMediaCommandResultSchema, {
|
|
57643
|
+
kind: "mutation",
|
|
57644
|
+
auth: "protected"
|
|
57645
|
+
});
|
|
57646
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
57647
|
+
/**
|
|
57648
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
57649
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
57650
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
57651
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
57652
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
57653
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
57654
|
+
*
|
|
57655
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
57656
|
+
* devices that still use a template, without parsing text.
|
|
57657
|
+
*/
|
|
57658
|
+
var TemplateRecordSchema = object({
|
|
57659
|
+
id: string().min(1),
|
|
57660
|
+
kind: TemplateKindSchema,
|
|
57661
|
+
name: string().min(1).max(120),
|
|
57662
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
57663
|
+
payload: unknown(),
|
|
57664
|
+
createdAt: number(),
|
|
57665
|
+
updatedAt: number()
|
|
57666
|
+
});
|
|
57667
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
57668
|
+
status: literal("saved"),
|
|
57669
|
+
template: TemplateRecordSchema
|
|
57670
|
+
}), object({
|
|
57671
|
+
status: literal("refused"),
|
|
57672
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
57673
|
+
detail: string()
|
|
57674
|
+
})]);
|
|
57675
|
+
/** A device still pointing at a template. */
|
|
57676
|
+
var TemplateUserSchema = object({
|
|
57677
|
+
deviceId: number().int().nonnegative(),
|
|
57678
|
+
name: string()
|
|
57679
|
+
});
|
|
57680
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
57681
|
+
object({ status: literal("deleted") }),
|
|
57682
|
+
object({ status: literal("not-found") }),
|
|
57683
|
+
object({
|
|
57684
|
+
status: literal("in-use"),
|
|
57685
|
+
devices: array(TemplateUserSchema).min(1)
|
|
57686
|
+
})
|
|
57687
|
+
]);
|
|
57688
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
57689
|
+
kind: TemplateKindSchema,
|
|
57690
|
+
name: string().min(1).max(120),
|
|
57691
|
+
payload: unknown()
|
|
57692
|
+
}), TemplateWriteResultSchema, {
|
|
57693
|
+
kind: "mutation",
|
|
57694
|
+
auth: "admin"
|
|
57695
|
+
}), method(object({
|
|
57696
|
+
id: string().min(1),
|
|
57697
|
+
name: string().min(1).max(120).optional(),
|
|
57698
|
+
payload: unknown().optional()
|
|
57699
|
+
}), TemplateWriteResultSchema, {
|
|
57700
|
+
kind: "mutation",
|
|
57701
|
+
auth: "admin"
|
|
57702
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
57703
|
+
kind: "mutation",
|
|
57704
|
+
auth: "admin"
|
|
57705
|
+
});
|
|
57366
57706
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
57367
57707
|
kind: "mutation",
|
|
57368
57708
|
auth: "protected"
|
|
@@ -60112,9 +60452,35 @@ var MediaInfoSchema = object({
|
|
|
60112
60452
|
/** Optional cover-art / thumbnail URL. */
|
|
60113
60453
|
imageUrl: string().optional()
|
|
60114
60454
|
});
|
|
60455
|
+
/**
|
|
60456
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
60457
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
60458
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
60459
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
60460
|
+
* guess, never as a reading.
|
|
60461
|
+
*/
|
|
60462
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
60463
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
60464
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
60465
|
+
"state",
|
|
60466
|
+
"volumeLevel",
|
|
60467
|
+
"isMuted",
|
|
60468
|
+
"source"
|
|
60469
|
+
]);
|
|
60115
60470
|
object({
|
|
60116
60471
|
/** Playback lifecycle state. */
|
|
60117
60472
|
state: MediaPlayerStateSchema,
|
|
60473
|
+
/**
|
|
60474
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
60475
|
+
* A slice written before this field existed parses as `reported`.
|
|
60476
|
+
*/
|
|
60477
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
60478
|
+
/**
|
|
60479
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
60480
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
60481
|
+
* from a running-state source, mute guessed from the last send).
|
|
60482
|
+
*/
|
|
60483
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
60118
60484
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
60119
60485
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
60120
60486
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61555,6 +61921,14 @@ object({
|
|
|
61555
61921
|
feedSound: boolean(),
|
|
61556
61922
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
61557
61923
|
volume: number().meta(readingMeta("none")),
|
|
61924
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
61925
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
61926
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
61927
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
61928
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
61929
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
61930
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
61931
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
61558
61932
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
61559
61933
|
lastFetchedAt: number()
|
|
61560
61934
|
});
|
|
@@ -66196,9 +66570,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
66196
66570
|
kind: "mutation",
|
|
66197
66571
|
auth: "admin"
|
|
66198
66572
|
});
|
|
66573
|
+
discriminatedUnion("kind", [object({
|
|
66574
|
+
kind: literal("raw"),
|
|
66575
|
+
timings: array(number().int()),
|
|
66576
|
+
settings: TransmitSettingsSchema.optional()
|
|
66577
|
+
}), object({
|
|
66578
|
+
kind: literal("pronto"),
|
|
66579
|
+
code: string()
|
|
66580
|
+
})]);
|
|
66199
66581
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
66200
66582
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
66201
|
-
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.Dishwasher, DeviceType.Washer, DeviceType.Dryer, 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.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
66583
|
+
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.Dishwasher, DeviceType.Washer, DeviceType.Dryer, 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;
|
|
66202
66584
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
66203
66585
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
66204
66586
|
new Set(CAP_NAMES);
|
|
@@ -71049,6 +71431,13 @@ Object.freeze({
|
|
|
71049
71431
|
access: "create",
|
|
71050
71432
|
role: "admin"
|
|
71051
71433
|
},
|
|
71434
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
71435
|
+
capName: "node-removal-hook",
|
|
71436
|
+
capScope: "system",
|
|
71437
|
+
addonId: null,
|
|
71438
|
+
access: "create",
|
|
71439
|
+
role: "admin"
|
|
71440
|
+
},
|
|
71052
71441
|
"nodes.clusterAddonStatus": {
|
|
71053
71442
|
capName: "nodes",
|
|
71054
71443
|
capScope: "system",
|
|
@@ -73940,6 +74329,41 @@ Object.freeze({
|
|
|
73940
74329
|
access: "create",
|
|
73941
74330
|
role: "admin"
|
|
73942
74331
|
},
|
|
74332
|
+
"remote.getConfig": {
|
|
74333
|
+
capName: "remote",
|
|
74334
|
+
capScope: "system",
|
|
74335
|
+
addonId: null,
|
|
74336
|
+
access: "view",
|
|
74337
|
+
role: "admin"
|
|
74338
|
+
},
|
|
74339
|
+
"remote.listCommands": {
|
|
74340
|
+
capName: "remote",
|
|
74341
|
+
capScope: "system",
|
|
74342
|
+
addonId: null,
|
|
74343
|
+
access: "view",
|
|
74344
|
+
role: "admin"
|
|
74345
|
+
},
|
|
74346
|
+
"remote.sendCommand": {
|
|
74347
|
+
capName: "remote",
|
|
74348
|
+
capScope: "system",
|
|
74349
|
+
addonId: null,
|
|
74350
|
+
access: "create",
|
|
74351
|
+
role: "admin"
|
|
74352
|
+
},
|
|
74353
|
+
"remote.sendMediaCommand": {
|
|
74354
|
+
capName: "remote",
|
|
74355
|
+
capScope: "system",
|
|
74356
|
+
addonId: null,
|
|
74357
|
+
access: "create",
|
|
74358
|
+
role: "admin"
|
|
74359
|
+
},
|
|
74360
|
+
"remote.setConfig": {
|
|
74361
|
+
capName: "remote",
|
|
74362
|
+
capScope: "system",
|
|
74363
|
+
addonId: null,
|
|
74364
|
+
access: "create",
|
|
74365
|
+
role: "admin"
|
|
74366
|
+
},
|
|
73943
74367
|
"runningState.getStatus": {
|
|
73944
74368
|
capName: "running-state",
|
|
73945
74369
|
capScope: "device",
|
|
@@ -75130,6 +75554,41 @@ Object.freeze({
|
|
|
75130
75554
|
access: "view",
|
|
75131
75555
|
role: "viewer"
|
|
75132
75556
|
},
|
|
75557
|
+
"template.create": {
|
|
75558
|
+
capName: "template",
|
|
75559
|
+
capScope: "system",
|
|
75560
|
+
addonId: null,
|
|
75561
|
+
access: "create",
|
|
75562
|
+
role: "admin"
|
|
75563
|
+
},
|
|
75564
|
+
"template.delete": {
|
|
75565
|
+
capName: "template",
|
|
75566
|
+
capScope: "system",
|
|
75567
|
+
addonId: null,
|
|
75568
|
+
access: "delete",
|
|
75569
|
+
role: "admin"
|
|
75570
|
+
},
|
|
75571
|
+
"template.get": {
|
|
75572
|
+
capName: "template",
|
|
75573
|
+
capScope: "system",
|
|
75574
|
+
addonId: null,
|
|
75575
|
+
access: "view",
|
|
75576
|
+
role: "admin"
|
|
75577
|
+
},
|
|
75578
|
+
"template.list": {
|
|
75579
|
+
capName: "template",
|
|
75580
|
+
capScope: "system",
|
|
75581
|
+
addonId: null,
|
|
75582
|
+
access: "view",
|
|
75583
|
+
role: "admin"
|
|
75584
|
+
},
|
|
75585
|
+
"template.update": {
|
|
75586
|
+
capName: "template",
|
|
75587
|
+
capScope: "system",
|
|
75588
|
+
addonId: null,
|
|
75589
|
+
access: "create",
|
|
75590
|
+
role: "admin"
|
|
75591
|
+
},
|
|
75133
75592
|
"terminalSession.adoptLegacyMonitor": {
|
|
75134
75593
|
capName: "terminal-session",
|
|
75135
75594
|
capScope: "system",
|
|
@@ -79922,6 +80381,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
79922
80381
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
79923
80382
|
"device-provider": system(INTERNAL),
|
|
79924
80383
|
"device-removal-hook": system(INTERNAL),
|
|
80384
|
+
"node-removal-hook": system(INTERNAL),
|
|
79925
80385
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
79926
80386
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
79927
80387
|
"embedding-encoder": system(ML),
|
|
@@ -79961,6 +80421,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
79961
80421
|
"recording-archive": system(STORAGE),
|
|
79962
80422
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
79963
80423
|
records: system(INTERNAL),
|
|
80424
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
79964
80425
|
"server-management": system(CLUSTER),
|
|
79965
80426
|
"settings-store": system(INTERNAL),
|
|
79966
80427
|
"smtp-provider": system(INTERNAL),
|
|
@@ -79973,6 +80434,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
79973
80434
|
"storage-provider": system(STORAGE),
|
|
79974
80435
|
"stream-broker": system(PIPELINE),
|
|
79975
80436
|
system: system(CLUSTER),
|
|
80437
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
79976
80438
|
"terminal-session": system(CLUSTER),
|
|
79977
80439
|
toast: system(UI_PLUMBING),
|
|
79978
80440
|
training: system(ML),
|
|
@@ -82399,6 +82861,31 @@ Object.freeze({
|
|
|
82399
82861
|
form: "single",
|
|
82400
82862
|
optional: true
|
|
82401
82863
|
}],
|
|
82864
|
+
"remote.getConfig": [{
|
|
82865
|
+
name: "deviceId",
|
|
82866
|
+
form: "single",
|
|
82867
|
+
optional: false
|
|
82868
|
+
}],
|
|
82869
|
+
"remote.listCommands": [{
|
|
82870
|
+
name: "deviceId",
|
|
82871
|
+
form: "single",
|
|
82872
|
+
optional: false
|
|
82873
|
+
}],
|
|
82874
|
+
"remote.sendCommand": [{
|
|
82875
|
+
name: "deviceId",
|
|
82876
|
+
form: "single",
|
|
82877
|
+
optional: false
|
|
82878
|
+
}],
|
|
82879
|
+
"remote.sendMediaCommand": [{
|
|
82880
|
+
name: "deviceId",
|
|
82881
|
+
form: "single",
|
|
82882
|
+
optional: false
|
|
82883
|
+
}],
|
|
82884
|
+
"remote.setConfig": [{
|
|
82885
|
+
name: "deviceId",
|
|
82886
|
+
form: "single",
|
|
82887
|
+
optional: false
|
|
82888
|
+
}],
|
|
82402
82889
|
"runningState.getStatus": [{
|
|
82403
82890
|
name: "deviceId",
|
|
82404
82891
|
form: "single",
|
|
@@ -84207,14 +84694,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
84207
84694
|
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
84208
84695
|
var MB = 1024 * 1024;
|
|
84209
84696
|
1024 * MB, 3072 * MB;
|
|
84210
|
-
discriminatedUnion("kind", [object({
|
|
84211
|
-
kind: literal("raw"),
|
|
84212
|
-
timings: array(number().int()),
|
|
84213
|
-
settings: TransmitSettingsSchema.optional()
|
|
84214
|
-
}), object({
|
|
84215
|
-
kind: literal("pronto"),
|
|
84216
|
-
code: string()
|
|
84217
|
-
})]);
|
|
84218
84697
|
object({
|
|
84219
84698
|
manufacturer: string().optional(),
|
|
84220
84699
|
supportedModels: array(string()).optional(),
|
|
@@ -84244,7 +84723,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
84244
84723
|
capability: adminUiCapability,
|
|
84245
84724
|
provider: {
|
|
84246
84725
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
84247
|
-
getVersion: async () => ({ version: "1.2.
|
|
84726
|
+
getVersion: async () => ({ version: "1.2.291" })
|
|
84248
84727
|
}
|
|
84249
84728
|
}];
|
|
84250
84729
|
}
|