@bivy/bivy 0.20.9-staging.12 → 0.20.9-staging.13
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/automation-reseal.js +30 -0
- package/dist/device-registry.js +27 -0
- package/dist/server.js +41 -1
- package/package.json +1 -1
- package/web/assets/AutomationsView-DN6Pjj3D.js +51 -0
- package/web/assets/{ChangesCard-g8Lhp8-o.js → ChangesCard-aSANT98o.js} +1 -1
- package/web/assets/{LibraryView-2DXscx59.js → LibraryView-CcssDQpe.js} +1 -1
- package/web/assets/{ProviderConnect-Cl2HBpl_.js → ProviderConnect-GHqdbDfx.js} +1 -1
- package/web/assets/{Settings-DUh6WdcC.js → Settings-zrbfuGw7.js} +3 -3
- package/web/assets/{Sheet-BERX6Dsv.js → Sheet-akpaXVWk.js} +1 -1
- package/web/assets/{Terminal-CJcgCagB.js → Terminal-Cl9BAqmG.js} +1 -1
- package/web/assets/{VoiceSettings-DkSdCkze.js → VoiceSettings-CiVFD62Z.js} +1 -1
- package/web/assets/{abnfDiagram-VCTEODGH-BHD5JTM6.js → abnfDiagram-VCTEODGH-DvcKa8Q6.js} +1 -1
- package/web/assets/architecture-7GRP2DOG-Db3dVfEg.js +1 -0
- package/web/assets/{architectureDiagram-5GKGNRK7-C_GKL4K7.js → architectureDiagram-5GKGNRK7-C5UHXNNA.js} +1 -1
- package/web/assets/{blockDiagram-I7D4REHJ-CRq2fdX9.js → blockDiagram-I7D4REHJ-B3bEudR9.js} +1 -1
- package/web/assets/{c4Diagram-7LVT6UL2-CvXSE3hG.js → c4Diagram-7LVT6UL2-B-Uwyk2S.js} +1 -1
- package/web/assets/channel-BmwZ91Zu.js +1 -0
- package/web/assets/{chunk-4HAMMTFA-Ds9o7yrU.js → chunk-4HAMMTFA-ZZNhY7ou.js} +1 -1
- package/web/assets/{chunk-75Z2AOVW-BwiC6QFm.js → chunk-75Z2AOVW-DkSlF2wc.js} +1 -1
- package/web/assets/{chunk-DU6HZSFF-236r-frX.js → chunk-DU6HZSFF-DJSerjpq.js} +1 -1
- package/web/assets/{chunk-F27PBJKO-CguQ8WaZ.js → chunk-F27PBJKO-BnSlJxd6.js} +1 -1
- package/web/assets/{chunk-GMAD6QVW-DmBwXsGy.js → chunk-GMAD6QVW-k1Kqheha.js} +1 -1
- package/web/assets/{chunk-GVQU2GXP-DnkJJSYL.js → chunk-GVQU2GXP-D-Dky606.js} +1 -1
- package/web/assets/{chunk-IMKFNOWR-YG1z0eu5.js → chunk-IMKFNOWR-CMgW8VOp.js} +1 -1
- package/web/assets/{chunk-L3NEJ4N5-D39eIpWM.js → chunk-L3NEJ4N5-BPppfNZq.js} +1 -1
- package/web/assets/{chunk-OSK3NFVY-CGrQqCBq.js → chunk-OSK3NFVY-X1S-7cI8.js} +1 -1
- package/web/assets/{chunk-P2QGCYS3-CnzAU-Mz.js → chunk-P2QGCYS3-C3D0xAbV.js} +1 -1
- package/web/assets/{chunk-POPQ4Y6H-CWalH36f.js → chunk-POPQ4Y6H-rzpiAvDt.js} +1 -1
- package/web/assets/{chunk-PWAF6VOD-BQT5ioTL.js → chunk-PWAF6VOD-BnelcVCG.js} +1 -1
- package/web/assets/{chunk-SHT3W25Y-wfqek-d7.js → chunk-SHT3W25Y-BpUiekby.js} +1 -1
- package/web/assets/{chunk-SVP7TREG-CBp3IjhM.js → chunk-SVP7TREG-CHzYiMcX.js} +1 -1
- package/web/assets/{chunk-TICWLB2K-ags6QsSk.js → chunk-TICWLB2K-Cil76YwI.js} +1 -1
- package/web/assets/classDiagram-ZZMXUADV-BWeCowiO.js +1 -0
- package/web/assets/classDiagram-v2-VYDZK3BY-BWeCowiO.js +1 -0
- package/web/assets/{cynefin-OW5HDTMX-DO3oi7vt.js → cynefin-OW5HDTMX-DqYTG6s3.js} +1 -1
- package/web/assets/{cynefinDiagram-5FMLGOSQ-CIXw7Cc6.js → cynefinDiagram-5FMLGOSQ-DHoCWcHR.js} +1 -1
- package/web/assets/{dagre-GXQ25YYZ-BLXWq9eV.js → dagre-GXQ25YYZ-CkVRQJ7Q.js} +1 -1
- package/web/assets/{diagram-S7CK7UJ4-bA0zwJY_.js → diagram-S7CK7UJ4-DTqxklJ8.js} +1 -1
- package/web/assets/{diagram-UQ7AKVKN-DKogFgPR.js → diagram-UQ7AKVKN-BfPq1M8P.js} +1 -1
- package/web/assets/{diagram-VSXAHHWV-qkLzNlr2.js → diagram-VSXAHHWV-BQnLbJ0g.js} +1 -1
- package/web/assets/{diagram-VX7I27RA-_osxbKbn.js → diagram-VX7I27RA-B8A1-dub.js} +1 -1
- package/web/assets/{diagram-Z3DM3KII-CQljxyfX.js → diagram-Z3DM3KII-CRBTYKWA.js} +1 -1
- package/web/assets/{ebnfDiagram-PWID7BFC-C8Y5lz7G.js → ebnfDiagram-PWID7BFC-FvVv2X7o.js} +1 -1
- package/web/assets/{erDiagram-RLTQ6QDP-DjUCgPos.js → erDiagram-RLTQ6QDP-D1s8uXzs.js} +1 -1
- package/web/assets/eventmodeling-NTZA5JFV-DRobz4Mt.js +1 -0
- package/web/assets/flowDiagram-HODETNUW-DmXstahq.js +1 -0
- package/web/assets/{ganttDiagram-EL5Y4UJY-CMCiD5IY.js → ganttDiagram-EL5Y4UJY-BEdenIa6.js} +1 -1
- package/web/assets/{gitGraph-4MIJSDKK-BRcacSQ-.js → gitGraph-4MIJSDKK-BCH2_BAZ.js} +1 -1
- package/web/assets/{gitGraphDiagram-WWUBYQGX-0js7hKj5.js → gitGraphDiagram-WWUBYQGX-BYL-zyse.js} +1 -1
- package/web/assets/{index-BdEB2YRe.js → index-ROUVrPbc.js} +2 -2
- package/web/assets/{info-A6RAGUB7-CsrRX5La.js → info-A6RAGUB7-CKrUmOha.js} +1 -1
- package/web/assets/{infoDiagram-27XIBGKW-DDP3W2Tm.js → infoDiagram-27XIBGKW-Dgv66P4Q.js} +1 -1
- package/web/assets/{ishikawaDiagram-5VMMS53U-BMu0M7NV.js → ishikawaDiagram-5VMMS53U-C0kmn2Cr.js} +1 -1
- package/web/assets/{journeyDiagram-3NMN7TZE-BPr-VSMD.js → journeyDiagram-3NMN7TZE-5jZi913z.js} +1 -1
- package/web/assets/{kanban-definition-UXKFOSKX-BM-VHNhy.js → kanban-definition-UXKFOSKX-DO4Z-hZf.js} +1 -1
- package/web/assets/{line-Bd9NaoV1.js → line-zuKPCmLl.js} +1 -1
- package/web/assets/{mermaid-parser.core-hutbDo6D.js → mermaid-parser.core-4-0aU2cI.js} +3 -3
- package/web/assets/{mermaid.core-gqG1ONr1.js → mermaid.core-BZrDCPKc.js} +4 -4
- package/web/assets/{mindmap-definition-YA3MSWOX-DxVb-AvM.js → mindmap-definition-YA3MSWOX-DOFnNlT5.js} +1 -1
- package/web/assets/{mount-DShkRPG0.js → mount-BpoYlWmV.js} +5 -5
- package/web/assets/{packet-AYTQ26CC-dFLVGDcI.js → packet-AYTQ26CC-BDFArHuv.js} +1 -1
- package/web/assets/{pegDiagram-XKGWAZYB-Bazytp0F.js → pegDiagram-XKGWAZYB-7CxEp7-m.js} +1 -1
- package/web/assets/{pie-WAS4IAKB-CTkqaK_f.js → pie-WAS4IAKB-BUC9CmzW.js} +1 -1
- package/web/assets/{pieDiagram-E7YTZNPT-CDvZ4aIB.js → pieDiagram-E7YTZNPT-BlXxIkan.js} +1 -1
- package/web/assets/{quadrantDiagram-AXDQQJYC-DTSeVxbf.js → quadrantDiagram-AXDQQJYC-C5GRb0RN.js} +1 -1
- package/web/assets/{radar-RG4KPBEZ-CKfc3MS_.js → radar-RG4KPBEZ-M1s8yzHp.js} +1 -1
- package/web/assets/{railroad-74A4TZTK-Cxcv3-64.js → railroad-74A4TZTK-BQj2Bxlk.js} +1 -1
- package/web/assets/railroad-abnf-HS5TGJTU-cooT4VHw.js +1 -0
- package/web/assets/railroad-ebnf-LZEXJU2U-Dbxg-HJI.js +1 -0
- package/web/assets/railroad-peg-WCYAUIDC-DF7RNXo3.js +1 -0
- package/web/assets/{railroadDiagram-O6MQD6OU-DevTuLL1.js → railroadDiagram-O6MQD6OU-n0Sd3MRX.js} +1 -1
- package/web/assets/{requirementDiagram-BXWQKSXE-BYjGKExS.js → requirementDiagram-BXWQKSXE-A0anIwln.js} +1 -1
- package/web/assets/{sankeyDiagram-P5KCCOFB-CfVa0PNX.js → sankeyDiagram-P5KCCOFB-f_ILKHwt.js} +1 -1
- package/web/assets/{sequenceDiagram-WJ2MYXX4-Dl5bPCHn.js → sequenceDiagram-WJ2MYXX4-Z4Yxn3Me.js} +1 -1
- package/web/assets/{settingsRoute-d6enyGGs.js → settingsRoute-Co4_ejOs.js} +1 -1
- package/web/assets/{stateDiagram-D77RDMKH-BtU_gQEb.js → stateDiagram-D77RDMKH-DH4tyyvM.js} +1 -1
- package/web/assets/stateDiagram-v2-MP3YSRHH-BGcz3nv5.js +1 -0
- package/web/assets/{swimlanes-42K2YHIH-DIe9GxhW.js → swimlanes-42K2YHIH-D0mYIRp_.js} +1 -1
- package/web/assets/swimlanesDiagram-VR7AAH4N-DytMuA5I.js +8 -0
- package/web/assets/{timeline-definition-24CTP7MA-B9g7nrL1.js → timeline-definition-24CTP7MA-D9SvE_xH.js} +1 -1
- package/web/assets/{treeView-Q6P3EWNA-DdT2XETS.js → treeView-Q6P3EWNA-BJZ3tNbp.js} +1 -1
- package/web/assets/{treemap-WGGIJYW6-h4WmocS0.js → treemap-WGGIJYW6-B4y9-El8.js} +1 -1
- package/web/assets/{useStore-DzDtTF5N.js → useStore-BjgRUXv4.js} +1 -1
- package/web/assets/{vennDiagram-4TSXK5OY-gk44eWcf.js → vennDiagram-4TSXK5OY-COLSJIgu.js} +1 -1
- package/web/assets/{wardley-WFR3VGLG-uJbKN4qW.js → wardley-WFR3VGLG-D8rExT50.js} +1 -1
- package/web/assets/{wardleyDiagram-VM6X3IG4-Diy79JCP.js → wardleyDiagram-VM6X3IG4-BSLx_T3_.js} +1 -1
- package/web/assets/{xychartDiagram-S5SC5T6Z-CbeKz8Bk.js → xychartDiagram-S5SC5T6Z-DekMZK0J.js} +1 -1
- package/web/index.html +1 -1
- package/web/sw.js +1 -1
- package/web/assets/AutomationsView-BWARomwT.js +0 -51
- package/web/assets/architecture-7GRP2DOG-BK3P2Dfz.js +0 -1
- package/web/assets/channel-Bsrodtv-.js +0 -1
- package/web/assets/classDiagram-ZZMXUADV-BBOjgswF.js +0 -1
- package/web/assets/classDiagram-v2-VYDZK3BY-BBOjgswF.js +0 -1
- package/web/assets/eventmodeling-NTZA5JFV-CKIRww6K.js +0 -1
- package/web/assets/flowDiagram-HODETNUW-C9kJw-vn.js +0 -1
- package/web/assets/railroad-abnf-HS5TGJTU-CDmyp3sp.js +0 -1
- package/web/assets/railroad-ebnf-LZEXJU2U-CbiTHSV5.js +0 -1
- package/web/assets/railroad-peg-WCYAUIDC-CVsfoDy0.js +0 -1
- package/web/assets/stateDiagram-v2-MP3YSRHH-CGVAIFE8.js +0 -1
- package/web/assets/swimlanesDiagram-VR7AAH4N-CY0bvLUP.js +0 -8
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (c) 2026 Petter André Sjulstad
|
|
3
|
+
import { open, seal } from "./e2e.js";
|
|
4
|
+
export async function resealAutomationTemplates(opts) {
|
|
5
|
+
const prefix = `bivy-room-v1:${opts.nodeId}:`;
|
|
6
|
+
const result = { resealed: 0, unreadable: [] };
|
|
7
|
+
for (const template of opts.templates) {
|
|
8
|
+
if (!template.templateCiphertext.startsWith(prefix))
|
|
9
|
+
continue;
|
|
10
|
+
const payload = template.templateCiphertext.slice(prefix.length);
|
|
11
|
+
if (tryOpen(opts.current, payload) !== undefined)
|
|
12
|
+
continue;
|
|
13
|
+
const plaintext = opts.retired.map((key) => tryOpen(key, payload)).find((text) => text !== undefined);
|
|
14
|
+
if (plaintext === undefined) {
|
|
15
|
+
result.unreadable.push(template.id);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
await opts.save(template.id, `${prefix}${seal(opts.current, plaintext)}`);
|
|
19
|
+
result.resealed += 1;
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function tryOpen(key, payload) {
|
|
24
|
+
try {
|
|
25
|
+
return open(key, payload);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
package/dist/device-registry.js
CHANGED
|
@@ -7,6 +7,7 @@ import { generatePairingKeypair, generateRoomKey, generatePairSecret, deriveWrap
|
|
|
7
7
|
import { seal, open } from "./e2e.js";
|
|
8
8
|
const DEFAULT_PAIR_TTL_MS = 5 * 60_000;
|
|
9
9
|
const ROOM_KEY_BYTES = 32;
|
|
10
|
+
const MAX_RETIRED_ROOM_KEYS = 8;
|
|
10
11
|
/**
|
|
11
12
|
* Validate + canonicalize a pre-shared room-key seed. Returns the canonical
|
|
12
13
|
* base64 of a well-formed 32-byte key, or undefined for anything malformed
|
|
@@ -81,6 +82,7 @@ export class PairingStore {
|
|
|
81
82
|
return new PairingStore(filePath, {
|
|
82
83
|
nodeKeypair: parsed.nodeKeypair,
|
|
83
84
|
roomKeyB64: parsed.roomKeyB64,
|
|
85
|
+
...(Array.isArray(parsed.retiredRoomKeysB64) && parsed.retiredRoomKeysB64.length ? { retiredRoomKeysB64: parsed.retiredRoomKeysB64 } : {}),
|
|
84
86
|
devices: Array.isArray(parsed.devices) ? parsed.devices : [],
|
|
85
87
|
});
|
|
86
88
|
}
|
|
@@ -130,6 +132,30 @@ export class PairingStore {
|
|
|
130
132
|
roomKey() {
|
|
131
133
|
return Buffer.from(this.data.roomKeyB64, "base64");
|
|
132
134
|
}
|
|
135
|
+
/** Room keys replaced by earlier rotations that still guard stored data. */
|
|
136
|
+
retiredRoomKeys() {
|
|
137
|
+
return (this.data.retiredRoomKeysB64 ?? []).map((key) => Buffer.from(key, "base64"));
|
|
138
|
+
}
|
|
139
|
+
/** Drop retired room keys once nothing stored is sealed under them. */
|
|
140
|
+
forgetRetiredRoomKeys() {
|
|
141
|
+
if (!this.data.retiredRoomKeysB64)
|
|
142
|
+
return;
|
|
143
|
+
delete this.data.retiredRoomKeysB64;
|
|
144
|
+
this.persist();
|
|
145
|
+
}
|
|
146
|
+
/** Open a payload sealed under the current room key or a retired one. */
|
|
147
|
+
openSealed(payload) {
|
|
148
|
+
let lastError;
|
|
149
|
+
for (const key of [this.roomKey(), ...this.retiredRoomKeys()]) {
|
|
150
|
+
try {
|
|
151
|
+
return open(key, payload);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
lastError = error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
throw lastError;
|
|
158
|
+
}
|
|
133
159
|
/** Issue a single-use, expiring pairing secret to embed in a linking QR. */
|
|
134
160
|
issuePairSecret(ttlMs = DEFAULT_PAIR_TTL_MS) {
|
|
135
161
|
this.sweepSecrets();
|
|
@@ -215,6 +241,7 @@ export class PairingStore {
|
|
|
215
241
|
}
|
|
216
242
|
/** Rotate the room key and re-wrap it for all current devices. */
|
|
217
243
|
rotateRoomKey() {
|
|
244
|
+
this.data.retiredRoomKeysB64 = [this.data.roomKeyB64, ...(this.data.retiredRoomKeysB64 ?? [])].slice(0, MAX_RETIRED_ROOM_KEYS);
|
|
218
245
|
this.data.roomKeyB64 = generateRoomKey().toString("base64");
|
|
219
246
|
this.persist();
|
|
220
247
|
const roomKey = this.roomKey();
|
package/dist/server.js
CHANGED
|
@@ -54,6 +54,7 @@ import { ControlPlaneSessionLocationRegistry, LayeredSessionLocationRegistry } f
|
|
|
54
54
|
import { attachAdoptedSessions, classifyAttachFailure } from "./runtime/adoption.js";
|
|
55
55
|
import { createCredentialStore, testProviderCredential } from "./runtime/credentials.js";
|
|
56
56
|
import { decodeAutomationTemplate } from "./automation-template.js";
|
|
57
|
+
import { resealAutomationTemplates } from "./automation-reseal.js";
|
|
57
58
|
import { passWebhookFilter } from "./automation-filter-gate.js";
|
|
58
59
|
import { isModelAuthError, authProviderForSession, classifyModelAuthError } from "./runtime/auth-errors.js";
|
|
59
60
|
import { createCredentialVault, migrateVaultDir } from "./runtime/credential-store.js";
|
|
@@ -1080,6 +1081,7 @@ const linkedDevices = createLinkedDeviceController({
|
|
|
1080
1081
|
syncPairingMetadata();
|
|
1081
1082
|
relay?.pushRotate(deliveries);
|
|
1082
1083
|
broadcast({ type: "devices.updated", devices });
|
|
1084
|
+
void resealRetiredAutomationTemplates();
|
|
1083
1085
|
},
|
|
1084
1086
|
});
|
|
1085
1087
|
const accessDevices = createAccessDeviceController({
|
|
@@ -3537,6 +3539,7 @@ function startRelayIfConfigured() {
|
|
|
3537
3539
|
if (config.controlPlaneUrl && config.enrollmentToken) {
|
|
3538
3540
|
sessionAdvertiseTarget = { controlPlaneUrl: config.controlPlaneUrl, enrollmentToken: config.enrollmentToken };
|
|
3539
3541
|
void syncModelAuthFromControlPlane();
|
|
3542
|
+
void resealRetiredAutomationTemplates();
|
|
3540
3543
|
if (remoteRuntimeEnabled()) {
|
|
3541
3544
|
// Stage 3: layer a control-plane-backed location registry UNDER the in-memory
|
|
3542
3545
|
// one (so a lookup surviving a restart resolves from durable state), then
|
|
@@ -3698,6 +3701,43 @@ async function modelAuthFetch(pathname, init = {}) {
|
|
|
3698
3701
|
headers.set("content-type", "application/json");
|
|
3699
3702
|
return fetch(`${sessionAdvertiseTarget.controlPlaneUrl.replace(/\/$/, "")}${pathname}`, { ...init, headers });
|
|
3700
3703
|
}
|
|
3704
|
+
// A device revoke rotates the room key. Re-seal this node's stored automation
|
|
3705
|
+
// instructions under the new key so the node and its devices can still read
|
|
3706
|
+
// them, then drop the retired keys. Retried at startup until it completes.
|
|
3707
|
+
async function resealRetiredAutomationTemplates() {
|
|
3708
|
+
const retired = pairingStore.retiredRoomKeys();
|
|
3709
|
+
if (!retired.length || !sessionAdvertiseTarget)
|
|
3710
|
+
return;
|
|
3711
|
+
const current = pairingStore.roomKey();
|
|
3712
|
+
try {
|
|
3713
|
+
const res = await modelAuthFetch("/node/automation-templates");
|
|
3714
|
+
if (!res?.ok)
|
|
3715
|
+
throw new Error(`control plane returned ${res?.status}`);
|
|
3716
|
+
const { templates } = await res.json();
|
|
3717
|
+
const result = await resealAutomationTemplates({
|
|
3718
|
+
nodeId: identity.nodeId,
|
|
3719
|
+
current,
|
|
3720
|
+
retired,
|
|
3721
|
+
templates,
|
|
3722
|
+
save: async (id, templateCiphertext) => {
|
|
3723
|
+
const saved = await modelAuthFetch(`/node/automation-templates/${encodeURIComponent(id)}`, { method: "PUT", body: JSON.stringify({ templateCiphertext }) });
|
|
3724
|
+
if (!saved?.ok)
|
|
3725
|
+
throw new Error(`control plane returned ${saved?.status}`);
|
|
3726
|
+
},
|
|
3727
|
+
});
|
|
3728
|
+
if (result.resealed)
|
|
3729
|
+
console.log(`[automation-reseal] re-sealed ${result.resealed} automation template(s) under the rotated room key`);
|
|
3730
|
+
if (result.unreadable.length)
|
|
3731
|
+
console.warn(`[automation-reseal] ${result.unreadable.length} automation template(s) were sealed under a key this node no longer has: ${result.unreadable.join(", ")}`);
|
|
3732
|
+
// Another rotation during this pass retired `current`; run again for it.
|
|
3733
|
+
if (!pairingStore.roomKey().equals(current))
|
|
3734
|
+
return void resealRetiredAutomationTemplates();
|
|
3735
|
+
pairingStore.forgetRetiredRoomKeys();
|
|
3736
|
+
}
|
|
3737
|
+
catch (error) {
|
|
3738
|
+
console.warn("[automation-reseal] will retry at next start:", error.message);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3701
3741
|
const remoteSessionAdmission = createRemoteSessionAdmission(async (idempotencyKey) => {
|
|
3702
3742
|
// Only remote scopes reach this callback. Self-hosted control planes answer
|
|
3703
3743
|
// allowed without an extension; losing enrollment mid-launch must fail closed.
|
|
@@ -5554,7 +5594,7 @@ async function executeWorkItem(item, report, signal) {
|
|
|
5554
5594
|
throw new Error("automation instructions were encrypted for a different node");
|
|
5555
5595
|
}
|
|
5556
5596
|
try {
|
|
5557
|
-
const template = decodeAutomationTemplate(
|
|
5597
|
+
const template = decodeAutomationTemplate(pairingStore.openSealed(payload.join(":")));
|
|
5558
5598
|
credentialLabels = template.credentialLabels;
|
|
5559
5599
|
filter = template.filter;
|
|
5560
5600
|
item = { ...item, body: template.instructions };
|
package/package.json
CHANGED