@camstack/addon-post-analysis 1.2.369 → 1.2.371
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/{clip-model-registry-C_-tWzrX.mjs → clip-model-registry-DnJSHCsn.mjs} +1620 -51
- package/dist/{clip-model-registry-E4CGZ8NR.js → clip-model-registry-aWakBGm3.js} +1643 -50
- package/dist/embedding-encoder/index.js +13 -2
- package/dist/embedding-encoder/index.mjs +13 -2
- package/dist/pipeline-analytics/_stub.js +752 -631
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Bac17NNv.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DzBqyp65.mjs} +3 -3
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BRMRfKVO.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-CYfz4e5v.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-CMFNXHOl.mjs → hostInit-B83y5X7G.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +3158 -2001
- package/dist/pipeline-analytics/index.mjs +3189 -2032
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +5 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DOGD-EFh.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-Bb1tsxlC.mjs +0 -26
|
@@ -5490,7 +5490,7 @@ var ZodIssueCode = {
|
|
|
5490
5490
|
var ZodFirstPartyTypeKind;
|
|
5491
5491
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5492
5492
|
//#endregion
|
|
5493
|
-
//#region ../types/dist/sleep-
|
|
5493
|
+
//#region ../types/dist/sleep-DRqxtc0C.mjs
|
|
5494
5494
|
/**
|
|
5495
5495
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5496
5496
|
* window to float samples (D455).
|
|
@@ -8517,6 +8517,10 @@ var DEVICE_SCOPED_CAPS = new Set([
|
|
|
8517
8517
|
function isDeviceScopedCap(capName) {
|
|
8518
8518
|
return DEVICE_SCOPED_CAPS.has(capName);
|
|
8519
8519
|
}
|
|
8520
|
+
object({
|
|
8521
|
+
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
8522
|
+
params: record(string(), union([string(), number()])).optional()
|
|
8523
|
+
});
|
|
8520
8524
|
function hfModelUrl(repo, path) {
|
|
8521
8525
|
return `https://huggingface.co/${repo}/resolve/main/${path}`;
|
|
8522
8526
|
}
|
|
@@ -8545,7 +8549,7 @@ function sleep(ms) {
|
|
|
8545
8549
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
8546
8550
|
}
|
|
8547
8551
|
//#endregion
|
|
8548
|
-
//#region ../types/dist/err-msg-
|
|
8552
|
+
//#region ../types/dist/err-msg-DLerKiVO.mjs
|
|
8549
8553
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
8550
8554
|
DeviceType["Camera"] = "camera";
|
|
8551
8555
|
DeviceType["Hub"] = "hub";
|
|
@@ -8795,6 +8799,22 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8795
8799
|
DeviceRole["Nightvision"] = "nightvision";
|
|
8796
8800
|
DeviceRole["PrivacyMask"] = "privacy-mask";
|
|
8797
8801
|
DeviceRole["Doorbell"] = "doorbell";
|
|
8802
|
+
/** Interior blind / shade / roller blind. HA `device_class: blind|shade`. */
|
|
8803
|
+
DeviceRole["CoverBlind"] = "cover-blind";
|
|
8804
|
+
/** Exterior roller shutter. HA `device_class: shutter`; Homematic BROLL. */
|
|
8805
|
+
DeviceRole["CoverShutter"] = "cover-shutter";
|
|
8806
|
+
/** Exterior awning. HA `device_class: awning`. */
|
|
8807
|
+
DeviceRole["CoverAwning"] = "cover-awning";
|
|
8808
|
+
/** Curtain / drape. HA `device_class: curtain`. */
|
|
8809
|
+
DeviceRole["CoverCurtain"] = "cover-curtain";
|
|
8810
|
+
/** Garage door. HA `device_class: garage`. A security actuator: exports gate it. */
|
|
8811
|
+
DeviceRole["CoverGarage"] = "cover-garage";
|
|
8812
|
+
/** Gate. HA `device_class: gate`. A security actuator: exports gate it. */
|
|
8813
|
+
DeviceRole["CoverGate"] = "cover-gate";
|
|
8814
|
+
/** Door. HA `device_class: door`. A security actuator: exports gate it. */
|
|
8815
|
+
DeviceRole["CoverDoor"] = "cover-door";
|
|
8816
|
+
/** Window. HA `device_class: window`. */
|
|
8817
|
+
DeviceRole["CoverWindow"] = "cover-window";
|
|
8798
8818
|
/** Virtual HA toggle (input_boolean.*) — distinguishable from a
|
|
8799
8819
|
* real Switch device for UI rendering / export adapters. */
|
|
8800
8820
|
DeviceRole["BinaryHelper"] = "binary-helper";
|
|
@@ -8875,7 +8895,7 @@ function errMsg(err) {
|
|
|
8875
8895
|
return String(err);
|
|
8876
8896
|
}
|
|
8877
8897
|
//#endregion
|
|
8878
|
-
//#region ../types/dist/composition-
|
|
8898
|
+
//#region ../types/dist/composition-EQ9Ok0Ee.mjs
|
|
8879
8899
|
/**
|
|
8880
8900
|
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
8881
8901
|
* canonical form sorts object keys alphabetically at every depth so two
|
|
@@ -12904,11 +12924,10 @@ var ClipModelMetaSchema = object({
|
|
|
12904
12924
|
/**
|
|
12905
12925
|
* The `vector-store` index this model's vectors live in. ONE feature space
|
|
12906
12926
|
* per index: two models share an index only when their vectors are ranked
|
|
12907
|
-
* against each other, which for CLIP means never across families.
|
|
12908
|
-
*
|
|
12909
|
-
* `modelId`); any other model gets its own.
|
|
12927
|
+
* against each other, which for CLIP means never across families. Every
|
|
12928
|
+
* model gets its own.
|
|
12910
12929
|
*/
|
|
12911
|
-
vectorIndex: string().regex(/^object-clip
|
|
12930
|
+
vectorIndex: string().regex(/^object-clip-[a-z0-9][a-z0-9-]*$/),
|
|
12912
12931
|
/**
|
|
12913
12932
|
* The text encoder's tokenizer, a declared SIBLING file of its onnx. The name
|
|
12914
12933
|
* must be unique per tokenizer: every model's siblings land in ONE flat
|
|
@@ -13436,6 +13455,177 @@ var ConvertResultSchema = object({
|
|
|
13436
13455
|
files: array(string()).readonly()
|
|
13437
13456
|
})).readonly()
|
|
13438
13457
|
});
|
|
13458
|
+
_enum(["new-session", "step-up"]);
|
|
13459
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
13460
|
+
var AppPageLangSchema = _enum(["en", "it"]);
|
|
13461
|
+
/** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
|
|
13462
|
+
var AppLoginPathSchema = discriminatedUnion("kind", [object({ kind: literal("native") }), object({
|
|
13463
|
+
kind: literal("browser"),
|
|
13464
|
+
startPath: string().startsWith("/")
|
|
13465
|
+
})]);
|
|
13466
|
+
/**
|
|
13467
|
+
* Device certificates (D855) — the wire contract shared by the hub, the admin
|
|
13468
|
+
* UI and the native viewer.
|
|
13469
|
+
*
|
|
13470
|
+
* A device (a phone) generates its OWN P-256 key pair in hardware (Secure
|
|
13471
|
+
* Enclave / Android Keystore / a non-extractable WebCrypto key). The private
|
|
13472
|
+
* key never travels. The hub signs the PUBLIC key into an X.509 leaf under a
|
|
13473
|
+
* dedicated device CA; the device later proves possession of the key by
|
|
13474
|
+
* signing a hub-issued nonce, and the hub answers with the same session a
|
|
13475
|
+
* password login opens.
|
|
13476
|
+
*
|
|
13477
|
+
* Everything on the wire is a small string (a PEM, a base64url signature):
|
|
13478
|
+
* D613 is about bulk bytes, and a certificate is ~600 bytes.
|
|
13479
|
+
*/
|
|
13480
|
+
/** Signature algorithm of every device credential: ECDSA, curve P-256, SHA-256. */
|
|
13481
|
+
var DEVICE_CERT_SIGNATURE = "ecdsa-p256-sha256";
|
|
13482
|
+
/** First line of every signed message; a change of format bumps the version. */
|
|
13483
|
+
var DEVICE_SIGNATURE_MESSAGE_VERSION = "camstack-device-cert-v1";
|
|
13484
|
+
_enum([
|
|
13485
|
+
"login",
|
|
13486
|
+
"renew",
|
|
13487
|
+
"revoke"
|
|
13488
|
+
]);
|
|
13489
|
+
var DevicePlatformSchema = _enum([
|
|
13490
|
+
"ios",
|
|
13491
|
+
"android",
|
|
13492
|
+
"web",
|
|
13493
|
+
"other"
|
|
13494
|
+
]);
|
|
13495
|
+
var Base64UrlSchema = string().min(1).max(4096).regex(/^[A-Za-z0-9_-]+$/);
|
|
13496
|
+
var PemSchema = string().min(1).max(16384);
|
|
13497
|
+
/**
|
|
13498
|
+
* Why a device-certificate endpoint said no. Distinct from a transport / 5xx
|
|
13499
|
+
* failure: those carry no reason and mean "try again", never "the credential is
|
|
13500
|
+
* dead". The viewer switches on this exhaustively.
|
|
13501
|
+
*/
|
|
13502
|
+
var DeviceRefusalReasonSchema = _enum([
|
|
13503
|
+
"revoked",
|
|
13504
|
+
"unknown-credential",
|
|
13505
|
+
"expired",
|
|
13506
|
+
"bad-signature",
|
|
13507
|
+
"nonce-invalid",
|
|
13508
|
+
"rate-limited",
|
|
13509
|
+
"invalid-certificate",
|
|
13510
|
+
"superseded",
|
|
13511
|
+
"user-gone",
|
|
13512
|
+
"unavailable",
|
|
13513
|
+
"code-invalid",
|
|
13514
|
+
"self-enrollment-disabled",
|
|
13515
|
+
"step-up-required",
|
|
13516
|
+
"bad-public-key"
|
|
13517
|
+
]);
|
|
13518
|
+
var DeviceRefusalSchema = object({
|
|
13519
|
+
ok: literal(false),
|
|
13520
|
+
reason: DeviceRefusalReasonSchema,
|
|
13521
|
+
definitive: boolean(),
|
|
13522
|
+
retryAfterSeconds: number().optional()
|
|
13523
|
+
});
|
|
13524
|
+
object({
|
|
13525
|
+
code: string().min(1).max(256),
|
|
13526
|
+
/** SubjectPublicKeyInfo DER of the device's P-256 public key, base64url. */
|
|
13527
|
+
publicKeySpki: Base64UrlSchema,
|
|
13528
|
+
deviceName: string().min(1).max(80).optional(),
|
|
13529
|
+
platform: DevicePlatformSchema
|
|
13530
|
+
});
|
|
13531
|
+
discriminatedUnion("ok", [object({
|
|
13532
|
+
credentialId: string(),
|
|
13533
|
+
certPem: PemSchema,
|
|
13534
|
+
/** The device CA certificate the leaf chains to. */
|
|
13535
|
+
chainPem: PemSchema,
|
|
13536
|
+
notAfter: number(),
|
|
13537
|
+
user: object({
|
|
13538
|
+
id: string(),
|
|
13539
|
+
username: string()
|
|
13540
|
+
})
|
|
13541
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13542
|
+
object({
|
|
13543
|
+
/** The single-use step-up proof (`auth.deviceEnrollProofFrom…`). */
|
|
13544
|
+
proof: string().min(1).max(512),
|
|
13545
|
+
publicKeySpki: Base64UrlSchema,
|
|
13546
|
+
deviceName: string().min(1).max(80),
|
|
13547
|
+
platform: DevicePlatformSchema
|
|
13548
|
+
});
|
|
13549
|
+
object({
|
|
13550
|
+
proof: string(),
|
|
13551
|
+
expiresAt: number()
|
|
13552
|
+
});
|
|
13553
|
+
discriminatedUnion("ok", [object({
|
|
13554
|
+
nonce: string(),
|
|
13555
|
+
/** The origin to put in the signed message. The app compares it to the hub it dialled. */
|
|
13556
|
+
origin: string(),
|
|
13557
|
+
expiresAt: number(),
|
|
13558
|
+
signature: literal(DEVICE_CERT_SIGNATURE)
|
|
13559
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13560
|
+
object({
|
|
13561
|
+
certPem: PemSchema,
|
|
13562
|
+
nonce: string().min(1).max(256),
|
|
13563
|
+
/** ECDSA P-256 SHA-256 over {@link buildDeviceSignatureMessage}; raw r||s or DER, base64url. */
|
|
13564
|
+
signature: Base64UrlSchema
|
|
13565
|
+
});
|
|
13566
|
+
discriminatedUnion("ok", [object({
|
|
13567
|
+
credentialId: string(),
|
|
13568
|
+
certPem: PemSchema,
|
|
13569
|
+
chainPem: PemSchema,
|
|
13570
|
+
notAfter: number()
|
|
13571
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13572
|
+
discriminatedUnion("ok", [object({
|
|
13573
|
+
ok: literal(true),
|
|
13574
|
+
credentialId: string(),
|
|
13575
|
+
sessionsEnded: number().int()
|
|
13576
|
+
}), DeviceRefusalSchema]);
|
|
13577
|
+
var DeviceCredentialStatusSchema = _enum([
|
|
13578
|
+
"active",
|
|
13579
|
+
"expired",
|
|
13580
|
+
"revoked"
|
|
13581
|
+
]);
|
|
13582
|
+
var DeviceCredentialSchema = object({
|
|
13583
|
+
id: string(),
|
|
13584
|
+
userId: string(),
|
|
13585
|
+
username: string().nullable(),
|
|
13586
|
+
deviceName: string(),
|
|
13587
|
+
platform: DevicePlatformSchema,
|
|
13588
|
+
enrolledVia: _enum(["qr", "self"]),
|
|
13589
|
+
/** SHA-256 of the leaf certificate DER, colon-hex. */
|
|
13590
|
+
fingerprint: string(),
|
|
13591
|
+
issuedAt: number(),
|
|
13592
|
+
expiresAt: number(),
|
|
13593
|
+
lastUsedAt: number().nullable(),
|
|
13594
|
+
lastUsedFrom: string().nullable(),
|
|
13595
|
+
revokedAt: number().nullable(),
|
|
13596
|
+
/** `admin:<userId>` | `user:<userId>` | `device` | `user-deleted`. */
|
|
13597
|
+
revokedBy: string().nullable(),
|
|
13598
|
+
status: DeviceCredentialStatusSchema
|
|
13599
|
+
});
|
|
13600
|
+
var StartEnrollmentOutputSchema = object({
|
|
13601
|
+
/** Shown once; only its hash is kept. */
|
|
13602
|
+
code: string(),
|
|
13603
|
+
expiresAt: number(),
|
|
13604
|
+
/** `camstack://enroll?hub=…&code=…` — what the QR encodes. */
|
|
13605
|
+
enrollUrl: string(),
|
|
13606
|
+
/** The hub origin in the link, or `null` when the hub could not name one (the link then has no `hub`). */
|
|
13607
|
+
hubOrigin: string().nullable(),
|
|
13608
|
+
/** Every origin the apps may try (role `appConnections`). */
|
|
13609
|
+
hubOrigins: array(string())
|
|
13610
|
+
});
|
|
13611
|
+
object({
|
|
13612
|
+
kind: literal("device-certificate"),
|
|
13613
|
+
id: literal("device-certificate"),
|
|
13614
|
+
label: string(),
|
|
13615
|
+
stage: literal("primary"),
|
|
13616
|
+
/** tRPC paths under the hub's `auth` router, so a client names no literal. */
|
|
13617
|
+
challengePath: literal("auth.getDeviceChallenge"),
|
|
13618
|
+
revokePath: literal("auth.revokeOwnDeviceCertificate"),
|
|
13619
|
+
enrollSelfPath: literal("auth.enrollSelf"),
|
|
13620
|
+
loginPath: literal("auth.loginWithDeviceCertificate"),
|
|
13621
|
+
renewPath: literal("auth.renewDeviceCertificate"),
|
|
13622
|
+
signature: literal(DEVICE_CERT_SIGNATURE),
|
|
13623
|
+
messageVersion: literal(DEVICE_SIGNATURE_MESSAGE_VERSION),
|
|
13624
|
+
/** Which clients can execute it: a native app silently, a browser with a non-extractable WebCrypto key. */
|
|
13625
|
+
clients: array(_enum(["native", "web"])),
|
|
13626
|
+
/** The app executes it itself, silently (D858). */
|
|
13627
|
+
app: AppLoginPathSchema.nullable()
|
|
13628
|
+
});
|
|
13439
13629
|
var ExpressionBindingSourceSchema = union([
|
|
13440
13630
|
object({
|
|
13441
13631
|
kind: literal("field").optional(),
|
|
@@ -13764,7 +13954,9 @@ var ConfigTabDeclarationSchema = object({
|
|
|
13764
13954
|
var ConfigSectionWithValuesSchema = object({
|
|
13765
13955
|
id: string(),
|
|
13766
13956
|
title: string(),
|
|
13957
|
+
titleKey: string().optional(),
|
|
13767
13958
|
description: string().optional(),
|
|
13959
|
+
descriptionKey: string().optional(),
|
|
13768
13960
|
style: _enum(["card", "accordion"]).optional(),
|
|
13769
13961
|
defaultCollapsed: boolean().optional(),
|
|
13770
13962
|
columns: union([
|
|
@@ -16279,7 +16471,11 @@ var cameraStreamsCapability = {
|
|
|
16279
16471
|
* See `RuntimeStateDurability`. Enforced by
|
|
16280
16472
|
* `scripts/check-runtime-state-durability.ts`.
|
|
16281
16473
|
*/
|
|
16282
|
-
durability: "session"
|
|
16474
|
+
durability: "session",
|
|
16475
|
+
/**
|
|
16476
|
+
* History (D850): none — `online` duplicates device-status.online (one authority); slot data is nested enum/string.
|
|
16477
|
+
*/
|
|
16478
|
+
history: "none"
|
|
16283
16479
|
};
|
|
16284
16480
|
/** kebab-case cap name → camelCase router-map key. */
|
|
16285
16481
|
function kebabToCamel(s) {
|
|
@@ -17122,7 +17318,345 @@ method(object({
|
|
|
17122
17318
|
}), method(object({ refs: RefListSchema }), KeychainResolveResultSchema, { auth: "admin" }), method(object({ refs: RefListSchema }), object({ deleted: number().int() }), {
|
|
17123
17319
|
kind: "mutation",
|
|
17124
17320
|
auth: "admin"
|
|
17321
|
+
}), method(object({ deviceId: number().int() }), object({ refs: array(string()).readonly() }), {
|
|
17322
|
+
kind: "mutation",
|
|
17323
|
+
auth: "admin"
|
|
17125
17324
|
}), method(object({}), array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }), method(object({}), KeychainStateSchema, { auth: "admin" });
|
|
17325
|
+
/**
|
|
17326
|
+
* device-history — the ONE mechanism for numeric history (D850).
|
|
17327
|
+
*
|
|
17328
|
+
* A device value is recorded because its capability says so (the `history`
|
|
17329
|
+
* block of a `*.cap.ts`, captured hub-side from `DeviceStateChanged`); any
|
|
17330
|
+
* other series is DECLARED by the addon that produces it and fed with points
|
|
17331
|
+
* (`record`) or closed five-minute buckets (`recordBuckets`). Rollups 5m / 1h /
|
|
17332
|
+
* 1d are computed here and nowhere else. Storage is `history.db` (D851).
|
|
17333
|
+
*
|
|
17334
|
+
* Who the PRODUCER is: `declareSeries`, `record` and `recordBuckets` are owner
|
|
17335
|
+
* checked against the `callerAddonId` the transport stamps into a call that
|
|
17336
|
+
* crossed a process (never in an input schema, so a session cannot supply it).
|
|
17337
|
+
* A call with no stamp is refused `not-owner`. The methods are `admin` so a
|
|
17338
|
+
* non-admin session never reaches them; an addon's `ctx.api` call bypasses the
|
|
17339
|
+
* tier by design.
|
|
17340
|
+
*/
|
|
17341
|
+
/** Whose history: a real device, or a cluster node (load, memory). */
|
|
17342
|
+
var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
|
|
17343
|
+
kind: literal("device"),
|
|
17344
|
+
deviceId: number().int()
|
|
17345
|
+
}), object({
|
|
17346
|
+
kind: literal("node"),
|
|
17347
|
+
nodeId: string().min(1)
|
|
17348
|
+
})]);
|
|
17349
|
+
var DeviceHistoryKindSchema = _enum([
|
|
17350
|
+
"gauge",
|
|
17351
|
+
"counter",
|
|
17352
|
+
"boolean"
|
|
17353
|
+
]);
|
|
17354
|
+
var DeviceHistoryResolutionSchema = _enum([
|
|
17355
|
+
"raw",
|
|
17356
|
+
"5m",
|
|
17357
|
+
"1h",
|
|
17358
|
+
"1d"
|
|
17359
|
+
]);
|
|
17360
|
+
/** Why a producer's point or bucket was not stored. Counted, never silent (D391). */
|
|
17361
|
+
var DeviceHistoryRefusalReasonSchema = _enum([
|
|
17362
|
+
"undeclared",
|
|
17363
|
+
"not-owner",
|
|
17364
|
+
"opted-out",
|
|
17365
|
+
"not-a-real-device",
|
|
17366
|
+
"rate",
|
|
17367
|
+
"ingest-mismatch",
|
|
17368
|
+
"out-of-range"
|
|
17369
|
+
]);
|
|
17370
|
+
var RefusalSchema = object({
|
|
17371
|
+
key: string(),
|
|
17372
|
+
reason: DeviceHistoryRefusalReasonSchema,
|
|
17373
|
+
count: number().int()
|
|
17374
|
+
});
|
|
17375
|
+
var IngestResultSchema = object({
|
|
17376
|
+
accepted: number().int(),
|
|
17377
|
+
refused: array(RefusalSchema).readonly()
|
|
17378
|
+
});
|
|
17379
|
+
var SeriesInfoSchema = object({
|
|
17380
|
+
key: string(),
|
|
17381
|
+
scope: string(),
|
|
17382
|
+
kind: DeviceHistoryKindSchema,
|
|
17383
|
+
/** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
|
|
17384
|
+
unit: string().nullable(),
|
|
17385
|
+
displayName: string(),
|
|
17386
|
+
source: _enum(["cap", "addon"]),
|
|
17387
|
+
firstTs: number(),
|
|
17388
|
+
lastTs: number()
|
|
17389
|
+
});
|
|
17390
|
+
var QueryPointSchema = object({
|
|
17391
|
+
/** Raw: the point's time. Rollup: the bucket start. */
|
|
17392
|
+
t: number(),
|
|
17393
|
+
samples: number().int(),
|
|
17394
|
+
/** `sum / samples`. */
|
|
17395
|
+
mean: number().nullable(),
|
|
17396
|
+
/** Time-weighted mean (`tw_sum / tw_ms`); `null` for bucket-ingested series. For a boolean: the fraction of time true. */
|
|
17397
|
+
twMean: number().nullable(),
|
|
17398
|
+
min: number(),
|
|
17399
|
+
max: number(),
|
|
17400
|
+
/** `null` is unknown, never zero (D393). */
|
|
17401
|
+
last: number().nullable()
|
|
17402
|
+
});
|
|
17403
|
+
var QuerySeriesSchema = object({
|
|
17404
|
+
scope: string(),
|
|
17405
|
+
/** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
|
|
17406
|
+
before: object({
|
|
17407
|
+
t: number(),
|
|
17408
|
+
value: number().nullable()
|
|
17409
|
+
}).nullable(),
|
|
17410
|
+
points: array(QueryPointSchema).readonly()
|
|
17411
|
+
});
|
|
17412
|
+
/** The window part of a query, shared by the device and node forms. */
|
|
17413
|
+
var QueryWindowShape = {
|
|
17414
|
+
key: string(),
|
|
17415
|
+
scope: string().optional(),
|
|
17416
|
+
from: number(),
|
|
17417
|
+
to: number(),
|
|
17418
|
+
resolution: union([DeviceHistoryResolutionSchema, literal("auto")]).default("auto"),
|
|
17419
|
+
maxPoints: number().int().positive().max(5e3).default(1e3)
|
|
17420
|
+
};
|
|
17421
|
+
var QueryResultSchema = object({
|
|
17422
|
+
resolution: DeviceHistoryResolutionSchema,
|
|
17423
|
+
series: array(QuerySeriesSchema).readonly(),
|
|
17424
|
+
truncated: boolean()
|
|
17425
|
+
});
|
|
17426
|
+
var TierStatusSchema = object({
|
|
17427
|
+
tier: DeviceHistoryResolutionSchema,
|
|
17428
|
+
/** `null` until the first background count answered. */
|
|
17429
|
+
rows: number().int().nullable(),
|
|
17430
|
+
/** `rows` times a fixed per-row estimate — approximate, labelled so. */
|
|
17431
|
+
approxBytes: number().nullable(),
|
|
17432
|
+
countedAt: number().nullable()
|
|
17433
|
+
});
|
|
17434
|
+
/** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
|
|
17435
|
+
var DeviceHistoryStatusSchema = object({
|
|
17436
|
+
startedAt: number(),
|
|
17437
|
+
/** The store is declared, series loaded and the first reconcile has answered. */
|
|
17438
|
+
ready: boolean(),
|
|
17439
|
+
series: number().int(),
|
|
17440
|
+
metrics: number().int(),
|
|
17441
|
+
optedOutDevices: number().int(),
|
|
17442
|
+
tiers: array(TierStatusSchema).readonly(),
|
|
17443
|
+
capture: object({
|
|
17444
|
+
eventsSeen: number().int(),
|
|
17445
|
+
pointsEmitted: number().int(),
|
|
17446
|
+
pointsWritten: number().int(),
|
|
17447
|
+
pointsDropped: number().int(),
|
|
17448
|
+
bufferDepth: number().int(),
|
|
17449
|
+
trailingEmitted: number().int(),
|
|
17450
|
+
reconciledPoints: number().int(),
|
|
17451
|
+
reconcileRuns: number().int(),
|
|
17452
|
+
reconcileFailures: number().int(),
|
|
17453
|
+
lastReconcileAt: number().nullable(),
|
|
17454
|
+
lastFlushAt: number().nullable(),
|
|
17455
|
+
flushFailures: number().int(),
|
|
17456
|
+
skipped: record(string(), number().int())
|
|
17457
|
+
}),
|
|
17458
|
+
ingest: object({
|
|
17459
|
+
accepted: number().int(),
|
|
17460
|
+
refused: record(string(), number().int())
|
|
17461
|
+
}),
|
|
17462
|
+
rollup: object({
|
|
17463
|
+
last5mAt: number().nullable(),
|
|
17464
|
+
last1hAt: number().nullable(),
|
|
17465
|
+
last1dAt: number().nullable(),
|
|
17466
|
+
errors: number().int(),
|
|
17467
|
+
dirty5m: number().int(),
|
|
17468
|
+
dirty1h: number().int(),
|
|
17469
|
+
dirty1d: number().int()
|
|
17470
|
+
}),
|
|
17471
|
+
retention: object({
|
|
17472
|
+
lastRunAt: number().nullable(),
|
|
17473
|
+
deleted: record(string(), number().int()),
|
|
17474
|
+
purgedSeries: number().int()
|
|
17475
|
+
}),
|
|
17476
|
+
directory: object({
|
|
17477
|
+
devices: number().int(),
|
|
17478
|
+
lastRefreshAt: number().nullable()
|
|
17479
|
+
})
|
|
17480
|
+
});
|
|
17481
|
+
method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
|
|
17482
|
+
deviceId: number().int(),
|
|
17483
|
+
...QueryWindowShape
|
|
17484
|
+
}), QueryResultSchema), method(object({
|
|
17485
|
+
nodeId: string().min(1),
|
|
17486
|
+
...QueryWindowShape
|
|
17487
|
+
}), QueryResultSchema, { auth: "admin" }), method(object({
|
|
17488
|
+
name: string().regex(/^[a-z0-9-]+$/),
|
|
17489
|
+
subjectKind: _enum(["device", "node"]),
|
|
17490
|
+
kind: DeviceHistoryKindSchema,
|
|
17491
|
+
unit: string().optional(),
|
|
17492
|
+
displayName: string().min(1),
|
|
17493
|
+
ingest: _enum(["points", "buckets"])
|
|
17494
|
+
}), object({ key: string() }), {
|
|
17495
|
+
kind: "mutation",
|
|
17496
|
+
auth: "admin"
|
|
17497
|
+
}), method(object({ points: array(object({
|
|
17498
|
+
key: string(),
|
|
17499
|
+
subject: DeviceHistorySubjectSchema,
|
|
17500
|
+
scope: string().default(""),
|
|
17501
|
+
ts: number(),
|
|
17502
|
+
value: number()
|
|
17503
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
17504
|
+
kind: "mutation",
|
|
17505
|
+
auth: "admin"
|
|
17506
|
+
}), method(object({ buckets: array(object({
|
|
17507
|
+
key: string(),
|
|
17508
|
+
subject: DeviceHistorySubjectSchema,
|
|
17509
|
+
scope: string().default(""),
|
|
17510
|
+
bucketStart: number(),
|
|
17511
|
+
samples: number().int().positive(),
|
|
17512
|
+
sum: number(),
|
|
17513
|
+
min: number(),
|
|
17514
|
+
max: number(),
|
|
17515
|
+
last: number().nullable(),
|
|
17516
|
+
lastTs: number().nullable()
|
|
17517
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
17518
|
+
kind: "mutation",
|
|
17519
|
+
auth: "admin"
|
|
17520
|
+
}), method(object({ deviceId: number().int() }), object({ enabled: boolean() })), method(object({
|
|
17521
|
+
deviceId: number().int(),
|
|
17522
|
+
enabled: boolean()
|
|
17523
|
+
}), object({ enabled: boolean() }), {
|
|
17524
|
+
kind: "mutation",
|
|
17525
|
+
auth: "admin"
|
|
17526
|
+
}), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
|
|
17527
|
+
var DeviceCaStatusSchema = discriminatedUnion("state", [
|
|
17528
|
+
object({ state: literal("absent") }),
|
|
17529
|
+
object({
|
|
17530
|
+
state: literal("ready"),
|
|
17531
|
+
subject: string(),
|
|
17532
|
+
fingerprintSha256: string(),
|
|
17533
|
+
validTo: string()
|
|
17534
|
+
}),
|
|
17535
|
+
object({
|
|
17536
|
+
state: literal("unavailable"),
|
|
17537
|
+
reason: string()
|
|
17538
|
+
})
|
|
17539
|
+
]);
|
|
17540
|
+
var DeviceCertificateSettingsSchema = object({ selfEnrollment: _enum(["allowed", "disabled"]) });
|
|
17541
|
+
method(object({
|
|
17542
|
+
userId: string().min(1).optional(),
|
|
17543
|
+
includeRevoked: boolean().default(false)
|
|
17544
|
+
}), array(DeviceCredentialSchema).readonly(), { auth: "admin" }), method(object({
|
|
17545
|
+
userId: string().min(1),
|
|
17546
|
+
deviceName: string().min(1).max(80)
|
|
17547
|
+
}), StartEnrollmentOutputSchema, {
|
|
17548
|
+
kind: "mutation",
|
|
17549
|
+
auth: "admin",
|
|
17550
|
+
caller: "required"
|
|
17551
|
+
}), method(object({ id: string().min(1) }), object({
|
|
17552
|
+
revoked: boolean(),
|
|
17553
|
+
sessionsEnded: number().int(),
|
|
17554
|
+
status: DeviceCredentialStatusSchema
|
|
17555
|
+
}), {
|
|
17556
|
+
kind: "mutation",
|
|
17557
|
+
auth: "admin",
|
|
17558
|
+
caller: "required"
|
|
17559
|
+
}), method(object({}), DeviceCertificateSettingsSchema, { auth: "admin" }), method(DeviceCertificateSettingsSchema, DeviceCertificateSettingsSchema, {
|
|
17560
|
+
kind: "mutation",
|
|
17561
|
+
auth: "admin"
|
|
17562
|
+
}), method(object({ id: string().min(1) }), object({ result: _enum([
|
|
17563
|
+
"deleted",
|
|
17564
|
+
"live",
|
|
17565
|
+
"unknown"
|
|
17566
|
+
]) }), {
|
|
17567
|
+
kind: "mutation",
|
|
17568
|
+
auth: "admin",
|
|
17569
|
+
caller: "required"
|
|
17570
|
+
}), method(object({}), DeviceCaStatusSchema, { auth: "admin" }), method(object({
|
|
17571
|
+
id: string().min(1),
|
|
17572
|
+
deviceName: string().min(1).max(80)
|
|
17573
|
+
}), object({ renamed: boolean() }), {
|
|
17574
|
+
kind: "mutation",
|
|
17575
|
+
auth: "admin"
|
|
17576
|
+
});
|
|
17577
|
+
/**
|
|
17578
|
+
* `node-certificates` - what a node holds and the two renewals the hub drives
|
|
17579
|
+
* (D856): the node's MESH leaf (mutual TLS to the hub) and its HTTPS leaf (issued
|
|
17580
|
+
* from the hub's local CA so a device that trusts the hub root trusts the node).
|
|
17581
|
+
*
|
|
17582
|
+
* Provided by the AGENT RUNTIME (the synthetic `agent-runtime` addon id, like
|
|
17583
|
+
* `server-management`): the hub reaches it through the ordinary node-pinned
|
|
17584
|
+
* capability call - no new Moleculer action. The hub's own certificates are
|
|
17585
|
+
* handled in-process by the hub (`certificates` router), so this cap has no hub
|
|
17586
|
+
* provider.
|
|
17587
|
+
*
|
|
17588
|
+
* No private key ever crosses the mesh: the node generates its key pair, sends a
|
|
17589
|
+
* CSR, and the hub returns only the signed certificate.
|
|
17590
|
+
*/
|
|
17591
|
+
var MeshLeafInfoSchema = object({
|
|
17592
|
+
cn: string(),
|
|
17593
|
+
serial: string(),
|
|
17594
|
+
fingerprintSha256: string(),
|
|
17595
|
+
notBefore: number(),
|
|
17596
|
+
notAfter: number()
|
|
17597
|
+
});
|
|
17598
|
+
var HttpsLeafInfoSchema = object({
|
|
17599
|
+
fingerprintSha256: string(),
|
|
17600
|
+
issuer: string(),
|
|
17601
|
+
sans: array(string()),
|
|
17602
|
+
notBefore: number(),
|
|
17603
|
+
notAfter: number()
|
|
17604
|
+
});
|
|
17605
|
+
var NodeHttpsStateSchema = discriminatedUnion("state", [object({
|
|
17606
|
+
state: literal("served"),
|
|
17607
|
+
leaf: HttpsLeafInfoSchema
|
|
17608
|
+
}), object({
|
|
17609
|
+
state: literal("not-issued"),
|
|
17610
|
+
reason: string()
|
|
17611
|
+
})]);
|
|
17612
|
+
method(object({}), object({
|
|
17613
|
+
nodeId: string(),
|
|
17614
|
+
mesh: MeshLeafInfoSchema.nullable(),
|
|
17615
|
+
https: NodeHttpsStateSchema
|
|
17616
|
+
}), { auth: "admin" }), method(object({}), object({ csrPem: string() }), {
|
|
17617
|
+
kind: "mutation",
|
|
17618
|
+
auth: "admin"
|
|
17619
|
+
}), method(object({
|
|
17620
|
+
certPem: string().min(1),
|
|
17621
|
+
caCertPem: string().min(1),
|
|
17622
|
+
confirmWithinMs: number().int().min(1e4).max(6e5)
|
|
17623
|
+
}), object({
|
|
17624
|
+
fingerprintSha256: string(),
|
|
17625
|
+
serial: string()
|
|
17626
|
+
}), {
|
|
17627
|
+
kind: "mutation",
|
|
17628
|
+
auth: "admin"
|
|
17629
|
+
}), method(object({ fingerprintSha256: string() }), object({ confirmed: boolean() }), {
|
|
17630
|
+
kind: "mutation",
|
|
17631
|
+
auth: "admin"
|
|
17632
|
+
}), method(object({}), object({ rolledBack: boolean() }), {
|
|
17633
|
+
kind: "mutation",
|
|
17634
|
+
auth: "admin"
|
|
17635
|
+
}), method(object({}), object({
|
|
17636
|
+
csrPem: string(),
|
|
17637
|
+
hostnames: array(string()),
|
|
17638
|
+
addresses: array(string()),
|
|
17639
|
+
/** SHA-256 of the hub local CA this node pinned at its first install; `null` before one. */
|
|
17640
|
+
pinnedCaFingerprintSha256: string().nullable()
|
|
17641
|
+
}), {
|
|
17642
|
+
kind: "mutation",
|
|
17643
|
+
auth: "admin"
|
|
17644
|
+
}), method(object({}), object({ ok: literal(true) }), {
|
|
17645
|
+
kind: "mutation",
|
|
17646
|
+
auth: "admin"
|
|
17647
|
+
}), method(object({
|
|
17648
|
+
certPem: string().min(1),
|
|
17649
|
+
caCertPem: string().min(1),
|
|
17650
|
+
/**
|
|
17651
|
+
* The hub signals that its local CA was rotated (D227) and this leaf chains to the NEW
|
|
17652
|
+
* one. Only the hub, over the authenticated mesh, can say so; a leaf with a different CA
|
|
17653
|
+
* and no signal is refused.
|
|
17654
|
+
*/
|
|
17655
|
+
caRotation: boolean().optional()
|
|
17656
|
+
}), HttpsLeafInfoSchema, {
|
|
17657
|
+
kind: "mutation",
|
|
17658
|
+
auth: "admin"
|
|
17659
|
+
});
|
|
17126
17660
|
var KeychainKeySourceSchema = object({
|
|
17127
17661
|
kind: _enum([
|
|
17128
17662
|
"config-file",
|
|
@@ -17597,6 +18131,10 @@ var deviceDiscoveryCapability = {
|
|
|
17597
18131
|
* `scripts/check-runtime-state-durability.ts`.
|
|
17598
18132
|
*/
|
|
17599
18133
|
durability: "session",
|
|
18134
|
+
/**
|
|
18135
|
+
* History (D850): none — inventory.
|
|
18136
|
+
*/
|
|
18137
|
+
history: "none",
|
|
17600
18138
|
methods: {
|
|
17601
18139
|
/**
|
|
17602
18140
|
* Snapshot of the current `discovered` list. Returns the
|
|
@@ -38297,6 +38835,42 @@ var DeviceRegisterPayloadSchema = object({
|
|
|
38297
38835
|
* omits it and the keyword backstop applies. */
|
|
38298
38836
|
secretConfigPaths: array(string()).optional()
|
|
38299
38837
|
});
|
|
38838
|
+
/** One deleted device, kept by device-manager so an addon that missed the
|
|
38839
|
+
* deletion can still learn of it (D865). Written by the delete path ONLY. */
|
|
38840
|
+
var DeviceTombstoneSchema = object({
|
|
38841
|
+
deviceId: number().int().positive(),
|
|
38842
|
+
/** Epoch ms the device was deleted. */
|
|
38843
|
+
deletedAt: number(),
|
|
38844
|
+
/** The addon that owned the device when it was deleted. */
|
|
38845
|
+
providerAddonId: string()
|
|
38846
|
+
});
|
|
38847
|
+
/** How long a tombstone stays readable. Past it, a device that was deleted
|
|
38848
|
+
* and never cleaned is only reachable by the admin "clean data of deleted
|
|
38849
|
+
* devices" action. */
|
|
38850
|
+
var DEVICE_TOMBSTONE_RETENTION_MS = 2160 * 60 * 60 * 1e3;
|
|
38851
|
+
/** Data held for one device that device-manager no longer knows. */
|
|
38852
|
+
var OrphanDeviceDataSchema = object({
|
|
38853
|
+
deviceId: number().int().positive(),
|
|
38854
|
+
/** Rows/files per store (`<addonId>:<store>`). */
|
|
38855
|
+
stores: record(string(), number().int().nonnegative())
|
|
38856
|
+
});
|
|
38857
|
+
var CleanupDeletedDevicesResultSchema = object({
|
|
38858
|
+
/**
|
|
38859
|
+
* `skipped` — the absence check could not be trusted (a device-list read
|
|
38860
|
+
* failed or the two reads disagreed); nothing was listed or deleted.
|
|
38861
|
+
* `dry-run` — `devices` is what a confirmed run would delete.
|
|
38862
|
+
* `cleaned` — `devices` is what was deleted.
|
|
38863
|
+
*/
|
|
38864
|
+
status: _enum([
|
|
38865
|
+
"skipped",
|
|
38866
|
+
"dry-run",
|
|
38867
|
+
"cleaned"
|
|
38868
|
+
]),
|
|
38869
|
+
reason: string().nullable(),
|
|
38870
|
+
devices: array(OrphanDeviceDataSchema),
|
|
38871
|
+
/** Implementers that could not be asked (their stores are not in `devices`). */
|
|
38872
|
+
unreachable: array(string())
|
|
38873
|
+
});
|
|
38300
38874
|
var DeviceRemovePayloadSchema = object({ deviceId: number() });
|
|
38301
38875
|
var DevicePersistConfigPayloadSchema = object({
|
|
38302
38876
|
deviceId: number(),
|
|
@@ -38535,6 +39109,9 @@ method(object({
|
|
|
38535
39109
|
}), method(object({ deviceId: number() }), object({ success: literal(true) }), {
|
|
38536
39110
|
kind: "mutation",
|
|
38537
39111
|
auth: "admin"
|
|
39112
|
+
}), method(object({ sinceMs: number() }), array(DeviceTombstoneSchema).readonly(), { auth: "admin" }), method(object({ confirm: boolean() }), CleanupDeletedDevicesResultSchema, {
|
|
39113
|
+
kind: "mutation",
|
|
39114
|
+
auth: "admin"
|
|
38538
39115
|
}), method(object({ integrationId: string() }), object({ removed: number() }), {
|
|
38539
39116
|
kind: "mutation",
|
|
38540
39117
|
auth: "admin"
|
|
@@ -39068,6 +39645,85 @@ var embeddingEncoderCapability = {
|
|
|
39068
39645
|
}
|
|
39069
39646
|
};
|
|
39070
39647
|
/**
|
|
39648
|
+
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
39649
|
+
* so it can delete what it keeps for that device (D865).
|
|
39650
|
+
*
|
|
39651
|
+
* ## Why an event was not enough
|
|
39652
|
+
*
|
|
39653
|
+
* `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
|
|
39654
|
+
* hung its per-device clean-up on it left durable garbage whenever the event was
|
|
39655
|
+
* lost, the addon was down, or it was restarting at that moment — footage,
|
|
39656
|
+
* analytics rows and settings of device 4483 outlived the device. Loss of this
|
|
39657
|
+
* signal corrupts durable state, so it travels by RPC with a recorded fact
|
|
39658
|
+
* behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
|
|
39659
|
+
*
|
|
39660
|
+
* ## The three pieces
|
|
39661
|
+
*
|
|
39662
|
+
* 1. device-manager records a TOMBSTONE per deleted device
|
|
39663
|
+
* (`deviceManager.listDeletedSince`). The tombstone is written by the delete
|
|
39664
|
+
* path only — a device that is unregistered, offline or whose provider is
|
|
39665
|
+
* restarting is NOT deleted and gets none.
|
|
39666
|
+
* 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
|
|
39667
|
+
* this collection, one by one, with bounded retries, logged.
|
|
39668
|
+
* 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
|
|
39669
|
+
* (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
|
|
39670
|
+
* may have missed. Reconcile is driven by tombstones, never by "the device is
|
|
39671
|
+
* not in the current list": a failed or partial list read must not destroy data.
|
|
39672
|
+
*
|
|
39673
|
+
* ## Contract for an implementer
|
|
39674
|
+
*
|
|
39675
|
+
* - **Idempotent.** It is called again by a retry, by a reconcile and by the
|
|
39676
|
+
* admin cleanup of data that predates tombstones. A device with nothing left
|
|
39677
|
+
* answers zero counts.
|
|
39678
|
+
* - **One key per store** in `counts`, deleted rows/files per store, so the log
|
|
39679
|
+
* line and the admin dry run can say where the data was.
|
|
39680
|
+
* - **Training datasets are NOT device data** and are never deleted by a hook.
|
|
39681
|
+
* - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
|
|
39682
|
+
* per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
|
|
39683
|
+
* for every addon centrally at delete time. This hook is for device DATA
|
|
39684
|
+
* that is not settings: footage, event media, analytics rows, history.
|
|
39685
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
39686
|
+
*
|
|
39687
|
+
* `listDeviceData` is the read side of the admin "Clean data of deleted devices"
|
|
39688
|
+
* action: which device ids this addon holds data for, and how much per store. It
|
|
39689
|
+
* never deletes. device-manager decides which of those ids are absent from the
|
|
39690
|
+
* fleet, from TWO consistent reads of the device list (D49).
|
|
39691
|
+
*/
|
|
39692
|
+
/** What a hook is told about the deletion. */
|
|
39693
|
+
var DeviceRemovedInputSchema = object({
|
|
39694
|
+
deviceId: number().int().positive(),
|
|
39695
|
+
/** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
|
|
39696
|
+
deletedAt: number(),
|
|
39697
|
+
/** The addon that owned the device, as device-manager last knew it. */
|
|
39698
|
+
providerAddonId: string()
|
|
39699
|
+
});
|
|
39700
|
+
/** Rows/files/refs deleted, per store this implementer owns. */
|
|
39701
|
+
var DeviceRemovedResultSchema = object({ counts: record(string(), number().int().nonnegative()) });
|
|
39702
|
+
/** One (store, device) pair an implementer holds data for. */
|
|
39703
|
+
var DeviceDataEntrySchema = object({
|
|
39704
|
+
store: string(),
|
|
39705
|
+
deviceId: number().int().positive(),
|
|
39706
|
+
/** Rows (or files) held for the device in the store. */
|
|
39707
|
+
count: number().int().nonnegative()
|
|
39708
|
+
});
|
|
39709
|
+
var deviceRemovalHookCapability = {
|
|
39710
|
+
name: "device-removal-hook",
|
|
39711
|
+
scope: "system",
|
|
39712
|
+
mode: "collection",
|
|
39713
|
+
internal: true,
|
|
39714
|
+
methods: {
|
|
39715
|
+
/** Delete everything this addon keeps for the deleted device. Idempotent. */
|
|
39716
|
+
onDeviceRemoved: method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
|
|
39717
|
+
kind: "mutation",
|
|
39718
|
+
auth: "admin"
|
|
39719
|
+
}),
|
|
39720
|
+
/** Which devices this addon holds data for, per store. Reads only. */
|
|
39721
|
+
listDeviceData: method(_void(), array(DeviceDataEntrySchema).readonly(), { auth: "admin" })
|
|
39722
|
+
},
|
|
39723
|
+
/** In-process only — enumerated through `addons.listCapabilityProviders`. */
|
|
39724
|
+
mount: { kind: "skip" }
|
|
39725
|
+
};
|
|
39726
|
+
/**
|
|
39071
39727
|
* `failure-contribution` — the capability an addon reports its OWN losses
|
|
39072
39728
|
* through, per camera, with the denominator attached. It stores nothing.
|
|
39073
39729
|
*
|
|
@@ -40144,7 +40800,13 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
40144
40800
|
* `beginExternalLink` offer exactly the redirect methods that set this,
|
|
40145
40801
|
* whatever their id. Absent / false — a login button only.
|
|
40146
40802
|
*/
|
|
40147
|
-
linkable: boolean().optional()
|
|
40803
|
+
linkable: boolean().optional(),
|
|
40804
|
+
/**
|
|
40805
|
+
* How a NATIVE app starts this method (D858): `{ kind: 'browser', startPath }`
|
|
40806
|
+
* when the route understands the app flow query (`app=1&code_challenge=…`),
|
|
40807
|
+
* `null`/absent when there is no app path - the app hides the method.
|
|
40808
|
+
*/
|
|
40809
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
40148
40810
|
}),
|
|
40149
40811
|
object({
|
|
40150
40812
|
kind: literal("widget"),
|
|
@@ -40156,7 +40818,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
40156
40818
|
bundle: string(),
|
|
40157
40819
|
/** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
|
|
40158
40820
|
remote: WidgetRemoteSchema,
|
|
40159
|
-
stage: LoginStageEnum
|
|
40821
|
+
stage: LoginStageEnum,
|
|
40822
|
+
/** Widgets are web ceremonies: no native app path (D858). Absent reads as `null`. */
|
|
40823
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
40160
40824
|
}),
|
|
40161
40825
|
object({
|
|
40162
40826
|
kind: literal("passkey"),
|
|
@@ -40168,7 +40832,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
40168
40832
|
/** Effective WebAuthn RP ID (`resolveRpID()`) — the shell gates visibility on it. */
|
|
40169
40833
|
rpId: string(),
|
|
40170
40834
|
/** Effective expected origin (`resolveOrigin()`), null when unconfigured. */
|
|
40171
|
-
origin: string().nullable()
|
|
40835
|
+
origin: string().nullable(),
|
|
40836
|
+
/** Set by the hub for the primary arm; a second-factor passkey has no app path (D858). */
|
|
40837
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
40172
40838
|
})
|
|
40173
40839
|
]);
|
|
40174
40840
|
method(_void(), array(LoginMethodContributionSchema).readonly());
|
|
@@ -40678,7 +41344,21 @@ var NetworkEndpointSchema = object({
|
|
|
40678
41344
|
url: string(),
|
|
40679
41345
|
hostname: string(),
|
|
40680
41346
|
port: number(),
|
|
40681
|
-
protocol: _enum(["http", "https"])
|
|
41347
|
+
protocol: _enum(["http", "https"]),
|
|
41348
|
+
/**
|
|
41349
|
+
* Whether this address survives a restart of its provider. `false` = it is
|
|
41350
|
+
* re-issued every time (a Quick tunnel's random `*.trycloudflare.com`); the
|
|
41351
|
+
* hub never selects such an address AUTOMATICALLY for a role (D860), though
|
|
41352
|
+
* it stays visible and an operator may still flag it. Absent = stable: every
|
|
41353
|
+
* provider except a Quick tunnel owns a name that does not change.
|
|
41354
|
+
*/
|
|
41355
|
+
stable: boolean().optional()
|
|
41356
|
+
});
|
|
41357
|
+
object({
|
|
41358
|
+
url: string(),
|
|
41359
|
+
/** Mirrors {@link NetworkEndpointSchema} `stable`; absent = stable. */
|
|
41360
|
+
stable: boolean().optional(),
|
|
41361
|
+
updated: boolean().optional()
|
|
40682
41362
|
});
|
|
40683
41363
|
var NetworkAccessStatusSchema = object({
|
|
40684
41364
|
connected: boolean(),
|
|
@@ -41806,6 +42486,10 @@ var alarmPanelCapability = {
|
|
|
41806
42486
|
* `scripts/check-runtime-state-durability.ts`.
|
|
41807
42487
|
*/
|
|
41808
42488
|
durability: "restored",
|
|
42489
|
+
/**
|
|
42490
|
+
* History (D850): none — enum state; arm/disarm history belongs in the events ledger.
|
|
42491
|
+
*/
|
|
42492
|
+
history: "none",
|
|
41809
42493
|
/** Clock fields: written, but excluded from the compare that decides
|
|
41810
42494
|
* whether persisting is worth a SQLite commit. */
|
|
41811
42495
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -50220,7 +50904,11 @@ var zonesCapability = {
|
|
|
50220
50904
|
* See `RuntimeStateDurability`. Enforced by
|
|
50221
50905
|
* `scripts/check-runtime-state-durability.ts`.
|
|
50222
50906
|
*/
|
|
50223
|
-
durability: "restored"
|
|
50907
|
+
durability: "restored",
|
|
50908
|
+
/**
|
|
50909
|
+
* History (D850): none — configuration arrays.
|
|
50910
|
+
*/
|
|
50911
|
+
history: "none"
|
|
50224
50912
|
};
|
|
50225
50913
|
/**
|
|
50226
50914
|
* A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
|
|
@@ -52601,7 +53289,22 @@ var SsoBridgeClaimsSchema = object({
|
|
|
52601
53289
|
* request to present the matching cookie — a login bridge is useless in
|
|
52602
53290
|
* any other browser.
|
|
52603
53291
|
*/
|
|
52604
|
-
browserBinding: string().optional()
|
|
53292
|
+
browserBinding: string().optional(),
|
|
53293
|
+
/**
|
|
53294
|
+
* The native app that started this sign-in (D858): its PKCE challenge,
|
|
53295
|
+
* `state`, purpose and allow-listed return URL, copied from the server-side
|
|
53296
|
+
* pending OIDC state. A bridge carrying it is finished ONLY at
|
|
53297
|
+
* `/api/auth/sso/finish-app` (which mints a handoff code, never a web
|
|
53298
|
+
* session); `/api/auth/sso/finish` refuses it.
|
|
53299
|
+
*/
|
|
53300
|
+
app: object({
|
|
53301
|
+
codeChallenge: string(),
|
|
53302
|
+
state: string(),
|
|
53303
|
+
purpose: _enum(["new-session", "step-up"]),
|
|
53304
|
+
redirect: string(),
|
|
53305
|
+
/** The page language the app asked for (D858); the confirm page speaks it. */
|
|
53306
|
+
lang: _enum(["en", "it"]).optional()
|
|
53307
|
+
}).optional()
|
|
52605
53308
|
});
|
|
52606
53309
|
method(object({
|
|
52607
53310
|
claims: SsoBridgeClaimsSchema,
|
|
@@ -53008,6 +53711,10 @@ var streamSignalsCapability = {
|
|
|
53008
53711
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53009
53712
|
*/
|
|
53010
53713
|
durability: "session",
|
|
53714
|
+
/**
|
|
53715
|
+
* History (D850): none — array state.
|
|
53716
|
+
*/
|
|
53717
|
+
history: "none",
|
|
53011
53718
|
methods: {
|
|
53012
53719
|
/**
|
|
53013
53720
|
* What this device can emit. Empty is a valid and common answer — most
|
|
@@ -54870,7 +55577,12 @@ var SearchResultSchema = object({
|
|
|
54870
55577
|
publishedAt: string(),
|
|
54871
55578
|
author: string(),
|
|
54872
55579
|
installed: boolean(),
|
|
54873
|
-
installedVersion: string().optional()
|
|
55580
|
+
installedVersion: string().optional(),
|
|
55581
|
+
/**
|
|
55582
|
+
* Capability names the package's addons declare (from its published
|
|
55583
|
+
* manifest). `null` = the registry lookup failed — unknown, never `[]` (D393).
|
|
55584
|
+
*/
|
|
55585
|
+
capabilities: array(string()).readonly().nullable()
|
|
54874
55586
|
});
|
|
54875
55587
|
var AutoUpdateSettingsSchema = object({
|
|
54876
55588
|
channel: ChannelSchema,
|
|
@@ -55032,7 +55744,11 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
55032
55744
|
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
55033
55745
|
kind: "mutation",
|
|
55034
55746
|
auth: "admin"
|
|
55035
|
-
}), method(object({
|
|
55747
|
+
}), method(object({
|
|
55748
|
+
query: string().optional(),
|
|
55749
|
+
/** Only packages whose addons declare this capability (unknown ones excluded). */
|
|
55750
|
+
capability: string().optional()
|
|
55751
|
+
}), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
55036
55752
|
name: string().min(1),
|
|
55037
55753
|
version: string().optional(),
|
|
55038
55754
|
nodeId: string().optional()
|
|
@@ -55168,6 +55884,36 @@ var airQualitySensorCapability = {
|
|
|
55168
55884
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55169
55885
|
*/
|
|
55170
55886
|
durability: "restored",
|
|
55887
|
+
/**
|
|
55888
|
+
* History (D850): recorded series.
|
|
55889
|
+
*/
|
|
55890
|
+
history: { fields: {
|
|
55891
|
+
co2Ppm: {
|
|
55892
|
+
kind: "gauge",
|
|
55893
|
+
unit: "ppm",
|
|
55894
|
+
deadband: 5
|
|
55895
|
+
},
|
|
55896
|
+
vocPpb: {
|
|
55897
|
+
kind: "gauge",
|
|
55898
|
+
unit: "ppb",
|
|
55899
|
+
deadband: 5
|
|
55900
|
+
},
|
|
55901
|
+
pm25: {
|
|
55902
|
+
kind: "gauge",
|
|
55903
|
+
unit: "ug/m3",
|
|
55904
|
+
deadband: 1
|
|
55905
|
+
},
|
|
55906
|
+
pm10: {
|
|
55907
|
+
kind: "gauge",
|
|
55908
|
+
unit: "ug/m3",
|
|
55909
|
+
deadband: 1
|
|
55910
|
+
},
|
|
55911
|
+
aqi: {
|
|
55912
|
+
kind: "gauge",
|
|
55913
|
+
unit: "count",
|
|
55914
|
+
deadband: 1
|
|
55915
|
+
}
|
|
55916
|
+
} },
|
|
55171
55917
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55172
55918
|
* whether persisting is worth a SQLite commit. */
|
|
55173
55919
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55210,6 +55956,15 @@ var ambientLightSensorCapability = {
|
|
|
55210
55956
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55211
55957
|
*/
|
|
55212
55958
|
durability: "restored",
|
|
55959
|
+
/**
|
|
55960
|
+
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
55961
|
+
*/
|
|
55962
|
+
history: { fields: { lux: {
|
|
55963
|
+
kind: "gauge",
|
|
55964
|
+
unit: "lx",
|
|
55965
|
+
deadbandPct: 10,
|
|
55966
|
+
minIntervalMs: 6e4
|
|
55967
|
+
} } },
|
|
55213
55968
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55214
55969
|
* whether persisting is worth a SQLite commit. */
|
|
55215
55970
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55337,7 +56092,11 @@ var audioMetricsCapability = {
|
|
|
55337
56092
|
* See `RuntimeStateDurability`. Enforced by
|
|
55338
56093
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55339
56094
|
*/
|
|
55340
|
-
durability: "session"
|
|
56095
|
+
durability: "session",
|
|
56096
|
+
/**
|
|
56097
|
+
* History (D850): none — the level is the addon series `pipeline-analytics/audio-level` (producer `record`); the other numbers move every inference window and duplicate it.
|
|
56098
|
+
*/
|
|
56099
|
+
history: "none"
|
|
55341
56100
|
};
|
|
55342
56101
|
/**
|
|
55343
56102
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
@@ -55406,7 +56165,11 @@ var automationControlCapability = {
|
|
|
55406
56165
|
* See `RuntimeStateDurability`. Enforced by
|
|
55407
56166
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55408
56167
|
*/
|
|
55409
|
-
durability: "session"
|
|
56168
|
+
durability: "session",
|
|
56169
|
+
/**
|
|
56170
|
+
* History (D850): none — configuration and transient run state.
|
|
56171
|
+
*/
|
|
56172
|
+
history: "none"
|
|
55410
56173
|
};
|
|
55411
56174
|
/**
|
|
55412
56175
|
* Battery status snapshot. Emitted by providers whose device is
|
|
@@ -55587,6 +56350,13 @@ onStatusChanged: { data: object({
|
|
|
55587
56350
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55588
56351
|
*/
|
|
55589
56352
|
durability: "restored",
|
|
56353
|
+
/**
|
|
56354
|
+
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
56355
|
+
*/
|
|
56356
|
+
history: { fields: { percentage: {
|
|
56357
|
+
kind: "gauge",
|
|
56358
|
+
unit: "%"
|
|
56359
|
+
} } },
|
|
55590
56360
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55591
56361
|
* whether persisting is worth a SQLite commit. */
|
|
55592
56362
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -55626,6 +56396,10 @@ var binaryCapability = {
|
|
|
55626
56396
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55627
56397
|
*/
|
|
55628
56398
|
durability: "restored",
|
|
56399
|
+
/**
|
|
56400
|
+
* History (D850): recorded series.
|
|
56401
|
+
*/
|
|
56402
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
55629
56403
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55630
56404
|
* whether persisting is worth a SQLite commit. */
|
|
55631
56405
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55688,7 +56462,15 @@ onBrightnessChanged: { data: object({
|
|
|
55688
56462
|
* See `RuntimeStateDurability`. Enforced by
|
|
55689
56463
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55690
56464
|
*/
|
|
55691
|
-
durability: "session"
|
|
56465
|
+
durability: "session",
|
|
56466
|
+
/**
|
|
56467
|
+
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
56468
|
+
*/
|
|
56469
|
+
history: { fields: { percentage: {
|
|
56470
|
+
kind: "gauge",
|
|
56471
|
+
unit: "%",
|
|
56472
|
+
minIntervalMs: 0
|
|
56473
|
+
} } }
|
|
55692
56474
|
};
|
|
55693
56475
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
55694
56476
|
kind: "mutation",
|
|
@@ -56049,6 +56831,10 @@ var carbonMonoxideCapability = {
|
|
|
56049
56831
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56050
56832
|
*/
|
|
56051
56833
|
durability: "restored",
|
|
56834
|
+
/**
|
|
56835
|
+
* History (D850): recorded series.
|
|
56836
|
+
*/
|
|
56837
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
56052
56838
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56053
56839
|
* whether persisting is worth a SQLite commit. */
|
|
56054
56840
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -56218,7 +57004,37 @@ var climateControlCapability = {
|
|
|
56218
57004
|
* See `RuntimeStateDurability`. Enforced by
|
|
56219
57005
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56220
57006
|
*/
|
|
56221
|
-
durability: "session"
|
|
57007
|
+
durability: "session",
|
|
57008
|
+
/**
|
|
57009
|
+
* History (D850): recorded series. Celsius by contract; setpoints keep every change (`minIntervalMs: 0`).
|
|
57010
|
+
*/
|
|
57011
|
+
history: { fields: {
|
|
57012
|
+
currentTemp: {
|
|
57013
|
+
kind: "gauge",
|
|
57014
|
+
unit: "°C",
|
|
57015
|
+
deadband: .1
|
|
57016
|
+
},
|
|
57017
|
+
currentHumidity: {
|
|
57018
|
+
kind: "gauge",
|
|
57019
|
+
unit: "%",
|
|
57020
|
+
deadband: .5
|
|
57021
|
+
},
|
|
57022
|
+
target: {
|
|
57023
|
+
kind: "gauge",
|
|
57024
|
+
unit: "°C",
|
|
57025
|
+
minIntervalMs: 0
|
|
57026
|
+
},
|
|
57027
|
+
targetHigh: {
|
|
57028
|
+
kind: "gauge",
|
|
57029
|
+
unit: "°C",
|
|
57030
|
+
minIntervalMs: 0
|
|
57031
|
+
},
|
|
57032
|
+
targetLow: {
|
|
57033
|
+
kind: "gauge",
|
|
57034
|
+
unit: "°C",
|
|
57035
|
+
minIntervalMs: 0
|
|
57036
|
+
}
|
|
57037
|
+
} }
|
|
56222
57038
|
};
|
|
56223
57039
|
/**
|
|
56224
57040
|
* Color-light cap. Coexists with `switch` (on/off) and `brightness`
|
|
@@ -56335,7 +57151,11 @@ onColorChanged: { data: object({
|
|
|
56335
57151
|
* See `RuntimeStateDurability`. Enforced by
|
|
56336
57152
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56337
57153
|
*/
|
|
56338
|
-
durability: "session"
|
|
57154
|
+
durability: "session",
|
|
57155
|
+
/**
|
|
57156
|
+
* History (D850): none — nested and cosmetic.
|
|
57157
|
+
*/
|
|
57158
|
+
history: "none"
|
|
56339
57159
|
};
|
|
56340
57160
|
var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
|
|
56341
57161
|
object({
|
|
@@ -56401,6 +57221,10 @@ var connectivityCapability = {
|
|
|
56401
57221
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56402
57222
|
*/
|
|
56403
57223
|
durability: "restored",
|
|
57224
|
+
/**
|
|
57225
|
+
* History (D850): none — duplicates device-status.online (one authority for availability).
|
|
57226
|
+
*/
|
|
57227
|
+
history: "none",
|
|
56404
57228
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56405
57229
|
* whether persisting is worth a SQLite commit. */
|
|
56406
57230
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -56525,6 +57349,10 @@ reset: method(object({
|
|
|
56525
57349
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56526
57350
|
*/
|
|
56527
57351
|
durability: "restored",
|
|
57352
|
+
/**
|
|
57353
|
+
* History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
|
|
57354
|
+
*/
|
|
57355
|
+
history: "none",
|
|
56528
57356
|
/** Clocks, not content: a re-read that changed no item costs no commit. */
|
|
56529
57357
|
volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
|
|
56530
57358
|
};
|
|
@@ -56565,6 +57393,10 @@ var contactCapability = {
|
|
|
56565
57393
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56566
57394
|
*/
|
|
56567
57395
|
durability: "restored",
|
|
57396
|
+
/**
|
|
57397
|
+
* History (D850): recorded series.
|
|
57398
|
+
*/
|
|
57399
|
+
history: { fields: { entryOpen: { kind: "boolean" } } },
|
|
56568
57400
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56569
57401
|
* whether persisting is worth a SQLite commit. */
|
|
56570
57402
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -56680,7 +57512,11 @@ var controlCapability = {
|
|
|
56680
57512
|
* See `RuntimeStateDurability`. Enforced by
|
|
56681
57513
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56682
57514
|
*/
|
|
56683
|
-
durability: "session"
|
|
57515
|
+
durability: "session",
|
|
57516
|
+
/**
|
|
57517
|
+
* History (D850): none — `value` is a number/string union; configuration entity.
|
|
57518
|
+
*/
|
|
57519
|
+
history: "none"
|
|
56684
57520
|
};
|
|
56685
57521
|
/**
|
|
56686
57522
|
* Window covering / blinds / garage door / valve cap. Models HA
|
|
@@ -56771,6 +57607,14 @@ var coverCapability = {
|
|
|
56771
57607
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56772
57608
|
*/
|
|
56773
57609
|
durability: "restored",
|
|
57610
|
+
/**
|
|
57611
|
+
* History (D850): recorded series. Actuator tier: position keeps every tick of a movement.
|
|
57612
|
+
*/
|
|
57613
|
+
history: { fields: { position: {
|
|
57614
|
+
kind: "gauge",
|
|
57615
|
+
unit: "%",
|
|
57616
|
+
minIntervalMs: 0
|
|
57617
|
+
} } },
|
|
56774
57618
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56775
57619
|
* whether persisting is worth a SQLite commit. */
|
|
56776
57620
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -56875,6 +57719,10 @@ var dayNightCapability = {
|
|
|
56875
57719
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56876
57720
|
*/
|
|
56877
57721
|
durability: "restored",
|
|
57722
|
+
/**
|
|
57723
|
+
* History (D850): none — firmware configuration, not a measurement.
|
|
57724
|
+
*/
|
|
57725
|
+
history: "none",
|
|
56878
57726
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56879
57727
|
* whether persisting is worth a SQLite commit. */
|
|
56880
57728
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -56932,6 +57780,10 @@ onStatusChanged: { data: object({
|
|
|
56932
57780
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56933
57781
|
*/
|
|
56934
57782
|
durability: "restored",
|
|
57783
|
+
/**
|
|
57784
|
+
* History (D850): recorded series. The ONE availability series.
|
|
57785
|
+
*/
|
|
57786
|
+
history: { fields: { online: { kind: "boolean" } } },
|
|
56935
57787
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56936
57788
|
* whether persisting is worth a SQLite commit. */
|
|
56937
57789
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -56998,7 +57850,11 @@ onPressed: {
|
|
|
56998
57850
|
* See `RuntimeStateDurability`. Enforced by
|
|
56999
57851
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57000
57852
|
*/
|
|
57001
|
-
durability: "restored"
|
|
57853
|
+
durability: "restored",
|
|
57854
|
+
/**
|
|
57855
|
+
* History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
|
|
57856
|
+
*/
|
|
57857
|
+
history: "none"
|
|
57002
57858
|
};
|
|
57003
57859
|
/**
|
|
57004
57860
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
@@ -57046,6 +57902,10 @@ var enumSensorCapability = {
|
|
|
57046
57902
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57047
57903
|
*/
|
|
57048
57904
|
durability: "restored",
|
|
57905
|
+
/**
|
|
57906
|
+
* History (D850): none — text/enum state has no history (non-goal).
|
|
57907
|
+
*/
|
|
57908
|
+
history: "none",
|
|
57049
57909
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57050
57910
|
* whether persisting is worth a SQLite commit. */
|
|
57051
57911
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -57091,7 +57951,11 @@ var eventEmitterCapability = {
|
|
|
57091
57951
|
* See `RuntimeStateDurability`. Enforced by
|
|
57092
57952
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57093
57953
|
*/
|
|
57094
|
-
durability: "session"
|
|
57954
|
+
durability: "session",
|
|
57955
|
+
/**
|
|
57956
|
+
* History (D850): none — `eventCountSinceStart` resets with the addon; events live in ledgers.
|
|
57957
|
+
*/
|
|
57958
|
+
history: "none"
|
|
57095
57959
|
};
|
|
57096
57960
|
var IdentitySchema = object({
|
|
57097
57961
|
id: string(),
|
|
@@ -57587,7 +58451,18 @@ var fanControlCapability = {
|
|
|
57587
58451
|
* See `RuntimeStateDurability`. Enforced by
|
|
57588
58452
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57589
58453
|
*/
|
|
57590
|
-
durability: "session"
|
|
58454
|
+
durability: "session",
|
|
58455
|
+
/**
|
|
58456
|
+
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
58457
|
+
*/
|
|
58458
|
+
history: { fields: {
|
|
58459
|
+
percentage: {
|
|
58460
|
+
kind: "gauge",
|
|
58461
|
+
unit: "%",
|
|
58462
|
+
minIntervalMs: 0
|
|
58463
|
+
},
|
|
58464
|
+
oscillating: { kind: "boolean" }
|
|
58465
|
+
} }
|
|
57591
58466
|
};
|
|
57592
58467
|
/**
|
|
57593
58468
|
* Per-device feature/identity probe slice. Holds the runtime-resolved
|
|
@@ -57670,7 +58545,11 @@ onProbeChanged: { data: object({
|
|
|
57670
58545
|
* See `RuntimeStateDurability`. Enforced by
|
|
57671
58546
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57672
58547
|
*/
|
|
57673
|
-
durability: "session"
|
|
58548
|
+
durability: "session",
|
|
58549
|
+
/**
|
|
58550
|
+
* History (D850): none — static identity and capability probe.
|
|
58551
|
+
*/
|
|
58552
|
+
history: "none"
|
|
57674
58553
|
};
|
|
57675
58554
|
/**
|
|
57676
58555
|
* Water leak / moisture sensor. Boolean "is liquid currently
|
|
@@ -57705,6 +58584,10 @@ var floodCapability = {
|
|
|
57705
58584
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57706
58585
|
*/
|
|
57707
58586
|
durability: "restored",
|
|
58587
|
+
/**
|
|
58588
|
+
* History (D850): recorded series.
|
|
58589
|
+
*/
|
|
58590
|
+
history: { fields: { flooded: { kind: "boolean" } } },
|
|
57708
58591
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57709
58592
|
* whether persisting is worth a SQLite commit. */
|
|
57710
58593
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -57738,6 +58621,10 @@ var gasCapability = {
|
|
|
57738
58621
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57739
58622
|
*/
|
|
57740
58623
|
durability: "restored",
|
|
58624
|
+
/**
|
|
58625
|
+
* History (D850): recorded series.
|
|
58626
|
+
*/
|
|
58627
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
57741
58628
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57742
58629
|
* whether persisting is worth a SQLite commit. */
|
|
57743
58630
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -57823,7 +58710,18 @@ var humidifierCapability = {
|
|
|
57823
58710
|
* See `RuntimeStateDurability`. Enforced by
|
|
57824
58711
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57825
58712
|
*/
|
|
57826
|
-
durability: "session"
|
|
58713
|
+
durability: "session",
|
|
58714
|
+
/**
|
|
58715
|
+
* History (D850): recorded series.
|
|
58716
|
+
*/
|
|
58717
|
+
history: { fields: {
|
|
58718
|
+
currentHumidity: {
|
|
58719
|
+
kind: "gauge",
|
|
58720
|
+
unit: "%",
|
|
58721
|
+
deadband: .5
|
|
58722
|
+
},
|
|
58723
|
+
on: { kind: "boolean" }
|
|
58724
|
+
} }
|
|
57827
58725
|
};
|
|
57828
58726
|
/**
|
|
57829
58727
|
* Single-metric humidity reading. Drives Home Assistant `sensor`
|
|
@@ -57867,6 +58765,14 @@ var humiditySensorCapability = {
|
|
|
57867
58765
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57868
58766
|
*/
|
|
57869
58767
|
durability: "restored",
|
|
58768
|
+
/**
|
|
58769
|
+
* History (D850): recorded series.
|
|
58770
|
+
*/
|
|
58771
|
+
history: { fields: { percent: {
|
|
58772
|
+
kind: "gauge",
|
|
58773
|
+
unit: "%",
|
|
58774
|
+
deadband: .5
|
|
58775
|
+
} } },
|
|
57870
58776
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57871
58777
|
* whether persisting is worth a SQLite commit. */
|
|
57872
58778
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -57914,7 +58820,11 @@ var imageCapability = {
|
|
|
57914
58820
|
* See `RuntimeStateDurability`. Enforced by
|
|
57915
58821
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57916
58822
|
*/
|
|
57917
|
-
durability: "session"
|
|
58823
|
+
durability: "session",
|
|
58824
|
+
/**
|
|
58825
|
+
* History (D850): none — not numeric.
|
|
58826
|
+
*/
|
|
58827
|
+
history: "none"
|
|
57918
58828
|
};
|
|
57919
58829
|
/**
|
|
57920
58830
|
* Vendor-neutral image / picture-adjustment cap — the per-camera config
|
|
@@ -58071,6 +58981,10 @@ var imageSettingsCapability = {
|
|
|
58071
58981
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58072
58982
|
*/
|
|
58073
58983
|
durability: "restored",
|
|
58984
|
+
/**
|
|
58985
|
+
* History (D850): none — camera image configuration (operator intent), not a trend.
|
|
58986
|
+
*/
|
|
58987
|
+
history: "none",
|
|
58074
58988
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58075
58989
|
* whether persisting is worth a SQLite commit. */
|
|
58076
58990
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -58456,7 +59370,11 @@ var intercomCapability = {
|
|
|
58456
59370
|
* See `RuntimeStateDurability`. Enforced by
|
|
58457
59371
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58458
59372
|
*/
|
|
58459
|
-
durability: "session"
|
|
59373
|
+
durability: "session",
|
|
59374
|
+
/**
|
|
59375
|
+
* History (D850): none — talk sessions are a ledger concern, not a trend.
|
|
59376
|
+
*/
|
|
59377
|
+
history: "none"
|
|
58460
59378
|
};
|
|
58461
59379
|
/**
|
|
58462
59380
|
* Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
|
|
@@ -58537,7 +59455,15 @@ var lawnMowerControlCapability = {
|
|
|
58537
59455
|
* See `RuntimeStateDurability`. Enforced by
|
|
58538
59456
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58539
59457
|
*/
|
|
58540
|
-
durability: "session"
|
|
59458
|
+
durability: "session",
|
|
59459
|
+
/**
|
|
59460
|
+
* History (D850): recorded series.
|
|
59461
|
+
*/
|
|
59462
|
+
history: { fields: { batteryLevel: {
|
|
59463
|
+
kind: "gauge",
|
|
59464
|
+
unit: "%",
|
|
59465
|
+
deadband: 2
|
|
59466
|
+
} } }
|
|
58541
59467
|
};
|
|
58542
59468
|
/**
|
|
58543
59469
|
* local-network — hub-only singleton.
|
|
@@ -58664,7 +59590,13 @@ var ConnectionEndpointSchema = object({
|
|
|
58664
59590
|
* calls so the client can sort even if the cap returns a new
|
|
58665
59591
|
* ordering between polls.
|
|
58666
59592
|
*/
|
|
58667
|
-
priority: number()
|
|
59593
|
+
priority: number(),
|
|
59594
|
+
/**
|
|
59595
|
+
* `false` = the address changes on its own (a Quick tunnel, re-issued on
|
|
59596
|
+
* every respawn). Automatic role resolution skips it (D860); an explicit
|
|
59597
|
+
* operator flag still honours it. Absent = stable.
|
|
59598
|
+
*/
|
|
59599
|
+
stable: boolean().optional()
|
|
58668
59600
|
});
|
|
58669
59601
|
/**
|
|
58670
59602
|
* Where the advertised local port came from. Ordered most → least
|
|
@@ -58829,7 +59761,19 @@ var TlsStatusSchema = object({
|
|
|
58829
59761
|
sans: array(string()),
|
|
58830
59762
|
caCertPem: string().nullable(),
|
|
58831
59763
|
reissueError: string().nullable(),
|
|
58832
|
-
restartRequired: boolean()
|
|
59764
|
+
restartRequired: boolean(),
|
|
59765
|
+
/** An uploaded certificate is served but no CA is kept for it and it is not publicly signed (D873). */
|
|
59766
|
+
caMissing: boolean(),
|
|
59767
|
+
/** Does the hub's own generated CA carry a critical name constraint? `null` while it has none. */
|
|
59768
|
+
localCaConstrained: boolean().nullable(),
|
|
59769
|
+
/** ISO time the generated CA was replaced by a constrained one; devices must re-download it. */
|
|
59770
|
+
caReplacedAt: string().nullable(),
|
|
59771
|
+
/** The uploaded certificate kept on disk, selectable again after "Revert to generated". */
|
|
59772
|
+
storedUpload: object({
|
|
59773
|
+
leafFingerprintSha256: string(),
|
|
59774
|
+
validTo: string(),
|
|
59775
|
+
hasCa: boolean()
|
|
59776
|
+
}).nullable()
|
|
58833
59777
|
});
|
|
58834
59778
|
method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
|
|
58835
59779
|
/**
|
|
@@ -58885,6 +59829,9 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
58885
59829
|
}), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
|
|
58886
59830
|
kind: "mutation",
|
|
58887
59831
|
auth: "admin"
|
|
59832
|
+
}), method(_void(), TlsStatusSchema, {
|
|
59833
|
+
kind: "mutation",
|
|
59834
|
+
auth: "admin"
|
|
58888
59835
|
});
|
|
58889
59836
|
/**
|
|
58890
59837
|
* Smart-lock cap. Models HA `lock.*` entities — anything with a
|
|
@@ -58965,6 +59912,10 @@ var lockControlCapability = {
|
|
|
58965
59912
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58966
59913
|
*/
|
|
58967
59914
|
durability: "restored",
|
|
59915
|
+
/**
|
|
59916
|
+
* History (D850): none — enum state; lock events belong in the events ledger.
|
|
59917
|
+
*/
|
|
59918
|
+
history: "none",
|
|
58968
59919
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58969
59920
|
* whether persisting is worth a SQLite commit. */
|
|
58970
59921
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -59136,7 +60087,11 @@ var mediaPlayerCapability = {
|
|
|
59136
60087
|
* See `RuntimeStateDurability`. Enforced by
|
|
59137
60088
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59138
60089
|
*/
|
|
59139
|
-
durability: "session"
|
|
60090
|
+
durability: "session",
|
|
60091
|
+
/**
|
|
60092
|
+
* History (D850): none — `positionMs` moves continuously while playing; volume is transient.
|
|
60093
|
+
*/
|
|
60094
|
+
history: "none"
|
|
59140
60095
|
};
|
|
59141
60096
|
/**
|
|
59142
60097
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
@@ -59470,7 +60425,14 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
59470
60425
|
* See `RuntimeStateDurability`. Enforced by
|
|
59471
60426
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59472
60427
|
*/
|
|
59473
|
-
durability: "session"
|
|
60428
|
+
durability: "session",
|
|
60429
|
+
/**
|
|
60430
|
+
* History (D850): recorded series. A PIR sensor is a series; a camera is not (its motion is an addon series and a ledger).
|
|
60431
|
+
*/
|
|
60432
|
+
history: { fields: { detected: {
|
|
60433
|
+
kind: "boolean",
|
|
60434
|
+
excludeDeviceTypes: [DeviceType.Camera]
|
|
60435
|
+
} } }
|
|
59474
60436
|
};
|
|
59475
60437
|
/**
|
|
59476
60438
|
* Motion-trigger toggle for accessory devices.
|
|
@@ -59542,7 +60504,11 @@ var motionTriggerCapability = {
|
|
|
59542
60504
|
* See `RuntimeStateDurability`. Enforced by
|
|
59543
60505
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59544
60506
|
*/
|
|
59545
|
-
durability: "session"
|
|
60507
|
+
durability: "session",
|
|
60508
|
+
/**
|
|
60509
|
+
* History (D850): none — configuration switch.
|
|
60510
|
+
*/
|
|
60511
|
+
history: "none"
|
|
59546
60512
|
};
|
|
59547
60513
|
/**
|
|
59548
60514
|
* Motion-zones share the same MaskShape vocabulary as privacy-mask — the
|
|
@@ -59617,6 +60583,10 @@ var motionZonesCapability = {
|
|
|
59617
60583
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59618
60584
|
*/
|
|
59619
60585
|
durability: "restored",
|
|
60586
|
+
/**
|
|
60587
|
+
* History (D850): none — configuration.
|
|
60588
|
+
*/
|
|
60589
|
+
history: "none",
|
|
59620
60590
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59621
60591
|
* whether persisting is worth a SQLite commit. */
|
|
59622
60592
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59746,6 +60716,10 @@ var nativeObjectDetectionCapability = {
|
|
|
59746
60716
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59747
60717
|
*/
|
|
59748
60718
|
durability: "restored",
|
|
60719
|
+
/**
|
|
60720
|
+
* History (D850): none — event-like and nested per class; detections live in the objects ledger.
|
|
60721
|
+
*/
|
|
60722
|
+
history: "none",
|
|
59749
60723
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59750
60724
|
* whether persisting is worth a SQLite commit. */
|
|
59751
60725
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -60029,7 +61003,11 @@ var navigationCapability = {
|
|
|
60029
61003
|
* See `RuntimeStateDurability`. Enforced by
|
|
60030
61004
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60031
61005
|
*/
|
|
60032
|
-
durability: "session"
|
|
61006
|
+
durability: "session",
|
|
61007
|
+
/**
|
|
61008
|
+
* History (D850): none — control state of a robotic camera, configuration-like.
|
|
61009
|
+
*/
|
|
61010
|
+
history: "none"
|
|
60033
61011
|
};
|
|
60034
61012
|
/**
|
|
60035
61013
|
* Network-link snapshot. Same shape for every provider (a Reolink wifi
|
|
@@ -60109,6 +61087,23 @@ onStatusChanged: { data: object({
|
|
|
60109
61087
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60110
61088
|
*/
|
|
60111
61089
|
durability: "restored",
|
|
61090
|
+
/**
|
|
61091
|
+
* History (D850): recorded series.
|
|
61092
|
+
*/
|
|
61093
|
+
history: { fields: {
|
|
61094
|
+
signalPercent: {
|
|
61095
|
+
kind: "gauge",
|
|
61096
|
+
unit: "%",
|
|
61097
|
+
deadband: 3,
|
|
61098
|
+
minIntervalMs: 6e4
|
|
61099
|
+
},
|
|
61100
|
+
rssiDbm: {
|
|
61101
|
+
kind: "gauge",
|
|
61102
|
+
unit: "dBm",
|
|
61103
|
+
deadband: 2,
|
|
61104
|
+
minIntervalMs: 6e4
|
|
61105
|
+
}
|
|
61106
|
+
} },
|
|
60112
61107
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60113
61108
|
* whether persisting is worth a SQLite commit. */
|
|
60114
61109
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -60497,7 +61492,11 @@ onSent: { data: object({
|
|
|
60497
61492
|
* See `RuntimeStateDurability`. Enforced by
|
|
60498
61493
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60499
61494
|
*/
|
|
60500
|
-
durability: "session"
|
|
61495
|
+
durability: "session",
|
|
61496
|
+
/**
|
|
61497
|
+
* History (D850): none — `queueDepth` is outbox operational state, not a device trend.
|
|
61498
|
+
*/
|
|
61499
|
+
history: "none"
|
|
60501
61500
|
};
|
|
60502
61501
|
/**
|
|
60503
61502
|
* Generic numeric sensor — last-resort fallback when no typed numeric
|
|
@@ -60548,6 +61547,14 @@ var numericSensorCapability = {
|
|
|
60548
61547
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60549
61548
|
*/
|
|
60550
61549
|
durability: "restored",
|
|
61550
|
+
/**
|
|
61551
|
+
* History (D850): recorded series. The unit is per device, read from the sibling `unit` field.
|
|
61552
|
+
*/
|
|
61553
|
+
history: { fields: { value: {
|
|
61554
|
+
kind: "gauge",
|
|
61555
|
+
unitFrom: "unit",
|
|
61556
|
+
minIntervalMs: 3e4
|
|
61557
|
+
} } },
|
|
60551
61558
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60552
61559
|
* whether persisting is worth a SQLite commit. */
|
|
60553
61560
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -60978,7 +61985,24 @@ var petFeederCapability = {
|
|
|
60978
61985
|
* See `RuntimeStateDurability`. Enforced by
|
|
60979
61986
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60980
61987
|
*/
|
|
60981
|
-
durability: "session"
|
|
61988
|
+
durability: "session",
|
|
61989
|
+
/**
|
|
61990
|
+
* History (D850): recorded series.
|
|
61991
|
+
*/
|
|
61992
|
+
history: { fields: {
|
|
61993
|
+
foodLevel: { kind: "gauge" },
|
|
61994
|
+
food1: { kind: "gauge" },
|
|
61995
|
+
food2: { kind: "gauge" },
|
|
61996
|
+
batteryPower: {
|
|
61997
|
+
kind: "gauge",
|
|
61998
|
+
unit: "%",
|
|
61999
|
+
deadband: 2
|
|
62000
|
+
},
|
|
62001
|
+
desiccantLeftDays: {
|
|
62002
|
+
kind: "gauge",
|
|
62003
|
+
unit: "days"
|
|
62004
|
+
}
|
|
62005
|
+
} }
|
|
60982
62006
|
};
|
|
60983
62007
|
var VehicleSchema = object({
|
|
60984
62008
|
id: string(),
|
|
@@ -61390,6 +62414,47 @@ var powerMeterCapability = {
|
|
|
61390
62414
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61391
62415
|
*/
|
|
61392
62416
|
durability: "restored",
|
|
62417
|
+
/**
|
|
62418
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `kwhTotal` is the one monotonic meter (counter).
|
|
62419
|
+
*/
|
|
62420
|
+
history: { fields: {
|
|
62421
|
+
watts: {
|
|
62422
|
+
kind: "gauge",
|
|
62423
|
+
unit: "W",
|
|
62424
|
+
deadband: 1,
|
|
62425
|
+
minIntervalMs: 3e4
|
|
62426
|
+
},
|
|
62427
|
+
kwhTotal: {
|
|
62428
|
+
kind: "counter",
|
|
62429
|
+
unit: "kWh",
|
|
62430
|
+
deadband: .01,
|
|
62431
|
+
minIntervalMs: 6e4
|
|
62432
|
+
},
|
|
62433
|
+
volts: {
|
|
62434
|
+
kind: "gauge",
|
|
62435
|
+
unit: "V",
|
|
62436
|
+
deadband: 1,
|
|
62437
|
+
minIntervalMs: 3e4
|
|
62438
|
+
},
|
|
62439
|
+
amps: {
|
|
62440
|
+
kind: "gauge",
|
|
62441
|
+
unit: "A",
|
|
62442
|
+
deadband: .05,
|
|
62443
|
+
minIntervalMs: 3e4
|
|
62444
|
+
},
|
|
62445
|
+
va: {
|
|
62446
|
+
kind: "gauge",
|
|
62447
|
+
unit: "VA",
|
|
62448
|
+
deadband: 1,
|
|
62449
|
+
minIntervalMs: 3e4
|
|
62450
|
+
},
|
|
62451
|
+
powerFactor: {
|
|
62452
|
+
kind: "gauge",
|
|
62453
|
+
unit: "ratio",
|
|
62454
|
+
deadband: .01,
|
|
62455
|
+
minIntervalMs: 6e4
|
|
62456
|
+
}
|
|
62457
|
+
} },
|
|
61393
62458
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61394
62459
|
* whether persisting is worth a SQLite commit. */
|
|
61395
62460
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -61457,6 +62522,14 @@ var presenceCapability = {
|
|
|
61457
62522
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61458
62523
|
*/
|
|
61459
62524
|
durability: "restored",
|
|
62525
|
+
/**
|
|
62526
|
+
* History (D850): recorded series.
|
|
62527
|
+
*/
|
|
62528
|
+
history: { fields: { batteryPercent: {
|
|
62529
|
+
kind: "gauge",
|
|
62530
|
+
unit: "%",
|
|
62531
|
+
deadband: 1
|
|
62532
|
+
} } },
|
|
61460
62533
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61461
62534
|
* whether persisting is worth a SQLite commit. */
|
|
61462
62535
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -61503,6 +62576,14 @@ var pressureSensorCapability = {
|
|
|
61503
62576
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61504
62577
|
*/
|
|
61505
62578
|
durability: "restored",
|
|
62579
|
+
/**
|
|
62580
|
+
* History (D850): recorded series.
|
|
62581
|
+
*/
|
|
62582
|
+
history: { fields: { hpa: {
|
|
62583
|
+
kind: "gauge",
|
|
62584
|
+
unit: "hPa",
|
|
62585
|
+
deadband: .1
|
|
62586
|
+
} } },
|
|
61506
62587
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61507
62588
|
* whether persisting is worth a SQLite commit. */
|
|
61508
62589
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -61662,6 +62743,10 @@ var privacyMaskCapability = {
|
|
|
61662
62743
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61663
62744
|
*/
|
|
61664
62745
|
durability: "restored",
|
|
62746
|
+
/**
|
|
62747
|
+
* History (D850): none — configuration.
|
|
62748
|
+
*/
|
|
62749
|
+
history: "none",
|
|
61665
62750
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61666
62751
|
* whether persisting is worth a SQLite commit. */
|
|
61667
62752
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -62023,7 +63108,11 @@ var ptzAutotrackCapability = {
|
|
|
62023
63108
|
* See `RuntimeStateDurability`. Enforced by
|
|
62024
63109
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62025
63110
|
*/
|
|
62026
|
-
durability: "session"
|
|
63111
|
+
durability: "session",
|
|
63112
|
+
/**
|
|
63113
|
+
* History (D850): none — configuration and capability.
|
|
63114
|
+
*/
|
|
63115
|
+
history: "none"
|
|
62027
63116
|
};
|
|
62028
63117
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
|
|
62029
63118
|
kind: "mutation",
|
|
@@ -63481,6 +64570,10 @@ var recordingOnboardCapability = {
|
|
|
63481
64570
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63482
64571
|
*/
|
|
63483
64572
|
durability: "restored",
|
|
64573
|
+
/**
|
|
64574
|
+
* History (D850): none — SD-card configuration and window inventory; arrays.
|
|
64575
|
+
*/
|
|
64576
|
+
history: "none",
|
|
63484
64577
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63485
64578
|
* whether persisting is worth a SQLite commit. */
|
|
63486
64579
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -63554,7 +64647,11 @@ getStatus: method(object({ deviceId: number() }), RecordingSignalStatusSchema) }
|
|
|
63554
64647
|
* See `RuntimeStateDurability`. Enforced by
|
|
63555
64648
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63556
64649
|
*/
|
|
63557
|
-
durability: "session"
|
|
64650
|
+
durability: "session",
|
|
64651
|
+
/**
|
|
64652
|
+
* History (D850): none — recording intent is already in the recordings ledger.
|
|
64653
|
+
*/
|
|
64654
|
+
history: "none"
|
|
63558
64655
|
};
|
|
63559
64656
|
/**
|
|
63560
64657
|
* scene-monitor — device-scoped reference-region state cap. An operator marks
|
|
@@ -63945,7 +65042,11 @@ var sceneMonitorCapability = {
|
|
|
63945
65042
|
* See `RuntimeStateDurability`. Enforced by
|
|
63946
65043
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63947
65044
|
*/
|
|
63948
|
-
durability: "session"
|
|
65045
|
+
durability: "session",
|
|
65046
|
+
/**
|
|
65047
|
+
* History (D850): none — nested configuration.
|
|
65048
|
+
*/
|
|
65049
|
+
history: "none"
|
|
63949
65050
|
};
|
|
63950
65051
|
/**
|
|
63951
65052
|
* Per-stage gating mode applied to the zones a rule references.
|
|
@@ -64096,7 +65197,11 @@ var scriptRunnerCapability = {
|
|
|
64096
65197
|
* See `RuntimeStateDurability`. Enforced by
|
|
64097
65198
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64098
65199
|
*/
|
|
64099
|
-
durability: "session"
|
|
65200
|
+
durability: "session",
|
|
65201
|
+
/**
|
|
65202
|
+
* History (D850): none — transient; run results belong in a ledger.
|
|
65203
|
+
*/
|
|
65204
|
+
history: "none"
|
|
64100
65205
|
};
|
|
64101
65206
|
/**
|
|
64102
65207
|
* Smoke alarm sensor — boolean "is smoke currently detected" with
|
|
@@ -64131,6 +65236,10 @@ var smokeCapability = {
|
|
|
64131
65236
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64132
65237
|
*/
|
|
64133
65238
|
durability: "restored",
|
|
65239
|
+
/**
|
|
65240
|
+
* History (D850): recorded series.
|
|
65241
|
+
*/
|
|
65242
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
64134
65243
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64135
65244
|
* whether persisting is worth a SQLite commit. */
|
|
64136
65245
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64230,6 +65339,10 @@ var streamCatalogCapability = {
|
|
|
64230
65339
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64231
65340
|
*/
|
|
64232
65341
|
durability: "restored",
|
|
65342
|
+
/**
|
|
65343
|
+
* History (D850): none — stream inventory.
|
|
65344
|
+
*/
|
|
65345
|
+
history: "none",
|
|
64233
65346
|
/** Clock field: written, but excluded from the compare that decides whether
|
|
64234
65347
|
* persisting is worth a SQLite commit — the descriptors are the value. */
|
|
64235
65348
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -64379,6 +65492,10 @@ var streamParamsCapability = {
|
|
|
64379
65492
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64380
65493
|
*/
|
|
64381
65494
|
durability: "restored",
|
|
65495
|
+
/**
|
|
65496
|
+
* History (D850): none — encoder configuration.
|
|
65497
|
+
*/
|
|
65498
|
+
history: "none",
|
|
64382
65499
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64383
65500
|
* whether persisting is worth a SQLite commit. */
|
|
64384
65501
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -64434,6 +65551,10 @@ var switchCapability = {
|
|
|
64434
65551
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64435
65552
|
*/
|
|
64436
65553
|
durability: "restored",
|
|
65554
|
+
/**
|
|
65555
|
+
* History (D850): recorded series.
|
|
65556
|
+
*/
|
|
65557
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
64437
65558
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64438
65559
|
* whether persisting is worth a SQLite commit. */
|
|
64439
65560
|
volatileStateFields: ["lastChangedAt"],
|
|
@@ -64448,6 +65569,21 @@ var switchCapability = {
|
|
|
64448
65569
|
}
|
|
64449
65570
|
}] }
|
|
64450
65571
|
};
|
|
65572
|
+
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
65573
|
+
function hasControlCharacter(value) {
|
|
65574
|
+
for (const char of value) {
|
|
65575
|
+
const code = char.codePointAt(0) ?? 0;
|
|
65576
|
+
if (code <= 31 || code >= 127 && code <= 159) return true;
|
|
65577
|
+
}
|
|
65578
|
+
return false;
|
|
65579
|
+
}
|
|
65580
|
+
string().transform((value) => value.trim()).pipe(string().min(1, "The server name cannot be empty").max(48, `The server name is at most 48 characters`).refine((value) => !hasControlCharacter(value), { message: "The server name cannot contain control characters" }));
|
|
65581
|
+
/** What every reader gets: the name to show, and whether the hub chose it itself. */
|
|
65582
|
+
var ServerNameInfoSchema = object({
|
|
65583
|
+
name: string(),
|
|
65584
|
+
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
65585
|
+
isDefault: boolean()
|
|
65586
|
+
});
|
|
64451
65587
|
/**
|
|
64452
65588
|
* system — system-scoped singleton capability exposing hub-level
|
|
64453
65589
|
* health, feature flags, network interface enumeration, and the
|
|
@@ -64477,6 +65613,12 @@ var FeatureManifestSchema = object({
|
|
|
64477
65613
|
backup: boolean(),
|
|
64478
65614
|
repl: boolean()
|
|
64479
65615
|
});
|
|
65616
|
+
/**
|
|
65617
|
+
* `system.info`: the feature flags plus the hub's human name (D861). The name is
|
|
65618
|
+
* `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
|
|
65619
|
+
* is the machine hostname.
|
|
65620
|
+
*/
|
|
65621
|
+
var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
|
|
64480
65622
|
var HealthStatusSchema = object({
|
|
64481
65623
|
status: literal("ok"),
|
|
64482
65624
|
uptime: number()
|
|
@@ -64949,7 +66091,7 @@ var LoggingSettingsStateSchema = object({
|
|
|
64949
66091
|
opsLogRetentionDays: number().int().min(0),
|
|
64950
66092
|
persisted: boolean()
|
|
64951
66093
|
});
|
|
64952
|
-
method(_void(),
|
|
66094
|
+
method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
64953
66095
|
kind: "mutation",
|
|
64954
66096
|
auth: "admin"
|
|
64955
66097
|
}), method(_void(), _void(), {
|
|
@@ -64995,6 +66137,10 @@ var tamperCapability = {
|
|
|
64995
66137
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64996
66138
|
*/
|
|
64997
66139
|
durability: "restored",
|
|
66140
|
+
/**
|
|
66141
|
+
* History (D850): recorded series.
|
|
66142
|
+
*/
|
|
66143
|
+
history: { fields: { tampered: { kind: "boolean" } } },
|
|
64998
66144
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64999
66145
|
* whether persisting is worth a SQLite commit. */
|
|
65000
66146
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65050,6 +66196,14 @@ var temperatureSensorCapability = {
|
|
|
65050
66196
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65051
66197
|
*/
|
|
65052
66198
|
durability: "restored",
|
|
66199
|
+
/**
|
|
66200
|
+
* History (D850): recorded series.
|
|
66201
|
+
*/
|
|
66202
|
+
history: { fields: { celsius: {
|
|
66203
|
+
kind: "gauge",
|
|
66204
|
+
unit: "°C",
|
|
66205
|
+
deadband: .1
|
|
66206
|
+
} } },
|
|
65053
66207
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65054
66208
|
* whether persisting is worth a SQLite commit. */
|
|
65055
66209
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -65128,7 +66282,11 @@ var updateCapability = {
|
|
|
65128
66282
|
* See `RuntimeStateDurability`. Enforced by
|
|
65129
66283
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65130
66284
|
*/
|
|
65131
|
-
durability: "session"
|
|
66285
|
+
durability: "session",
|
|
66286
|
+
/**
|
|
66287
|
+
* History (D850): none — text and state.
|
|
66288
|
+
*/
|
|
66289
|
+
history: "none"
|
|
65132
66290
|
};
|
|
65133
66291
|
var UserSummarySchema = object({
|
|
65134
66292
|
id: string(),
|
|
@@ -65485,7 +66643,37 @@ var vacuumControlCapability = {
|
|
|
65485
66643
|
* See `RuntimeStateDurability`. Enforced by
|
|
65486
66644
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65487
66645
|
*/
|
|
65488
|
-
durability: "session"
|
|
66646
|
+
durability: "session",
|
|
66647
|
+
/**
|
|
66648
|
+
* History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
|
|
66649
|
+
*/
|
|
66650
|
+
history: { fields: {
|
|
66651
|
+
batteryLevel: {
|
|
66652
|
+
kind: "gauge",
|
|
66653
|
+
unit: "%",
|
|
66654
|
+
deadband: 2
|
|
66655
|
+
},
|
|
66656
|
+
"cleanWater.level": {
|
|
66657
|
+
kind: "gauge",
|
|
66658
|
+
unit: "%",
|
|
66659
|
+
deadband: 2
|
|
66660
|
+
},
|
|
66661
|
+
"dirtyWater.level": {
|
|
66662
|
+
kind: "gauge",
|
|
66663
|
+
unit: "%",
|
|
66664
|
+
deadband: 2
|
|
66665
|
+
},
|
|
66666
|
+
"detergent.level": {
|
|
66667
|
+
kind: "gauge",
|
|
66668
|
+
unit: "%",
|
|
66669
|
+
deadband: 2
|
|
66670
|
+
},
|
|
66671
|
+
"dustBin.level": {
|
|
66672
|
+
kind: "gauge",
|
|
66673
|
+
unit: "%",
|
|
66674
|
+
deadband: 2
|
|
66675
|
+
}
|
|
66676
|
+
} }
|
|
65489
66677
|
};
|
|
65490
66678
|
var ValveStatusSchema = object({
|
|
65491
66679
|
/** Lifecycle state of the valve. */
|
|
@@ -65544,7 +66732,15 @@ var valveCapability = {
|
|
|
65544
66732
|
* See `RuntimeStateDurability`. Enforced by
|
|
65545
66733
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65546
66734
|
*/
|
|
65547
|
-
durability: "session"
|
|
66735
|
+
durability: "session",
|
|
66736
|
+
/**
|
|
66737
|
+
* History (D850): recorded series. Actuator tier: position keeps every change.
|
|
66738
|
+
*/
|
|
66739
|
+
history: { fields: { position: {
|
|
66740
|
+
kind: "gauge",
|
|
66741
|
+
unit: "%",
|
|
66742
|
+
minIntervalMs: 0
|
|
66743
|
+
} } }
|
|
65548
66744
|
};
|
|
65549
66745
|
/**
|
|
65550
66746
|
* Vibration / shake / impact sensor. Drives Home Assistant
|
|
@@ -65574,6 +66770,10 @@ var vibrationCapability = {
|
|
|
65574
66770
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65575
66771
|
*/
|
|
65576
66772
|
durability: "restored",
|
|
66773
|
+
/**
|
|
66774
|
+
* History (D850): recorded series.
|
|
66775
|
+
*/
|
|
66776
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
65577
66777
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65578
66778
|
* whether persisting is worth a SQLite commit. */
|
|
65579
66779
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65657,7 +66857,22 @@ var waterHeaterCapability = {
|
|
|
65657
66857
|
* See `RuntimeStateDurability`. Enforced by
|
|
65658
66858
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65659
66859
|
*/
|
|
65660
|
-
durability: "session"
|
|
66860
|
+
durability: "session",
|
|
66861
|
+
/**
|
|
66862
|
+
* History (D850): recorded series. The schema carries no unit; providers publish Celsius. Setpoint keeps every change.
|
|
66863
|
+
*/
|
|
66864
|
+
history: { fields: {
|
|
66865
|
+
currentTemp: {
|
|
66866
|
+
kind: "gauge",
|
|
66867
|
+
unit: "°C",
|
|
66868
|
+
deadband: .5
|
|
66869
|
+
},
|
|
66870
|
+
targetTemp: {
|
|
66871
|
+
kind: "gauge",
|
|
66872
|
+
unit: "°C",
|
|
66873
|
+
minIntervalMs: 0
|
|
66874
|
+
}
|
|
66875
|
+
} }
|
|
65661
66876
|
};
|
|
65662
66877
|
/**
|
|
65663
66878
|
* Weather provider cap. Models HA `weather.*` entities — a read-only
|
|
@@ -65723,7 +66938,32 @@ var weatherCapability = {
|
|
|
65723
66938
|
* See `RuntimeStateDurability`. Enforced by
|
|
65724
66939
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65725
66940
|
*/
|
|
65726
|
-
durability: "session"
|
|
66941
|
+
durability: "session",
|
|
66942
|
+
/**
|
|
66943
|
+
* History (D850): recorded series. Units follow the sibling `*Unit` fields.
|
|
66944
|
+
*/
|
|
66945
|
+
history: { fields: {
|
|
66946
|
+
temperature: {
|
|
66947
|
+
kind: "gauge",
|
|
66948
|
+
unitFrom: "temperatureUnit",
|
|
66949
|
+
deadband: .2
|
|
66950
|
+
},
|
|
66951
|
+
humidity: {
|
|
66952
|
+
kind: "gauge",
|
|
66953
|
+
unit: "%",
|
|
66954
|
+
deadband: 1
|
|
66955
|
+
},
|
|
66956
|
+
pressure: {
|
|
66957
|
+
kind: "gauge",
|
|
66958
|
+
unitFrom: "pressureUnit",
|
|
66959
|
+
deadband: .5
|
|
66960
|
+
},
|
|
66961
|
+
windSpeed: {
|
|
66962
|
+
kind: "gauge",
|
|
66963
|
+
unitFrom: "windSpeedUnit",
|
|
66964
|
+
deadband: .5
|
|
66965
|
+
}
|
|
66966
|
+
} }
|
|
65727
66967
|
};
|
|
65728
66968
|
/**
|
|
65729
66969
|
* Per-zone occupancy aggregation produced by the analytics frame
|
|
@@ -65965,7 +67205,11 @@ var zoneAnalyticsCapability = {
|
|
|
65965
67205
|
* See `RuntimeStateDurability`. Enforced by
|
|
65966
67206
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65967
67207
|
*/
|
|
65968
|
-
durability: "session"
|
|
67208
|
+
durability: "session",
|
|
67209
|
+
/**
|
|
67210
|
+
* History (D850): none — occupancy is the addon series `pipeline-analytics/occupancy`; the rest is per-zone arrays keyed by runtime ids.
|
|
67211
|
+
*/
|
|
67212
|
+
history: "none"
|
|
65969
67213
|
};
|
|
65970
67214
|
/**
|
|
65971
67215
|
* Stages a {@link ZoneRule} can apply to. Discriminator on the rules
|
|
@@ -66050,7 +67294,11 @@ var zoneRulesCapability = {
|
|
|
66050
67294
|
* See `RuntimeStateDurability`. Enforced by
|
|
66051
67295
|
* `scripts/check-runtime-state-durability.ts`.
|
|
66052
67296
|
*/
|
|
66053
|
-
durability: "restored"
|
|
67297
|
+
durability: "restored",
|
|
67298
|
+
/**
|
|
67299
|
+
* History (D850): none — configuration arrays.
|
|
67300
|
+
*/
|
|
67301
|
+
history: "none"
|
|
66054
67302
|
};
|
|
66055
67303
|
/**
|
|
66056
67304
|
* `training-provider` — ONE cloud that can run the CamStack trainer.
|
|
@@ -69215,6 +70463,54 @@ Object.freeze({
|
|
|
69215
70463
|
addonId: null,
|
|
69216
70464
|
access: "create"
|
|
69217
70465
|
},
|
|
70466
|
+
"deviceCredentials.deleteDeviceCredential": {
|
|
70467
|
+
capName: "device-credentials",
|
|
70468
|
+
capScope: "system",
|
|
70469
|
+
addonId: null,
|
|
70470
|
+
access: "delete"
|
|
70471
|
+
},
|
|
70472
|
+
"deviceCredentials.getDeviceCaStatus": {
|
|
70473
|
+
capName: "device-credentials",
|
|
70474
|
+
capScope: "system",
|
|
70475
|
+
addonId: null,
|
|
70476
|
+
access: "view"
|
|
70477
|
+
},
|
|
70478
|
+
"deviceCredentials.getDeviceCertificateSettings": {
|
|
70479
|
+
capName: "device-credentials",
|
|
70480
|
+
capScope: "system",
|
|
70481
|
+
addonId: null,
|
|
70482
|
+
access: "view"
|
|
70483
|
+
},
|
|
70484
|
+
"deviceCredentials.listDeviceCredentials": {
|
|
70485
|
+
capName: "device-credentials",
|
|
70486
|
+
capScope: "system",
|
|
70487
|
+
addonId: null,
|
|
70488
|
+
access: "view"
|
|
70489
|
+
},
|
|
70490
|
+
"deviceCredentials.renameDeviceCredential": {
|
|
70491
|
+
capName: "device-credentials",
|
|
70492
|
+
capScope: "system",
|
|
70493
|
+
addonId: null,
|
|
70494
|
+
access: "create"
|
|
70495
|
+
},
|
|
70496
|
+
"deviceCredentials.revokeDeviceCredential": {
|
|
70497
|
+
capName: "device-credentials",
|
|
70498
|
+
capScope: "system",
|
|
70499
|
+
addonId: null,
|
|
70500
|
+
access: "delete"
|
|
70501
|
+
},
|
|
70502
|
+
"deviceCredentials.setDeviceCertificateSettings": {
|
|
70503
|
+
capName: "device-credentials",
|
|
70504
|
+
capScope: "system",
|
|
70505
|
+
addonId: null,
|
|
70506
|
+
access: "create"
|
|
70507
|
+
},
|
|
70508
|
+
"deviceCredentials.startEnrollment": {
|
|
70509
|
+
capName: "device-credentials",
|
|
70510
|
+
capScope: "system",
|
|
70511
|
+
addonId: null,
|
|
70512
|
+
access: "create"
|
|
70513
|
+
},
|
|
69218
70514
|
"deviceDiscovery.adoptDevice": {
|
|
69219
70515
|
capName: "device-discovery",
|
|
69220
70516
|
capScope: "device",
|
|
@@ -69317,6 +70613,66 @@ Object.freeze({
|
|
|
69317
70613
|
addonId: null,
|
|
69318
70614
|
access: "create"
|
|
69319
70615
|
},
|
|
70616
|
+
"deviceHistory.declareSeries": {
|
|
70617
|
+
capName: "device-history",
|
|
70618
|
+
capScope: "system",
|
|
70619
|
+
addonId: null,
|
|
70620
|
+
access: "create"
|
|
70621
|
+
},
|
|
70622
|
+
"deviceHistory.getDeviceEnabled": {
|
|
70623
|
+
capName: "device-history",
|
|
70624
|
+
capScope: "system",
|
|
70625
|
+
addonId: null,
|
|
70626
|
+
access: "view"
|
|
70627
|
+
},
|
|
70628
|
+
"deviceHistory.getStatus": {
|
|
70629
|
+
capName: "device-history",
|
|
70630
|
+
capScope: "system",
|
|
70631
|
+
addonId: null,
|
|
70632
|
+
access: "view"
|
|
70633
|
+
},
|
|
70634
|
+
"deviceHistory.listNodeSeries": {
|
|
70635
|
+
capName: "device-history",
|
|
70636
|
+
capScope: "system",
|
|
70637
|
+
addonId: null,
|
|
70638
|
+
access: "view"
|
|
70639
|
+
},
|
|
70640
|
+
"deviceHistory.listSeries": {
|
|
70641
|
+
capName: "device-history",
|
|
70642
|
+
capScope: "system",
|
|
70643
|
+
addonId: null,
|
|
70644
|
+
access: "view"
|
|
70645
|
+
},
|
|
70646
|
+
"deviceHistory.query": {
|
|
70647
|
+
capName: "device-history",
|
|
70648
|
+
capScope: "system",
|
|
70649
|
+
addonId: null,
|
|
70650
|
+
access: "view"
|
|
70651
|
+
},
|
|
70652
|
+
"deviceHistory.queryNode": {
|
|
70653
|
+
capName: "device-history",
|
|
70654
|
+
capScope: "system",
|
|
70655
|
+
addonId: null,
|
|
70656
|
+
access: "view"
|
|
70657
|
+
},
|
|
70658
|
+
"deviceHistory.record": {
|
|
70659
|
+
capName: "device-history",
|
|
70660
|
+
capScope: "system",
|
|
70661
|
+
addonId: null,
|
|
70662
|
+
access: "create"
|
|
70663
|
+
},
|
|
70664
|
+
"deviceHistory.recordBuckets": {
|
|
70665
|
+
capName: "device-history",
|
|
70666
|
+
capScope: "system",
|
|
70667
|
+
addonId: null,
|
|
70668
|
+
access: "create"
|
|
70669
|
+
},
|
|
70670
|
+
"deviceHistory.setDeviceEnabled": {
|
|
70671
|
+
capName: "device-history",
|
|
70672
|
+
capScope: "system",
|
|
70673
|
+
addonId: null,
|
|
70674
|
+
access: "create"
|
|
70675
|
+
},
|
|
69320
70676
|
"deviceManager.addLocation": {
|
|
69321
70677
|
capName: "device-manager",
|
|
69322
70678
|
capScope: "system",
|
|
@@ -69395,6 +70751,12 @@ Object.freeze({
|
|
|
69395
70751
|
addonId: null,
|
|
69396
70752
|
access: "create"
|
|
69397
70753
|
},
|
|
70754
|
+
"deviceManager.cleanupDeletedDevicesData": {
|
|
70755
|
+
capName: "device-manager",
|
|
70756
|
+
capScope: "system",
|
|
70757
|
+
addonId: null,
|
|
70758
|
+
access: "create"
|
|
70759
|
+
},
|
|
69398
70760
|
"deviceManager.createDevice": {
|
|
69399
70761
|
capName: "device-manager",
|
|
69400
70762
|
capScope: "system",
|
|
@@ -69575,6 +70937,12 @@ Object.freeze({
|
|
|
69575
70937
|
addonId: null,
|
|
69576
70938
|
access: "view"
|
|
69577
70939
|
},
|
|
70940
|
+
"deviceManager.listDeletedSince": {
|
|
70941
|
+
capName: "device-manager",
|
|
70942
|
+
capScope: "system",
|
|
70943
|
+
addonId: null,
|
|
70944
|
+
access: "view"
|
|
70945
|
+
},
|
|
69578
70946
|
"deviceManager.listDeviceIdsByCaps": {
|
|
69579
70947
|
capName: "device-manager",
|
|
69580
70948
|
capScope: "system",
|
|
@@ -69983,6 +71351,18 @@ Object.freeze({
|
|
|
69983
71351
|
addonId: null,
|
|
69984
71352
|
access: "create"
|
|
69985
71353
|
},
|
|
71354
|
+
"deviceRemovalHook.listDeviceData": {
|
|
71355
|
+
capName: "device-removal-hook",
|
|
71356
|
+
capScope: "system",
|
|
71357
|
+
addonId: null,
|
|
71358
|
+
access: "view"
|
|
71359
|
+
},
|
|
71360
|
+
"deviceRemovalHook.onDeviceRemoved": {
|
|
71361
|
+
capName: "device-removal-hook",
|
|
71362
|
+
capScope: "system",
|
|
71363
|
+
addonId: null,
|
|
71364
|
+
access: "create"
|
|
71365
|
+
},
|
|
69986
71366
|
"deviceState.claimFields": {
|
|
69987
71367
|
capName: "device-state",
|
|
69988
71368
|
capScope: "system",
|
|
@@ -70415,6 +71795,12 @@ Object.freeze({
|
|
|
70415
71795
|
addonId: null,
|
|
70416
71796
|
access: "delete"
|
|
70417
71797
|
},
|
|
71798
|
+
"keychain.deleteDeviceScope": {
|
|
71799
|
+
capName: "keychain",
|
|
71800
|
+
capScope: "system",
|
|
71801
|
+
addonId: null,
|
|
71802
|
+
access: "delete"
|
|
71803
|
+
},
|
|
70418
71804
|
"keychain.getState": {
|
|
70419
71805
|
capName: "keychain",
|
|
70420
71806
|
capScope: "system",
|
|
@@ -70853,6 +72239,12 @@ Object.freeze({
|
|
|
70853
72239
|
addonId: null,
|
|
70854
72240
|
access: "create"
|
|
70855
72241
|
},
|
|
72242
|
+
"localNetwork.useStoredUploadedCertificate": {
|
|
72243
|
+
capName: "local-network",
|
|
72244
|
+
capScope: "system",
|
|
72245
|
+
addonId: null,
|
|
72246
|
+
access: "create"
|
|
72247
|
+
},
|
|
70856
72248
|
"lockControl.getStatus": {
|
|
70857
72249
|
capName: "lock-control",
|
|
70858
72250
|
capScope: "device",
|
|
@@ -71375,6 +72767,54 @@ Object.freeze({
|
|
|
71375
72767
|
addonId: null,
|
|
71376
72768
|
access: "create"
|
|
71377
72769
|
},
|
|
72770
|
+
"nodeCertificates.confirmMeshLeaf": {
|
|
72771
|
+
capName: "node-certificates",
|
|
72772
|
+
capScope: "system",
|
|
72773
|
+
addonId: null,
|
|
72774
|
+
access: "create"
|
|
72775
|
+
},
|
|
72776
|
+
"nodeCertificates.forgetHub": {
|
|
72777
|
+
capName: "node-certificates",
|
|
72778
|
+
capScope: "system",
|
|
72779
|
+
addonId: null,
|
|
72780
|
+
access: "delete"
|
|
72781
|
+
},
|
|
72782
|
+
"nodeCertificates.getCertificates": {
|
|
72783
|
+
capName: "node-certificates",
|
|
72784
|
+
capScope: "system",
|
|
72785
|
+
addonId: null,
|
|
72786
|
+
access: "view"
|
|
72787
|
+
},
|
|
72788
|
+
"nodeCertificates.installHttpsCertificate": {
|
|
72789
|
+
capName: "node-certificates",
|
|
72790
|
+
capScope: "system",
|
|
72791
|
+
addonId: null,
|
|
72792
|
+
access: "create"
|
|
72793
|
+
},
|
|
72794
|
+
"nodeCertificates.installMeshLeaf": {
|
|
72795
|
+
capName: "node-certificates",
|
|
72796
|
+
capScope: "system",
|
|
72797
|
+
addonId: null,
|
|
72798
|
+
access: "create"
|
|
72799
|
+
},
|
|
72800
|
+
"nodeCertificates.prepareHttpsCertificate": {
|
|
72801
|
+
capName: "node-certificates",
|
|
72802
|
+
capScope: "system",
|
|
72803
|
+
addonId: null,
|
|
72804
|
+
access: "create"
|
|
72805
|
+
},
|
|
72806
|
+
"nodeCertificates.prepareMeshRenewal": {
|
|
72807
|
+
capName: "node-certificates",
|
|
72808
|
+
capScope: "system",
|
|
72809
|
+
addonId: null,
|
|
72810
|
+
access: "create"
|
|
72811
|
+
},
|
|
72812
|
+
"nodeCertificates.rollbackMeshLeaf": {
|
|
72813
|
+
capName: "node-certificates",
|
|
72814
|
+
capScope: "system",
|
|
72815
|
+
addonId: null,
|
|
72816
|
+
access: "create"
|
|
72817
|
+
},
|
|
71378
72818
|
"nodes.clusterAddonStatus": {
|
|
71379
72819
|
capName: "nodes",
|
|
71380
72820
|
capScope: "system",
|
|
@@ -76066,6 +77506,26 @@ Object.freeze({
|
|
|
76066
77506
|
form: "single",
|
|
76067
77507
|
optional: false
|
|
76068
77508
|
}],
|
|
77509
|
+
"deviceHistory.getDeviceEnabled": [{
|
|
77510
|
+
name: "deviceId",
|
|
77511
|
+
form: "single",
|
|
77512
|
+
optional: false
|
|
77513
|
+
}],
|
|
77514
|
+
"deviceHistory.listSeries": [{
|
|
77515
|
+
name: "deviceId",
|
|
77516
|
+
form: "single",
|
|
77517
|
+
optional: false
|
|
77518
|
+
}],
|
|
77519
|
+
"deviceHistory.query": [{
|
|
77520
|
+
name: "deviceId",
|
|
77521
|
+
form: "single",
|
|
77522
|
+
optional: false
|
|
77523
|
+
}],
|
|
77524
|
+
"deviceHistory.setDeviceEnabled": [{
|
|
77525
|
+
name: "deviceId",
|
|
77526
|
+
form: "single",
|
|
77527
|
+
optional: false
|
|
77528
|
+
}],
|
|
76069
77529
|
"deviceManager.adoptionRelease": [{
|
|
76070
77530
|
name: "camDeviceId",
|
|
76071
77531
|
form: "single",
|
|
@@ -76359,6 +77819,11 @@ Object.freeze({
|
|
|
76359
77819
|
form: "single",
|
|
76360
77820
|
optional: false
|
|
76361
77821
|
}],
|
|
77822
|
+
"deviceRemovalHook.onDeviceRemoved": [{
|
|
77823
|
+
name: "deviceId",
|
|
77824
|
+
form: "single",
|
|
77825
|
+
optional: false
|
|
77826
|
+
}],
|
|
76362
77827
|
"deviceState.claimFields": [{
|
|
76363
77828
|
name: "deviceId",
|
|
76364
77829
|
form: "single",
|
|
@@ -76548,6 +78013,11 @@ Object.freeze({
|
|
|
76548
78013
|
form: "single",
|
|
76549
78014
|
optional: false
|
|
76550
78015
|
}],
|
|
78016
|
+
"keychain.deleteDeviceScope": [{
|
|
78017
|
+
name: "deviceId",
|
|
78018
|
+
form: "single",
|
|
78019
|
+
optional: false
|
|
78020
|
+
}],
|
|
76551
78021
|
"lawnMowerControl.dock": [{
|
|
76552
78022
|
name: "deviceId",
|
|
76553
78023
|
form: "single",
|
|
@@ -78244,6 +79714,7 @@ Object.freeze({
|
|
|
78244
79714
|
"network-access": "ingress",
|
|
78245
79715
|
"smtp-provider": "email"
|
|
78246
79716
|
});
|
|
79717
|
+
DeviceType.Camera;
|
|
78247
79718
|
var G711_SCALE_CORRECTION_DB = {
|
|
78248
79719
|
PCMU: 20 * Math.log10(4),
|
|
78249
79720
|
PCMA: 20 * Math.log10(8)
|
|
@@ -81028,6 +82499,8 @@ function eventKindLabel(kind, locale) {
|
|
|
81028
82499
|
const key = kind.trim().toLowerCase();
|
|
81029
82500
|
return isEventKindLabelKey(key) ? EVENT_KIND_LABELS[key][locale] : kind;
|
|
81030
82501
|
}
|
|
82502
|
+
AppPageLangSchema.options;
|
|
82503
|
+
record(string().min(1), string());
|
|
81031
82504
|
/**
|
|
81032
82505
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
81033
82506
|
*
|
|
@@ -81456,6 +82929,32 @@ function slideInsideFrame(rect, frameWidth, frameHeight) {
|
|
|
81456
82929
|
h
|
|
81457
82930
|
};
|
|
81458
82931
|
}
|
|
82932
|
+
/** Slider bounds. `0` is "disabled"; anything in 1..9 is raised to `min`. */
|
|
82933
|
+
var FACE_RESCORE_INTERVAL_FIELD = {
|
|
82934
|
+
min: 0,
|
|
82935
|
+
max: 1440,
|
|
82936
|
+
step: 5,
|
|
82937
|
+
default: 60
|
|
82938
|
+
};
|
|
82939
|
+
/**
|
|
82940
|
+
* Narrow a stored value to minutes. `0` ⇒ disabled; a positive value under
|
|
82941
|
+
* {@link FACE_RESCORE_INTERVAL_MIN_RUNNING} is raised to it; junk or absent ⇒
|
|
82942
|
+
* the default (an unreadable setting must not switch the job off nor storm it).
|
|
82943
|
+
*/
|
|
82944
|
+
function readFaceRescoreIntervalMinutes(value) {
|
|
82945
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
82946
|
+
if (value === 0) return 0;
|
|
82947
|
+
return Math.min(FACE_RESCORE_INTERVAL_FIELD.max, Math.max(10, Math.floor(value)));
|
|
82948
|
+
}
|
|
82949
|
+
/** The interval out of a hydrated payload; a `null` view (mid-boot) is the default. */
|
|
82950
|
+
function pickFaceRescoreIntervalMinutes(view) {
|
|
82951
|
+
if (view === null) return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
82952
|
+
for (const section of view.sections) for (const entry of section.fields) {
|
|
82953
|
+
if (typeof entry !== "object" || entry === null || !("key" in entry)) continue;
|
|
82954
|
+
if (entry.key === "faceRescoreIntervalMinutes") return readFaceRescoreIntervalMinutes("value" in entry ? entry.value : void 0);
|
|
82955
|
+
}
|
|
82956
|
+
return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
82957
|
+
}
|
|
81459
82958
|
/**
|
|
81460
82959
|
* WHICH delivered frames the decode worker retains a native copy of.
|
|
81461
82960
|
*
|
|
@@ -81940,6 +83439,76 @@ function encodeVectorBase64(vector) {
|
|
|
81940
83439
|
function vectorDimFromBase64(encoded) {
|
|
81941
83440
|
return Math.floor(Buffer.from(encoded, "base64").byteLength / 4);
|
|
81942
83441
|
}
|
|
83442
|
+
/** How often an implementer re-asks for tombstones after its start-up pass. */
|
|
83443
|
+
var REMOVAL_RECONCILE_INTERVAL_MS = 360 * 60 * 1e3;
|
|
83444
|
+
/** One reconcile pass over every tombstone inside the retention window. */
|
|
83445
|
+
async function reconcileRemovedDevices(opts) {
|
|
83446
|
+
const now = opts.now ?? (() => Date.now());
|
|
83447
|
+
const api = opts.api;
|
|
83448
|
+
if (api === void 0) {
|
|
83449
|
+
opts.logger.warn("device removal reconcile skipped — no device-manager api");
|
|
83450
|
+
return {
|
|
83451
|
+
read: false,
|
|
83452
|
+
applied: 0,
|
|
83453
|
+
failed: 0
|
|
83454
|
+
};
|
|
83455
|
+
}
|
|
83456
|
+
let tombstones;
|
|
83457
|
+
try {
|
|
83458
|
+
tombstones = await api.deviceManager.listDeletedSince.query({ sinceMs: now() - DEVICE_TOMBSTONE_RETENTION_MS });
|
|
83459
|
+
} catch (err) {
|
|
83460
|
+
opts.logger.warn("device removal reconcile skipped — tombstones unreadable, nothing deleted", { meta: { error: errMsg(err) } });
|
|
83461
|
+
return {
|
|
83462
|
+
read: false,
|
|
83463
|
+
applied: 0,
|
|
83464
|
+
failed: 0
|
|
83465
|
+
};
|
|
83466
|
+
}
|
|
83467
|
+
let applied = 0;
|
|
83468
|
+
let failed = 0;
|
|
83469
|
+
for (const tombstone of tombstones) try {
|
|
83470
|
+
const result = await opts.remove(tombstone);
|
|
83471
|
+
applied += 1;
|
|
83472
|
+
if (Object.values(result.counts).reduce((sum, n) => sum + n, 0) > 0) opts.logger.info("device removal reconcile cleaned a missed deletion", {
|
|
83473
|
+
tags: { deviceId: tombstone.deviceId },
|
|
83474
|
+
meta: {
|
|
83475
|
+
counts: result.counts,
|
|
83476
|
+
deletedAt: tombstone.deletedAt
|
|
83477
|
+
}
|
|
83478
|
+
});
|
|
83479
|
+
} catch (err) {
|
|
83480
|
+
failed += 1;
|
|
83481
|
+
opts.logger.warn("device removal reconcile failed for a device — retried next pass", {
|
|
83482
|
+
tags: { deviceId: tombstone.deviceId },
|
|
83483
|
+
meta: { error: errMsg(err) }
|
|
83484
|
+
});
|
|
83485
|
+
}
|
|
83486
|
+
return {
|
|
83487
|
+
read: true,
|
|
83488
|
+
applied,
|
|
83489
|
+
failed
|
|
83490
|
+
};
|
|
83491
|
+
}
|
|
83492
|
+
/**
|
|
83493
|
+
* Run the reconcile now and then periodically. Returns the disposer. The timer
|
|
83494
|
+
* is unref'd and a pass never overlaps the previous one.
|
|
83495
|
+
*/
|
|
83496
|
+
function armRemovalReconcile(opts) {
|
|
83497
|
+
let running = false;
|
|
83498
|
+
const pass = () => {
|
|
83499
|
+
if (running) return;
|
|
83500
|
+
running = true;
|
|
83501
|
+
reconcileRemovedDevices(opts).catch((err) => {
|
|
83502
|
+
opts.logger.warn("device removal reconcile pass crashed", { meta: { error: errMsg(err) } });
|
|
83503
|
+
}).finally(() => {
|
|
83504
|
+
running = false;
|
|
83505
|
+
});
|
|
83506
|
+
};
|
|
83507
|
+
pass();
|
|
83508
|
+
const timer = setInterval(pass, REMOVAL_RECONCILE_INTERVAL_MS);
|
|
83509
|
+
timer.unref?.();
|
|
83510
|
+
return () => clearInterval(timer);
|
|
83511
|
+
}
|
|
81943
83512
|
//#endregion
|
|
81944
83513
|
//#region src/pipeline-analytics/cluster-model-pin.ts
|
|
81945
83514
|
/**
|
|
@@ -82326,6 +83895,12 @@ Object.defineProperty(exports, "CLIP_TEXT_MODELS", {
|
|
|
82326
83895
|
return CLIP_TEXT_MODELS;
|
|
82327
83896
|
}
|
|
82328
83897
|
});
|
|
83898
|
+
Object.defineProperty(exports, "CLUSTER_MODEL_OWNER_ADDON_ID", {
|
|
83899
|
+
enumerable: true,
|
|
83900
|
+
get: function() {
|
|
83901
|
+
return CLUSTER_MODEL_OWNER_ADDON_ID;
|
|
83902
|
+
}
|
|
83903
|
+
});
|
|
82329
83904
|
Object.defineProperty(exports, "COCO_TO_MACRO", {
|
|
82330
83905
|
enumerable: true,
|
|
82331
83906
|
get: function() {
|
|
@@ -83136,6 +84711,12 @@ Object.defineProperty(exports, "applySecureOnArmEdit", {
|
|
|
83136
84711
|
return applySecureOnArmEdit;
|
|
83137
84712
|
}
|
|
83138
84713
|
});
|
|
84714
|
+
Object.defineProperty(exports, "armRemovalReconcile", {
|
|
84715
|
+
enumerable: true,
|
|
84716
|
+
get: function() {
|
|
84717
|
+
return armRemovalReconcile;
|
|
84718
|
+
}
|
|
84719
|
+
});
|
|
83139
84720
|
Object.defineProperty(exports, "array", {
|
|
83140
84721
|
enumerable: true,
|
|
83141
84722
|
get: function() {
|
|
@@ -83280,6 +84861,12 @@ Object.defineProperty(exports, "describeSystemEventFamilyProblem", {
|
|
|
83280
84861
|
return describeSystemEventFamilyProblem;
|
|
83281
84862
|
}
|
|
83282
84863
|
});
|
|
84864
|
+
Object.defineProperty(exports, "deviceRemovalHookCapability", {
|
|
84865
|
+
enumerable: true,
|
|
84866
|
+
get: function() {
|
|
84867
|
+
return deviceRemovalHookCapability;
|
|
84868
|
+
}
|
|
84869
|
+
});
|
|
83283
84870
|
Object.defineProperty(exports, "discriminatedUnion", {
|
|
83284
84871
|
enumerable: true,
|
|
83285
84872
|
get: function() {
|
|
@@ -83574,6 +85161,12 @@ Object.defineProperty(exports, "partialRecord", {
|
|
|
83574
85161
|
return partialRecord;
|
|
83575
85162
|
}
|
|
83576
85163
|
});
|
|
85164
|
+
Object.defineProperty(exports, "pickFaceRescoreIntervalMinutes", {
|
|
85165
|
+
enumerable: true,
|
|
85166
|
+
get: function() {
|
|
85167
|
+
return pickFaceRescoreIntervalMinutes;
|
|
85168
|
+
}
|
|
85169
|
+
});
|
|
83577
85170
|
Object.defineProperty(exports, "pipelineAnalyticsCapability", {
|
|
83578
85171
|
enumerable: true,
|
|
83579
85172
|
get: function() {
|