@haex-space/vault-sdk 3.1.0 → 3.2.2

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.
Files changed (45) hide show
  1. package/dist/{client-C0DPNG62.d.mts → client-GeColu97.d.mts} +263 -2
  2. package/dist/{client-B_B6rLIw.d.ts → client-z1jTcuQE.d.ts} +263 -2
  3. package/dist/index.d.mts +76 -6
  4. package/dist/index.d.ts +76 -6
  5. package/dist/index.js +244 -47
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +241 -48
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/node.d.mts +1 -1
  10. package/dist/node.d.ts +1 -1
  11. package/dist/nuxt.js +16 -6
  12. package/dist/nuxt.js.map +1 -1
  13. package/dist/nuxt.mjs +16 -6
  14. package/dist/nuxt.mjs.map +1 -1
  15. package/dist/react.d.mts +2 -2
  16. package/dist/react.d.ts +2 -2
  17. package/dist/react.js +237 -46
  18. package/dist/react.js.map +1 -1
  19. package/dist/react.mjs +237 -46
  20. package/dist/react.mjs.map +1 -1
  21. package/dist/runtime/nuxt.plugin.client.d.mts +2 -2
  22. package/dist/runtime/nuxt.plugin.client.d.ts +2 -2
  23. package/dist/runtime/nuxt.plugin.client.js +237 -50
  24. package/dist/runtime/nuxt.plugin.client.js.map +1 -1
  25. package/dist/runtime/nuxt.plugin.client.mjs +237 -50
  26. package/dist/runtime/nuxt.plugin.client.mjs.map +1 -1
  27. package/dist/svelte.d.mts +2 -2
  28. package/dist/svelte.d.ts +2 -2
  29. package/dist/svelte.js +237 -46
  30. package/dist/svelte.js.map +1 -1
  31. package/dist/svelte.mjs +237 -46
  32. package/dist/svelte.mjs.map +1 -1
  33. package/dist/{types-DmCSegdY.d.mts → types-CDMBvvjl.d.mts} +2 -0
  34. package/dist/{types-DmCSegdY.d.ts → types-CDMBvvjl.d.ts} +2 -0
  35. package/dist/vite.js +15 -5
  36. package/dist/vite.js.map +1 -1
  37. package/dist/vite.mjs +15 -5
  38. package/dist/vite.mjs.map +1 -1
  39. package/dist/vue.d.mts +2 -2
  40. package/dist/vue.d.ts +2 -2
  41. package/dist/vue.js +237 -46
  42. package/dist/vue.js.map +1 -1
  43. package/dist/vue.mjs +237 -46
  44. package/dist/vue.mjs.map +1 -1
  45. package/package.json +1 -1
@@ -265,6 +265,40 @@ var SHELL_COMMANDS = {
265
265
  close: "extension_shell_close"
266
266
  };
267
267
 
268
+ // src/commands/passwords.ts
269
+ var PASSWORD_COMMANDS = {
270
+ /** List items (no secrets) within the extension's tag scope */
271
+ list: "extension_password_list",
272
+ /** Read full item including secrets, by id */
273
+ read: "extension_password_read",
274
+ /** Create item — must include >=1 tag in scope */
275
+ create: "extension_password_create",
276
+ /** Update item — keeps >=1 tag in scope */
277
+ update: "extension_password_update",
278
+ /** Delete item — must be in scope */
279
+ delete: "extension_password_delete"
280
+ };
281
+
282
+ // src/commands/mail.ts
283
+ var MAIL_COMMANDS = {
284
+ /** LIST mailboxes + optional STATUS counts */
285
+ listMailboxes: "extension_mail_list_mailboxes",
286
+ /** Lightweight envelope fetch for list views */
287
+ fetchEnvelopes: "extension_mail_fetch_envelopes",
288
+ /** Full message fetch (envelope + body + attachment metadata) */
289
+ fetchMessage: "extension_mail_fetch_message",
290
+ /** Set or unset IMAP flags on a UID set */
291
+ setFlags: "extension_mail_set_flags",
292
+ /** MOVE messages between mailboxes (COPY+EXPUNGE fallback) */
293
+ moveMessages: "extension_mail_move_messages",
294
+ /** APPEND a base64-encoded RFC822 message into a mailbox */
295
+ appendMessage: "extension_mail_append_message",
296
+ /** SMTP send. Returns the assigned Message-ID. */
297
+ sendMessage: "extension_mail_send_message",
298
+ /** Build RFC822 bytes without sending (for Drafts via APPEND) */
299
+ buildRfc822: "extension_mail_build_rfc822"
300
+ };
301
+
268
302
  // src/api/storage.ts
269
303
  var StorageAPI = class {
270
304
  constructor(client) {
@@ -288,6 +322,12 @@ var StorageAPI = class {
288
322
  };
289
323
 
290
324
  // src/api/database.ts
325
+ function quoteIdent(identifier) {
326
+ if (identifier.startsWith('"') && identifier.endsWith('"')) {
327
+ return identifier;
328
+ }
329
+ return `"${identifier.replace(/"/g, '""')}"`;
330
+ }
291
331
  var DatabaseAPI = class {
292
332
  constructor(client) {
293
333
  this.client = client;
@@ -318,11 +358,11 @@ var DatabaseAPI = class {
318
358
  });
319
359
  }
320
360
  async createTable(tableName, columns) {
321
- const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
361
+ const query = `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${columns})`;
322
362
  await this.execute(query);
323
363
  }
324
364
  async dropTable(tableName) {
325
- const query = `DROP TABLE IF EXISTS ${tableName}`;
365
+ const query = `DROP TABLE IF EXISTS ${quoteIdent(tableName)}`;
326
366
  await this.execute(query);
327
367
  }
328
368
  /**
@@ -351,18 +391,17 @@ var DatabaseAPI = class {
351
391
  async insert(tableName, data) {
352
392
  const keys = Object.keys(data);
353
393
  const values = Object.values(data);
394
+ const quotedCols = keys.map(quoteIdent).join(", ");
354
395
  const placeholders = keys.map(() => "?").join(", ");
355
- const query = `INSERT INTO ${tableName} (${keys.join(
356
- ", "
357
- )}) VALUES (${placeholders})`;
396
+ const query = `INSERT INTO ${quoteIdent(tableName)} (${quotedCols}) VALUES (${placeholders})`;
358
397
  const result = await this.execute(query, values);
359
398
  return result.lastInsertId ?? -1;
360
399
  }
361
400
  async update(tableName, data, where, whereParams) {
362
401
  const keys = Object.keys(data);
363
402
  const values = Object.values(data);
364
- const setClause = keys.map((key) => `${key} = ?`).join(", ");
365
- const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
403
+ const setClause = keys.map((key) => `${quoteIdent(key)} = ?`).join(", ");
404
+ const query = `UPDATE ${quoteIdent(tableName)} SET ${setClause} WHERE ${where}`;
366
405
  const result = await this.execute(query, [
367
406
  ...values,
368
407
  ...whereParams || []
@@ -370,12 +409,12 @@ var DatabaseAPI = class {
370
409
  return result.rowsAffected;
371
410
  }
372
411
  async delete(tableName, where, whereParams) {
373
- const query = `DELETE FROM ${tableName} WHERE ${where}`;
412
+ const query = `DELETE FROM ${quoteIdent(tableName)} WHERE ${where}`;
374
413
  const result = await this.execute(query, whereParams);
375
414
  return result.rowsAffected;
376
415
  }
377
416
  async count(tableName, where, whereParams) {
378
- const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
417
+ const query = where ? `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)}`;
379
418
  const result = await this.queryOne(query, whereParams);
380
419
  return result?.count ?? 0;
381
420
  }
@@ -1222,6 +1261,140 @@ var ShellAPI = class {
1222
1261
  }
1223
1262
  };
1224
1263
 
1264
+ // src/api/passwords.ts
1265
+ var PasswordsAPI = class {
1266
+ constructor(client) {
1267
+ this.client = client;
1268
+ }
1269
+ /** List items in scope — summaries only, no secrets. */
1270
+ async listAsync() {
1271
+ return this.client.request(
1272
+ PASSWORD_COMMANDS.list,
1273
+ {}
1274
+ );
1275
+ }
1276
+ /** Read a single item by id with full secrets. */
1277
+ async readAsync(itemId) {
1278
+ return this.client.request(PASSWORD_COMMANDS.read, {
1279
+ itemId
1280
+ });
1281
+ }
1282
+ /**
1283
+ * Create a new password item. `input.tags` must contain at least one
1284
+ * tag within the extension's permission scope, otherwise the write
1285
+ * is rejected as a security violation.
1286
+ *
1287
+ * Returns the new item id.
1288
+ */
1289
+ async createAsync(input) {
1290
+ return this.client.request(PASSWORD_COMMANDS.create, { input });
1291
+ }
1292
+ /**
1293
+ * Update an existing item. The item must already be in scope, and
1294
+ * the new tag set must keep at least one tag in scope (extensions
1295
+ * cannot orphan an item out of their own reach).
1296
+ */
1297
+ async updateAsync(itemId, input) {
1298
+ return this.client.request(PASSWORD_COMMANDS.update, {
1299
+ itemId,
1300
+ input
1301
+ });
1302
+ }
1303
+ /** Delete an item by id. Item must be in scope. */
1304
+ async deleteAsync(itemId) {
1305
+ return this.client.request(PASSWORD_COMMANDS.delete, { itemId });
1306
+ }
1307
+ };
1308
+
1309
+ // src/api/mail.ts
1310
+ var MailAPI = class {
1311
+ constructor(client) {
1312
+ this.client = client;
1313
+ }
1314
+ /**
1315
+ * LIST mailboxes for an IMAP account. Pass `includeStatus=true` for
1316
+ * EXISTS/UNSEEN/UIDVALIDITY/UIDNEXT per box (one extra round-trip
1317
+ * per mailbox — fine for typical accounts, expensive for large
1318
+ * trees).
1319
+ */
1320
+ async listMailboxesAsync(imap, options = {}) {
1321
+ return this.client.request(MAIL_COMMANDS.listMailboxes, {
1322
+ imap,
1323
+ reference: options.reference,
1324
+ pattern: options.pattern,
1325
+ includeStatus: options.includeStatus
1326
+ });
1327
+ }
1328
+ /** Fetch lightweight envelopes for a mailbox + range (for list views). */
1329
+ async fetchEnvelopesAsync(imap, mailbox, range) {
1330
+ return this.client.request(
1331
+ MAIL_COMMANDS.fetchEnvelopes,
1332
+ { imap, mailbox, range }
1333
+ );
1334
+ }
1335
+ /** Fetch a full message (envelope + body + attachment metadata) by UID. */
1336
+ async fetchMessageAsync(imap, mailbox, uid) {
1337
+ return this.client.request(MAIL_COMMANDS.fetchMessage, {
1338
+ imap,
1339
+ mailbox,
1340
+ uid
1341
+ });
1342
+ }
1343
+ /**
1344
+ * Set or unset IMAP flags. Use `flags=["\\Seen"]` + `add=true` to
1345
+ * mark messages as read; `add=false` removes the flag(s).
1346
+ */
1347
+ async setFlagsAsync(imap, mailbox, uids, flags, add) {
1348
+ return this.client.request(MAIL_COMMANDS.setFlags, {
1349
+ imap,
1350
+ mailbox,
1351
+ uids,
1352
+ flags,
1353
+ add
1354
+ });
1355
+ }
1356
+ /** Move messages between mailboxes. Falls back to COPY+EXPUNGE on servers without MOVE. */
1357
+ async moveMessagesAsync(imap, sourceMailbox, destinationMailbox, uids) {
1358
+ return this.client.request(MAIL_COMMANDS.moveMessages, {
1359
+ imap,
1360
+ sourceMailbox,
1361
+ destinationMailbox,
1362
+ uids
1363
+ });
1364
+ }
1365
+ /**
1366
+ * APPEND a base64-encoded RFC822 message into a mailbox. Combine
1367
+ * with `buildRfc822Async` to save drafts, or with the bytes returned
1368
+ * after `sendMessageAsync` to mirror the sent copy into "Sent".
1369
+ */
1370
+ async appendMessageAsync(imap, mailbox, rfc822Base64, flags) {
1371
+ return this.client.request(MAIL_COMMANDS.appendMessage, {
1372
+ imap,
1373
+ mailbox,
1374
+ rfc822Base64,
1375
+ flags
1376
+ });
1377
+ }
1378
+ /** Send a message via SMTP. Returns the assigned Message-ID (no angle brackets). */
1379
+ async sendMessageAsync(smtp, message) {
1380
+ return this.client.request(MAIL_COMMANDS.sendMessage, {
1381
+ smtp,
1382
+ message
1383
+ });
1384
+ }
1385
+ /**
1386
+ * Build RFC822 bytes for a message without sending — useful for
1387
+ * drafts that get APPENDed to a "Drafts" folder. Permission-wise
1388
+ * this is a fetch operation (no SMTP host involved).
1389
+ */
1390
+ async buildRfc822Async(imapHost, message) {
1391
+ return this.client.request(MAIL_COMMANDS.buildRfc822, {
1392
+ imapHost,
1393
+ message
1394
+ });
1395
+ }
1396
+ };
1397
+
1225
1398
  // src/messages.ts
1226
1399
  var HAEXSPACE_MESSAGE_TYPES = {
1227
1400
  /** Debug message for development/troubleshooting */
@@ -1400,6 +1573,10 @@ function parseTableName(fullTableName) {
1400
1573
 
1401
1574
  // src/client/init.ts
1402
1575
  var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
1576
+ function getCurrentWebviewLabel() {
1577
+ const internals = window.__TAURI_INTERNALS__;
1578
+ return internals?.metadata?.currentWebview?.label;
1579
+ }
1403
1580
  function isInIframe() {
1404
1581
  return window.self !== window.top;
1405
1582
  }
@@ -1428,6 +1605,13 @@ async function initNativeMode(ctx, log, onEvent, onContextChange) {
1428
1605
  }
1429
1606
  async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1430
1607
  const { listen } = getTauriEvent();
1608
+ const webviewLabel = getCurrentWebviewLabel();
1609
+ const listenOptions = webviewLabel ? { target: webviewLabel } : void 0;
1610
+ if (!webviewLabel) {
1611
+ log(
1612
+ "WARNING: could not read __TAURI_INTERNALS__.metadata.currentWebview.label \u2014 registering listeners without a target. Label-scoped emits from the host will not be delivered until the metadata is available."
1613
+ );
1614
+ }
1431
1615
  log("Setting up Tauri event listener for:", HAEXTENSION_EVENTS.CONTEXT_CHANGED);
1432
1616
  try {
1433
1617
  await listen(HAEXTENSION_EVENTS.CONTEXT_CHANGED, (event) => {
@@ -1445,7 +1629,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1445
1629
  } else {
1446
1630
  log("Event received but no context in payload:", event);
1447
1631
  }
1448
- });
1632
+ }, listenOptions);
1449
1633
  log("Context change listener registered successfully");
1450
1634
  } catch (error) {
1451
1635
  log("Failed to setup context change listener:", error);
@@ -1463,7 +1647,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1463
1647
  } else {
1464
1648
  log("External request event has no payload!");
1465
1649
  }
1466
- });
1650
+ }, listenOptions);
1467
1651
  log("External request listener registered successfully");
1468
1652
  } catch (error) {
1469
1653
  log("Failed to setup external request listener:", error);
@@ -1481,7 +1665,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1481
1665
  } else {
1482
1666
  log("AI action request event has no payload!");
1483
1667
  }
1484
- });
1668
+ }, listenOptions);
1485
1669
  log("AI action request listener registered successfully");
1486
1670
  } catch (error) {
1487
1671
  log("Failed to setup AI action request listener:", error);
@@ -1500,7 +1684,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1500
1684
  timestamp: Date.now()
1501
1685
  });
1502
1686
  }
1503
- });
1687
+ }, listenOptions);
1504
1688
  log("File change listener registered successfully");
1505
1689
  } catch (error) {
1506
1690
  log("Failed to setup file change listener:", error);
@@ -1517,14 +1701,14 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1517
1701
  timestamp: Date.now()
1518
1702
  });
1519
1703
  }
1520
- });
1704
+ }, listenOptions);
1521
1705
  log("Sync tables updated listener registered successfully");
1522
1706
  } catch (error) {
1523
1707
  log("Failed to setup sync tables updated listener:", error);
1524
1708
  }
1525
1709
  log("Setting up LocalSend event listeners");
1526
1710
  try {
1527
- await setupLocalSendEventListeners(log, onEvent);
1711
+ await setupLocalSendEventListeners(log, onEvent, listenOptions);
1528
1712
  log("LocalSend event listeners setup complete");
1529
1713
  } catch (error) {
1530
1714
  log("Failed to setup LocalSend event listeners:", error);
@@ -1541,7 +1725,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1541
1725
  data: payload.data
1542
1726
  });
1543
1727
  }
1544
- });
1728
+ }, listenOptions);
1545
1729
  log("Shell output listener registered");
1546
1730
  await listen(SHELL_EVENTS.EXIT, (event) => {
1547
1731
  if (event.payload) {
@@ -1553,13 +1737,13 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
1553
1737
  exitCode: payload.exitCode
1554
1738
  });
1555
1739
  }
1556
- });
1740
+ }, listenOptions);
1557
1741
  log("Shell exit listener registered");
1558
1742
  } catch (error) {
1559
1743
  log("Failed to setup Shell event listeners:", error);
1560
1744
  }
1561
1745
  }
1562
- async function setupLocalSendEventListeners(log, onEvent) {
1746
+ async function setupLocalSendEventListeners(log, onEvent, listenOptions) {
1563
1747
  const { listen } = getTauriEvent();
1564
1748
  try {
1565
1749
  await listen(LOCALSEND_EVENTS.deviceDiscovered, (event) => {
@@ -1571,7 +1755,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
1571
1755
  timestamp: Date.now()
1572
1756
  });
1573
1757
  }
1574
- });
1758
+ }, listenOptions);
1575
1759
  log("LocalSend device discovered listener registered");
1576
1760
  } catch (error) {
1577
1761
  log("Failed to setup LocalSend device discovered listener:", error);
@@ -1586,7 +1770,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
1586
1770
  timestamp: Date.now()
1587
1771
  });
1588
1772
  }
1589
- });
1773
+ }, listenOptions);
1590
1774
  log("LocalSend device lost listener registered");
1591
1775
  } catch (error) {
1592
1776
  log("Failed to setup LocalSend device lost listener:", error);
@@ -1601,7 +1785,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
1601
1785
  timestamp: Date.now()
1602
1786
  });
1603
1787
  }
1604
- });
1788
+ }, listenOptions);
1605
1789
  log("LocalSend transfer request listener registered");
1606
1790
  } catch (error) {
1607
1791
  log("Failed to setup LocalSend transfer request listener:", error);
@@ -1616,7 +1800,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
1616
1800
  timestamp: Date.now()
1617
1801
  });
1618
1802
  }
1619
- });
1803
+ }, listenOptions);
1620
1804
  log("LocalSend transfer progress listener registered");
1621
1805
  } catch (error) {
1622
1806
  log("Failed to setup LocalSend transfer progress listener:", error);
@@ -1631,7 +1815,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
1631
1815
  timestamp: Date.now()
1632
1816
  });
1633
1817
  }
1634
- });
1818
+ }, listenOptions);
1635
1819
  log("LocalSend transfer complete listener registered");
1636
1820
  } catch (error) {
1637
1821
  log("Failed to setup LocalSend transfer complete listener:", error);
@@ -1646,13 +1830,13 @@ async function setupLocalSendEventListeners(log, onEvent) {
1646
1830
  timestamp: Date.now()
1647
1831
  });
1648
1832
  }
1649
- });
1833
+ }, listenOptions);
1650
1834
  log("LocalSend transfer failed listener registered");
1651
1835
  } catch (error) {
1652
1836
  log("Failed to setup LocalSend transfer failed listener:", error);
1653
1837
  }
1654
1838
  }
1655
- async function initIframeMode(ctx, log, messageHandler, request) {
1839
+ async function initIframeMode(ctx, log, messageHandler) {
1656
1840
  if (!isInIframe()) {
1657
1841
  throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
1658
1842
  }
@@ -1669,15 +1853,12 @@ async function initIframeMode(ctx, log, messageHandler, request) {
1669
1853
  publicKey: ctx.config.manifest.publicKey,
1670
1854
  name: ctx.config.manifest.name,
1671
1855
  version: ctx.config.manifest.version,
1672
- displayName: ctx.config.manifest.name
1856
+ displayName: ctx.config.manifest.displayName ?? ctx.config.manifest.name
1673
1857
  };
1674
1858
  log("Extension info loaded from manifest:", ctx.state.extensionInfo);
1675
1859
  }
1676
1860
  sendDebugInfo(ctx.config);
1677
- const context = await request(EXTENSION_COMMANDS.getContext);
1678
- ctx.state.context = context;
1679
- log("Application context received:", context);
1680
- return { context, port };
1861
+ return port;
1681
1862
  }
1682
1863
  function waitForHostPortAsync(log) {
1683
1864
  return new Promise((resolve, reject) => {
@@ -1860,11 +2041,10 @@ function processEvent(event, log, eventListeners, onContextChanged, onExternalRe
1860
2041
  emitEvent(event, log, eventListeners);
1861
2042
  }
1862
2043
  function emitEvent(event, log, eventListeners) {
1863
- console.log("[HaexVault SDK] emitEvent called with:", event.type, event);
1864
- console.log("[HaexVault SDK] Registered event types:", Array.from(eventListeners.keys()));
1865
- log("Event received:", event);
2044
+ log("emitEvent called with:", event.type, event);
2045
+ log("Registered event types:", Array.from(eventListeners.keys()));
1866
2046
  const listeners = eventListeners.get(event.type);
1867
- console.log("[HaexVault SDK] Listeners for", event.type, ":", listeners?.size ?? 0);
2047
+ log("Listeners for", event.type, ":", listeners?.size ?? 0);
1868
2048
  if (listeners) {
1869
2049
  listeners.forEach((callback) => callback(event));
1870
2050
  }
@@ -1961,9 +2141,9 @@ function registerExternalHandler(action, handler, handlers, log) {
1961
2141
  };
1962
2142
  }
1963
2143
  async function handleExternalRequest(request, handlers, respond, log) {
1964
- console.log("[SDK Debug] handleExternalRequest called!");
1965
- console.log("[SDK Debug] Request:", JSON.stringify(request, null, 2));
1966
- console.log("[SDK Debug] Available handlers:", Array.from(handlers.keys()));
2144
+ log("handleExternalRequest called");
2145
+ log("Request:", request);
2146
+ log("Available handlers:", Array.from(handlers.keys()));
1967
2147
  log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
1968
2148
  const handler = handlers.get(request.action);
1969
2149
  if (!handler) {
@@ -1989,7 +2169,6 @@ async function handleExternalRequest(request, handlers, respond, log) {
1989
2169
  }
1990
2170
  }
1991
2171
  async function respondToExternalRequest(response, request) {
1992
- console.log("[SDK Debug] respondToExternalRequest called with:", JSON.stringify(response, null, 2));
1993
2172
  await request(EXTERNAL_BRIDGE_COMMANDS.respond, response);
1994
2173
  }
1995
2174
 
@@ -2047,11 +2226,17 @@ var HaexVaultSdk = class {
2047
2226
  this.localsend = new LocalSendAPI(this);
2048
2227
  this.spaces = new SpacesAPI(this);
2049
2228
  this.shell = new ShellAPI(this);
2229
+ this.passwords = new PasswordsAPI(this);
2230
+ this.mail = new MailAPI(this);
2050
2231
  installConsoleForwarding(this.config.debug);
2051
- this.readyPromise = new Promise((resolve) => {
2232
+ this.readyPromise = new Promise((resolve, reject) => {
2052
2233
  this.resolveReady = resolve;
2234
+ this.rejectReady = reject;
2235
+ });
2236
+ this.init().catch((error) => {
2237
+ this.log("Init failed:", error);
2238
+ this.rejectReady(error);
2053
2239
  });
2054
- this.init();
2055
2240
  }
2056
2241
  // ==========================================================================
2057
2242
  // Lifecycle
@@ -2079,9 +2264,14 @@ var HaexVaultSdk = class {
2079
2264
  return this.setupPromise;
2080
2265
  }
2081
2266
  destroy() {
2082
- if (this.messageHandler) {
2083
- window.removeEventListener("message", this.messageHandler);
2267
+ if (this.messageHandler && this.hostPort) {
2268
+ this.hostPort.removeEventListener("message", this.messageHandler);
2084
2269
  }
2270
+ if (this.hostPort) {
2271
+ this.hostPort.close();
2272
+ this.hostPort = null;
2273
+ }
2274
+ this.messageHandler = null;
2085
2275
  this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
2086
2276
  this.pendingRequests.clear();
2087
2277
  this.eventListeners.clear();
@@ -2271,7 +2461,7 @@ var HaexVaultSdk = class {
2271
2461
  () => this._extensionInfo,
2272
2462
  this.handleEvent.bind(this)
2273
2463
  );
2274
- const { context, port } = await initIframeMode(
2464
+ const port = await initIframeMode(
2275
2465
  {
2276
2466
  config: this.config,
2277
2467
  state: {
@@ -2300,8 +2490,7 @@ var HaexVaultSdk = class {
2300
2490
  }
2301
2491
  },
2302
2492
  this.log.bind(this),
2303
- this.messageHandler,
2304
- this.request.bind(this)
2493
+ this.messageHandler
2305
2494
  );
2306
2495
  this.hostPort = port;
2307
2496
  if (this.config.manifest) {
@@ -2309,10 +2498,12 @@ var HaexVaultSdk = class {
2309
2498
  publicKey: this.config.manifest.publicKey,
2310
2499
  name: this.config.manifest.name,
2311
2500
  version: this.config.manifest.version,
2312
- displayName: this.config.manifest.name
2501
+ displayName: this.config.manifest.displayName ?? this.config.manifest.name
2313
2502
  };
2314
2503
  this.notifySubscribersInternal();
2315
2504
  }
2505
+ const context = await this.request(EXTENSION_COMMANDS.getContext);
2506
+ this.log("Application context received:", context);
2316
2507
  this._context = context;
2317
2508
  this.isNativeWindow = false;
2318
2509
  this.initialized = true;
@@ -2391,22 +2582,18 @@ var nuxt_plugin_client_default = defineNuxtPlugin(async (nuxtApp) => {
2391
2582
  context: client.context
2392
2583
  });
2393
2584
  await client.ready();
2394
- console.log("[Nuxt Plugin] Client ready, context:", client.context);
2395
2585
  state.value = {
2396
2586
  isReady: true,
2397
2587
  isSetupComplete: false,
2398
2588
  context: client.context
2399
2589
  };
2400
- console.log("[Nuxt Plugin] Initial state set:", state.value);
2401
2590
  client.subscribe(() => {
2402
- console.log("[Nuxt Plugin] Client context updated:", client.context);
2403
2591
  const isSetupComplete = client.setupCompleted;
2404
2592
  state.value = {
2405
2593
  ...state.value,
2406
2594
  context: client.context,
2407
2595
  isSetupComplete
2408
2596
  };
2409
- console.log("[Nuxt Plugin] State updated:", state.value);
2410
2597
  });
2411
2598
  const haexVaultPlugin = {
2412
2599
  client,