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