@camstack/addon-post-analysis 1.2.650 → 1.2.651
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 +6 -0
- package/dist/{clip-model-registry-B_mY0hd7.mjs → clip-model-registry-BWY8P-AK.mjs} +502 -11
- package/dist/{clip-model-registry-CC7pvitG.js → clip-model-registry-Dte3QQEt.js} +502 -11
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-HjnmptAc.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-_vVfXkDx.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-6PIugMbv.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bk6VlAsZ.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-BjUFFpLS.mjs → hostInit-A7m5uu3n.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +40 -2
- package/dist/pipeline-analytics/index.mjs +40 -3
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-YNYqWfWY.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-OPayQG8i.mjs +0 -26
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.651] - 2026-10-29
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The live detection overlay no longer shows boxes from replayed pre-roll frames
|
|
15
|
+
|
|
10
16
|
## [1.2.650] - 2026-10-28
|
|
11
17
|
|
|
12
18
|
### Changed
|
|
@@ -5645,7 +5645,7 @@ var ZodIssueCode = {
|
|
|
5645
5645
|
var ZodFirstPartyTypeKind;
|
|
5646
5646
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5647
5647
|
//#endregion
|
|
5648
|
-
//#region ../types/dist/sleep-
|
|
5648
|
+
//#region ../types/dist/sleep-C_u6cEAJ.mjs
|
|
5649
5649
|
/**
|
|
5650
5650
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5651
5651
|
* window to float samples (D455).
|
|
@@ -9107,6 +9107,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9107
9107
|
"network-link",
|
|
9108
9108
|
"network-quality",
|
|
9109
9109
|
"node-certificates",
|
|
9110
|
+
"node-removal-hook",
|
|
9110
9111
|
"nodes",
|
|
9111
9112
|
"notification-output",
|
|
9112
9113
|
"notification-rules",
|
|
@@ -9137,6 +9138,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9137
9138
|
"recording-onboard",
|
|
9138
9139
|
"recording-signal",
|
|
9139
9140
|
"records",
|
|
9141
|
+
"remote",
|
|
9140
9142
|
"running-state",
|
|
9141
9143
|
"scene-monitor",
|
|
9142
9144
|
"script-runner",
|
|
@@ -9160,6 +9162,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9160
9162
|
"system",
|
|
9161
9163
|
"tamper",
|
|
9162
9164
|
"temperature-sensor",
|
|
9165
|
+
"template",
|
|
9163
9166
|
"terminal-session",
|
|
9164
9167
|
"toast",
|
|
9165
9168
|
"training",
|
|
@@ -10100,6 +10103,11 @@ Object.freeze({
|
|
|
10100
10103
|
"standby"
|
|
10101
10104
|
]
|
|
10102
10105
|
},
|
|
10106
|
+
{
|
|
10107
|
+
"path": "stateSource",
|
|
10108
|
+
"valueType": "enum",
|
|
10109
|
+
"enumValues": ["reported", "assumed"]
|
|
10110
|
+
},
|
|
10103
10111
|
{
|
|
10104
10112
|
"path": "volumeLevel",
|
|
10105
10113
|
"valueType": "number"
|
|
@@ -10375,6 +10383,18 @@ Object.freeze({
|
|
|
10375
10383
|
{
|
|
10376
10384
|
"path": "volume",
|
|
10377
10385
|
"valueType": "number"
|
|
10386
|
+
},
|
|
10387
|
+
{
|
|
10388
|
+
"path": "lastFeedGrams",
|
|
10389
|
+
"valueType": "number"
|
|
10390
|
+
},
|
|
10391
|
+
{
|
|
10392
|
+
"path": "lastFeedHopper1",
|
|
10393
|
+
"valueType": "number"
|
|
10394
|
+
},
|
|
10395
|
+
{
|
|
10396
|
+
"path": "lastFeedHopper2",
|
|
10397
|
+
"valueType": "number"
|
|
10378
10398
|
}
|
|
10379
10399
|
],
|
|
10380
10400
|
"power-meter": [
|
|
@@ -11422,7 +11442,7 @@ function errMsg(err) {
|
|
|
11422
11442
|
return String(err);
|
|
11423
11443
|
}
|
|
11424
11444
|
//#endregion
|
|
11425
|
-
//#region ../types/dist/composition-
|
|
11445
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
11426
11446
|
/**
|
|
11427
11447
|
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
11428
11448
|
* canonical form sorts object keys alphabetically at every depth so two
|
|
@@ -17793,9 +17813,21 @@ var AlertSeveritySchema = _enum([
|
|
|
17793
17813
|
"error",
|
|
17794
17814
|
"critical"
|
|
17795
17815
|
]);
|
|
17816
|
+
/**
|
|
17817
|
+
* An action that RUNS something instead of going somewhere: the admin UI calls
|
|
17818
|
+
* the addon's custom action (`addons.custom`) with exactly these fields. The
|
|
17819
|
+
* producer owns the meaning; the UI knows nothing about the addon or the kind.
|
|
17820
|
+
*/
|
|
17821
|
+
var AlertActionInvokeSchema = object({
|
|
17822
|
+
addonId: string().min(1),
|
|
17823
|
+
action: string().min(1),
|
|
17824
|
+
input: record(string(), unknown()).optional()
|
|
17825
|
+
});
|
|
17826
|
+
/** An action has `href` (a link) OR `invoke` (a button that runs a custom action). */
|
|
17796
17827
|
var AlertActionSchema = object({
|
|
17797
17828
|
label: string(),
|
|
17798
17829
|
href: string().optional(),
|
|
17830
|
+
invoke: AlertActionInvokeSchema.optional(),
|
|
17799
17831
|
/**
|
|
17800
17832
|
* How `href` is followed. Absent / `app`: an admin-ui route (client-side).
|
|
17801
17833
|
* `server`: a route the HUB serves (an addon HTTP route such as an OAuth
|
|
@@ -44237,6 +44269,14 @@ var embeddingEncoderCapability = {
|
|
|
44237
44269
|
})
|
|
44238
44270
|
}
|
|
44239
44271
|
};
|
|
44272
|
+
method(object({
|
|
44273
|
+
nodeId: string().min(1),
|
|
44274
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
44275
|
+
removedAt: number()
|
|
44276
|
+
}), object({ counts: record(string(), number().int().nonnegative()) }), {
|
|
44277
|
+
kind: "mutation",
|
|
44278
|
+
auth: "admin"
|
|
44279
|
+
});
|
|
44240
44280
|
/**
|
|
44241
44281
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
44242
44282
|
* so it can delete what it keeps for that device (D865).
|
|
@@ -61766,6 +61806,318 @@ onBrightnessChanged: { data: object({
|
|
|
61766
61806
|
minIntervalMs: 0
|
|
61767
61807
|
} } }
|
|
61768
61808
|
};
|
|
61809
|
+
/**
|
|
61810
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
61811
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
61812
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
61813
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
61814
|
+
*
|
|
61815
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
61816
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
61817
|
+
*/
|
|
61818
|
+
var REMOTE_KNOWN_ROLES = [
|
|
61819
|
+
"power",
|
|
61820
|
+
"power_on",
|
|
61821
|
+
"power_off",
|
|
61822
|
+
"volume_up",
|
|
61823
|
+
"volume_down",
|
|
61824
|
+
"mute",
|
|
61825
|
+
"channel_up",
|
|
61826
|
+
"channel_down",
|
|
61827
|
+
"up",
|
|
61828
|
+
"down",
|
|
61829
|
+
"left",
|
|
61830
|
+
"right",
|
|
61831
|
+
"ok",
|
|
61832
|
+
"back",
|
|
61833
|
+
"home",
|
|
61834
|
+
"menu",
|
|
61835
|
+
"info",
|
|
61836
|
+
"guide",
|
|
61837
|
+
"exit",
|
|
61838
|
+
"input",
|
|
61839
|
+
"play",
|
|
61840
|
+
"pause",
|
|
61841
|
+
"play_pause",
|
|
61842
|
+
"stop",
|
|
61843
|
+
"next",
|
|
61844
|
+
"previous",
|
|
61845
|
+
"fast_forward",
|
|
61846
|
+
"rewind",
|
|
61847
|
+
"digit_0",
|
|
61848
|
+
"digit_1",
|
|
61849
|
+
"digit_2",
|
|
61850
|
+
"digit_3",
|
|
61851
|
+
"digit_4",
|
|
61852
|
+
"digit_5",
|
|
61853
|
+
"digit_6",
|
|
61854
|
+
"digit_7",
|
|
61855
|
+
"digit_8",
|
|
61856
|
+
"digit_9"
|
|
61857
|
+
];
|
|
61858
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
61859
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
61860
|
+
function isRemoteKnownRole(value) {
|
|
61861
|
+
return KNOWN_ROLES.has(value);
|
|
61862
|
+
}
|
|
61863
|
+
function isRemoteCustomKey(key) {
|
|
61864
|
+
return CUSTOM_KEY_RE.test(key);
|
|
61865
|
+
}
|
|
61866
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
61867
|
+
function customKeyOfRole(role) {
|
|
61868
|
+
if (!role.startsWith("custom:")) return null;
|
|
61869
|
+
const key = role.slice(7);
|
|
61870
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
61871
|
+
}
|
|
61872
|
+
function isRemoteRole(value) {
|
|
61873
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
61874
|
+
}
|
|
61875
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
61876
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
61877
|
+
var RemoteCustomButtonSchema = object({
|
|
61878
|
+
/** The slug after `custom:` in the role. */
|
|
61879
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
61880
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
61881
|
+
name: string().min(1).max(60)
|
|
61882
|
+
});
|
|
61883
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
61884
|
+
var RemoteConfigSchema = object({
|
|
61885
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
61886
|
+
/**
|
|
61887
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
61888
|
+
* names its own device, so one command may override it.
|
|
61889
|
+
*/
|
|
61890
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
61891
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
61892
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
61893
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
61894
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
61895
|
+
}).superRefine((config, ctx) => {
|
|
61896
|
+
const roles = Object.keys(config.bindings);
|
|
61897
|
+
if (roles.length > 200) ctx.addIssue({
|
|
61898
|
+
code: "custom",
|
|
61899
|
+
message: "too many bindings",
|
|
61900
|
+
path: ["bindings"]
|
|
61901
|
+
});
|
|
61902
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
61903
|
+
code: "custom",
|
|
61904
|
+
message: `"${role}" is not a role`,
|
|
61905
|
+
path: ["bindings", role]
|
|
61906
|
+
});
|
|
61907
|
+
const keys = /* @__PURE__ */ new Set();
|
|
61908
|
+
config.customButtons.forEach((button, index) => {
|
|
61909
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
61910
|
+
code: "custom",
|
|
61911
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
61912
|
+
path: [
|
|
61913
|
+
"customButtons",
|
|
61914
|
+
index,
|
|
61915
|
+
"key"
|
|
61916
|
+
]
|
|
61917
|
+
});
|
|
61918
|
+
keys.add(button.key);
|
|
61919
|
+
});
|
|
61920
|
+
for (const role of roles) {
|
|
61921
|
+
const key = customKeyOfRole(role);
|
|
61922
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
61923
|
+
code: "custom",
|
|
61924
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
61925
|
+
path: ["bindings", role]
|
|
61926
|
+
});
|
|
61927
|
+
}
|
|
61928
|
+
});
|
|
61929
|
+
object({
|
|
61930
|
+
power: object({
|
|
61931
|
+
state: _enum(["on", "off"]),
|
|
61932
|
+
at: number()
|
|
61933
|
+
}).nullable(),
|
|
61934
|
+
muted: object({
|
|
61935
|
+
value: boolean(),
|
|
61936
|
+
at: number()
|
|
61937
|
+
}).nullable()
|
|
61938
|
+
});
|
|
61939
|
+
var RemoteLayoutButtonSchema = object({
|
|
61940
|
+
id: string().min(1).max(40),
|
|
61941
|
+
/** 0-based grid position. */
|
|
61942
|
+
row: number().int().min(0).max(24),
|
|
61943
|
+
col: number().int().min(0).max(24),
|
|
61944
|
+
rowSpan: number().int().min(1).max(24),
|
|
61945
|
+
colSpan: number().int().min(1).max(24),
|
|
61946
|
+
icon: string().min(1).max(60).optional(),
|
|
61947
|
+
label: string().min(1).max(40).optional(),
|
|
61948
|
+
role: RemoteRoleSchema
|
|
61949
|
+
});
|
|
61950
|
+
object({
|
|
61951
|
+
columns: number().int().min(1).max(24),
|
|
61952
|
+
rows: number().int().min(1).max(24),
|
|
61953
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
61954
|
+
}).superRefine((grid, ctx) => {
|
|
61955
|
+
const ids = /* @__PURE__ */ new Set();
|
|
61956
|
+
const taken = /* @__PURE__ */ new Map();
|
|
61957
|
+
grid.buttons.forEach((button, index) => {
|
|
61958
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
61959
|
+
code: "custom",
|
|
61960
|
+
message: `button id "${button.id}" is used twice`,
|
|
61961
|
+
path: [
|
|
61962
|
+
"buttons",
|
|
61963
|
+
index,
|
|
61964
|
+
"id"
|
|
61965
|
+
]
|
|
61966
|
+
});
|
|
61967
|
+
ids.add(button.id);
|
|
61968
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
61969
|
+
ctx.addIssue({
|
|
61970
|
+
code: "custom",
|
|
61971
|
+
message: `button "${button.id}" leaves the grid`,
|
|
61972
|
+
path: ["buttons", index]
|
|
61973
|
+
});
|
|
61974
|
+
return;
|
|
61975
|
+
}
|
|
61976
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
61977
|
+
const cell = `${r}:${c}`;
|
|
61978
|
+
const other = taken.get(cell);
|
|
61979
|
+
if (other !== void 0) {
|
|
61980
|
+
ctx.addIssue({
|
|
61981
|
+
code: "custom",
|
|
61982
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
61983
|
+
path: ["buttons", index]
|
|
61984
|
+
});
|
|
61985
|
+
return;
|
|
61986
|
+
}
|
|
61987
|
+
taken.set(cell, button.id);
|
|
61988
|
+
}
|
|
61989
|
+
});
|
|
61990
|
+
});
|
|
61991
|
+
var RemoteBoundCommandSchema = object({
|
|
61992
|
+
role: RemoteRoleSchema,
|
|
61993
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
61994
|
+
label: string().optional(),
|
|
61995
|
+
custom: boolean()
|
|
61996
|
+
});
|
|
61997
|
+
var RemoteCommandListSchema = object({
|
|
61998
|
+
layoutTemplateId: string().nullable(),
|
|
61999
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
62000
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
62001
|
+
commands: array(RemoteBoundCommandSchema)
|
|
62002
|
+
});
|
|
62003
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
62004
|
+
"no-remote",
|
|
62005
|
+
"unbound-role",
|
|
62006
|
+
"action-failed"
|
|
62007
|
+
]);
|
|
62008
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
62009
|
+
object({
|
|
62010
|
+
status: literal("sent"),
|
|
62011
|
+
/** How many times the action ran. */
|
|
62012
|
+
sends: number().int().min(1)
|
|
62013
|
+
}),
|
|
62014
|
+
object({
|
|
62015
|
+
status: literal("skipped"),
|
|
62016
|
+
reason: literal("already-in-state")
|
|
62017
|
+
}),
|
|
62018
|
+
object({
|
|
62019
|
+
status: literal("refused"),
|
|
62020
|
+
reason: RemoteRefusalReasonSchema,
|
|
62021
|
+
detail: string().optional()
|
|
62022
|
+
})
|
|
62023
|
+
]);
|
|
62024
|
+
var RemoteMediaCommandSchema = _enum([
|
|
62025
|
+
"play",
|
|
62026
|
+
"pause",
|
|
62027
|
+
"stop",
|
|
62028
|
+
"next",
|
|
62029
|
+
"previous",
|
|
62030
|
+
"setMute",
|
|
62031
|
+
"selectSource"
|
|
62032
|
+
]);
|
|
62033
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
62034
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
62035
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
62036
|
+
status: literal("refused"),
|
|
62037
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
62038
|
+
detail: string()
|
|
62039
|
+
})]);
|
|
62040
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
62041
|
+
DeviceType.MediaPlayer;
|
|
62042
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
62043
|
+
kind: "mutation",
|
|
62044
|
+
auth: "admin"
|
|
62045
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
62046
|
+
role: RemoteRoleSchema,
|
|
62047
|
+
/** Sends in a row (volume steps). */
|
|
62048
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
62049
|
+
}), RemoteSendResultSchema, {
|
|
62050
|
+
kind: "mutation",
|
|
62051
|
+
auth: "protected"
|
|
62052
|
+
}), method(deviceInput.extend({
|
|
62053
|
+
command: RemoteMediaCommandSchema,
|
|
62054
|
+
muted: boolean().optional(),
|
|
62055
|
+
source: string().optional(),
|
|
62056
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
62057
|
+
}), RemoteMediaCommandResultSchema, {
|
|
62058
|
+
kind: "mutation",
|
|
62059
|
+
auth: "protected"
|
|
62060
|
+
});
|
|
62061
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
62062
|
+
/**
|
|
62063
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
62064
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
62065
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
62066
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
62067
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
62068
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
62069
|
+
*
|
|
62070
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
62071
|
+
* devices that still use a template, without parsing text.
|
|
62072
|
+
*/
|
|
62073
|
+
var TemplateRecordSchema = object({
|
|
62074
|
+
id: string().min(1),
|
|
62075
|
+
kind: TemplateKindSchema,
|
|
62076
|
+
name: string().min(1).max(120),
|
|
62077
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
62078
|
+
payload: unknown(),
|
|
62079
|
+
createdAt: number(),
|
|
62080
|
+
updatedAt: number()
|
|
62081
|
+
});
|
|
62082
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
62083
|
+
status: literal("saved"),
|
|
62084
|
+
template: TemplateRecordSchema
|
|
62085
|
+
}), object({
|
|
62086
|
+
status: literal("refused"),
|
|
62087
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
62088
|
+
detail: string()
|
|
62089
|
+
})]);
|
|
62090
|
+
/** A device still pointing at a template. */
|
|
62091
|
+
var TemplateUserSchema = object({
|
|
62092
|
+
deviceId: number().int().nonnegative(),
|
|
62093
|
+
name: string()
|
|
62094
|
+
});
|
|
62095
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
62096
|
+
object({ status: literal("deleted") }),
|
|
62097
|
+
object({ status: literal("not-found") }),
|
|
62098
|
+
object({
|
|
62099
|
+
status: literal("in-use"),
|
|
62100
|
+
devices: array(TemplateUserSchema).min(1)
|
|
62101
|
+
})
|
|
62102
|
+
]);
|
|
62103
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
62104
|
+
kind: TemplateKindSchema,
|
|
62105
|
+
name: string().min(1).max(120),
|
|
62106
|
+
payload: unknown()
|
|
62107
|
+
}), TemplateWriteResultSchema, {
|
|
62108
|
+
kind: "mutation",
|
|
62109
|
+
auth: "admin"
|
|
62110
|
+
}), method(object({
|
|
62111
|
+
id: string().min(1),
|
|
62112
|
+
name: string().min(1).max(120).optional(),
|
|
62113
|
+
payload: unknown().optional()
|
|
62114
|
+
}), TemplateWriteResultSchema, {
|
|
62115
|
+
kind: "mutation",
|
|
62116
|
+
auth: "admin"
|
|
62117
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
62118
|
+
kind: "mutation",
|
|
62119
|
+
auth: "admin"
|
|
62120
|
+
});
|
|
61769
62121
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
61770
62122
|
kind: "mutation",
|
|
61771
62123
|
auth: "protected"
|
|
@@ -66041,9 +66393,35 @@ var MediaInfoSchema = object({
|
|
|
66041
66393
|
/** Optional cover-art / thumbnail URL. */
|
|
66042
66394
|
imageUrl: string().optional()
|
|
66043
66395
|
});
|
|
66396
|
+
/**
|
|
66397
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
66398
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
66399
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
66400
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
66401
|
+
* guess, never as a reading.
|
|
66402
|
+
*/
|
|
66403
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
66404
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
66405
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
66406
|
+
"state",
|
|
66407
|
+
"volumeLevel",
|
|
66408
|
+
"isMuted",
|
|
66409
|
+
"source"
|
|
66410
|
+
]);
|
|
66044
66411
|
var MediaPlayerStatusSchema = object({
|
|
66045
66412
|
/** Playback lifecycle state. */
|
|
66046
66413
|
state: MediaPlayerStateSchema,
|
|
66414
|
+
/**
|
|
66415
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
66416
|
+
* A slice written before this field existed parses as `reported`.
|
|
66417
|
+
*/
|
|
66418
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
66419
|
+
/**
|
|
66420
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
66421
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
66422
|
+
* from a running-state source, mute guessed from the last send).
|
|
66423
|
+
*/
|
|
66424
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
66047
66425
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
66048
66426
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
66049
66427
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -68031,6 +68409,14 @@ var PetFeederStatusSchema = object({
|
|
|
68031
68409
|
feedSound: boolean(),
|
|
68032
68410
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
68033
68411
|
volume: number().meta(readingMeta("none")),
|
|
68412
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
68413
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
68414
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
68415
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
68416
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
68417
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
68418
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
68419
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
68034
68420
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
68035
68421
|
lastFetchedAt: number()
|
|
68036
68422
|
});
|
|
@@ -74153,9 +74539,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
74153
74539
|
kind: "mutation",
|
|
74154
74540
|
auth: "admin"
|
|
74155
74541
|
});
|
|
74542
|
+
discriminatedUnion("kind", [object({
|
|
74543
|
+
kind: literal("raw"),
|
|
74544
|
+
timings: array(number().int()),
|
|
74545
|
+
settings: TransmitSettingsSchema.optional()
|
|
74546
|
+
}), object({
|
|
74547
|
+
kind: literal("pronto"),
|
|
74548
|
+
code: string()
|
|
74549
|
+
})]);
|
|
74156
74550
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
74157
74551
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
74158
|
-
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;
|
|
74552
|
+
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;
|
|
74159
74553
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
74160
74554
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
74161
74555
|
new Set(CAP_NAMES);
|
|
@@ -80124,6 +80518,13 @@ Object.freeze({
|
|
|
80124
80518
|
access: "create",
|
|
80125
80519
|
role: "admin"
|
|
80126
80520
|
},
|
|
80521
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
80522
|
+
capName: "node-removal-hook",
|
|
80523
|
+
capScope: "system",
|
|
80524
|
+
addonId: null,
|
|
80525
|
+
access: "create",
|
|
80526
|
+
role: "admin"
|
|
80527
|
+
},
|
|
80127
80528
|
"nodes.clusterAddonStatus": {
|
|
80128
80529
|
capName: "nodes",
|
|
80129
80530
|
capScope: "system",
|
|
@@ -83015,6 +83416,41 @@ Object.freeze({
|
|
|
83015
83416
|
access: "create",
|
|
83016
83417
|
role: "admin"
|
|
83017
83418
|
},
|
|
83419
|
+
"remote.getConfig": {
|
|
83420
|
+
capName: "remote",
|
|
83421
|
+
capScope: "system",
|
|
83422
|
+
addonId: null,
|
|
83423
|
+
access: "view",
|
|
83424
|
+
role: "admin"
|
|
83425
|
+
},
|
|
83426
|
+
"remote.listCommands": {
|
|
83427
|
+
capName: "remote",
|
|
83428
|
+
capScope: "system",
|
|
83429
|
+
addonId: null,
|
|
83430
|
+
access: "view",
|
|
83431
|
+
role: "admin"
|
|
83432
|
+
},
|
|
83433
|
+
"remote.sendCommand": {
|
|
83434
|
+
capName: "remote",
|
|
83435
|
+
capScope: "system",
|
|
83436
|
+
addonId: null,
|
|
83437
|
+
access: "create",
|
|
83438
|
+
role: "admin"
|
|
83439
|
+
},
|
|
83440
|
+
"remote.sendMediaCommand": {
|
|
83441
|
+
capName: "remote",
|
|
83442
|
+
capScope: "system",
|
|
83443
|
+
addonId: null,
|
|
83444
|
+
access: "create",
|
|
83445
|
+
role: "admin"
|
|
83446
|
+
},
|
|
83447
|
+
"remote.setConfig": {
|
|
83448
|
+
capName: "remote",
|
|
83449
|
+
capScope: "system",
|
|
83450
|
+
addonId: null,
|
|
83451
|
+
access: "create",
|
|
83452
|
+
role: "admin"
|
|
83453
|
+
},
|
|
83018
83454
|
"runningState.getStatus": {
|
|
83019
83455
|
capName: "running-state",
|
|
83020
83456
|
capScope: "device",
|
|
@@ -84205,6 +84641,41 @@ Object.freeze({
|
|
|
84205
84641
|
access: "view",
|
|
84206
84642
|
role: "viewer"
|
|
84207
84643
|
},
|
|
84644
|
+
"template.create": {
|
|
84645
|
+
capName: "template",
|
|
84646
|
+
capScope: "system",
|
|
84647
|
+
addonId: null,
|
|
84648
|
+
access: "create",
|
|
84649
|
+
role: "admin"
|
|
84650
|
+
},
|
|
84651
|
+
"template.delete": {
|
|
84652
|
+
capName: "template",
|
|
84653
|
+
capScope: "system",
|
|
84654
|
+
addonId: null,
|
|
84655
|
+
access: "delete",
|
|
84656
|
+
role: "admin"
|
|
84657
|
+
},
|
|
84658
|
+
"template.get": {
|
|
84659
|
+
capName: "template",
|
|
84660
|
+
capScope: "system",
|
|
84661
|
+
addonId: null,
|
|
84662
|
+
access: "view",
|
|
84663
|
+
role: "admin"
|
|
84664
|
+
},
|
|
84665
|
+
"template.list": {
|
|
84666
|
+
capName: "template",
|
|
84667
|
+
capScope: "system",
|
|
84668
|
+
addonId: null,
|
|
84669
|
+
access: "view",
|
|
84670
|
+
role: "admin"
|
|
84671
|
+
},
|
|
84672
|
+
"template.update": {
|
|
84673
|
+
capName: "template",
|
|
84674
|
+
capScope: "system",
|
|
84675
|
+
addonId: null,
|
|
84676
|
+
access: "create",
|
|
84677
|
+
role: "admin"
|
|
84678
|
+
},
|
|
84208
84679
|
"terminalSession.adoptLegacyMonitor": {
|
|
84209
84680
|
capName: "terminal-session",
|
|
84210
84681
|
capScope: "system",
|
|
@@ -88997,6 +89468,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
88997
89468
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
88998
89469
|
"device-provider": system(INTERNAL),
|
|
88999
89470
|
"device-removal-hook": system(INTERNAL),
|
|
89471
|
+
"node-removal-hook": system(INTERNAL),
|
|
89000
89472
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
89001
89473
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
89002
89474
|
"embedding-encoder": system(ML),
|
|
@@ -89036,6 +89508,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
89036
89508
|
"recording-archive": system(STORAGE),
|
|
89037
89509
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
89038
89510
|
records: system(INTERNAL),
|
|
89511
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
89039
89512
|
"server-management": system(CLUSTER),
|
|
89040
89513
|
"settings-store": system(INTERNAL),
|
|
89041
89514
|
"smtp-provider": system(INTERNAL),
|
|
@@ -89048,6 +89521,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
89048
89521
|
"storage-provider": system(STORAGE),
|
|
89049
89522
|
"stream-broker": system(PIPELINE),
|
|
89050
89523
|
system: system(CLUSTER),
|
|
89524
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
89051
89525
|
"terminal-session": system(CLUSTER),
|
|
89052
89526
|
toast: system(UI_PLUMBING),
|
|
89053
89527
|
training: system(ML),
|
|
@@ -91474,6 +91948,31 @@ Object.freeze({
|
|
|
91474
91948
|
form: "single",
|
|
91475
91949
|
optional: true
|
|
91476
91950
|
}],
|
|
91951
|
+
"remote.getConfig": [{
|
|
91952
|
+
name: "deviceId",
|
|
91953
|
+
form: "single",
|
|
91954
|
+
optional: false
|
|
91955
|
+
}],
|
|
91956
|
+
"remote.listCommands": [{
|
|
91957
|
+
name: "deviceId",
|
|
91958
|
+
form: "single",
|
|
91959
|
+
optional: false
|
|
91960
|
+
}],
|
|
91961
|
+
"remote.sendCommand": [{
|
|
91962
|
+
name: "deviceId",
|
|
91963
|
+
form: "single",
|
|
91964
|
+
optional: false
|
|
91965
|
+
}],
|
|
91966
|
+
"remote.sendMediaCommand": [{
|
|
91967
|
+
name: "deviceId",
|
|
91968
|
+
form: "single",
|
|
91969
|
+
optional: false
|
|
91970
|
+
}],
|
|
91971
|
+
"remote.setConfig": [{
|
|
91972
|
+
name: "deviceId",
|
|
91973
|
+
form: "single",
|
|
91974
|
+
optional: false
|
|
91975
|
+
}],
|
|
91477
91976
|
"runningState.getStatus": [{
|
|
91478
91977
|
name: "deviceId",
|
|
91479
91978
|
form: "single",
|
|
@@ -96843,14 +97342,6 @@ function armRemovalReconcile(opts) {
|
|
|
96843
97342
|
timer.unref?.();
|
|
96844
97343
|
return () => clearInterval(timer);
|
|
96845
97344
|
}
|
|
96846
|
-
discriminatedUnion("kind", [object({
|
|
96847
|
-
kind: literal("raw"),
|
|
96848
|
-
timings: array(number().int()),
|
|
96849
|
-
settings: TransmitSettingsSchema.optional()
|
|
96850
|
-
}), object({
|
|
96851
|
-
kind: literal("pronto"),
|
|
96852
|
-
code: string()
|
|
96853
|
-
})]);
|
|
96854
97345
|
object({
|
|
96855
97346
|
manufacturer: string().optional(),
|
|
96856
97347
|
supportedModels: array(string()).optional(),
|