@agenticmail/core 0.6.0 → 0.7.0

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/index.cjs CHANGED
@@ -1469,7 +1469,16 @@ var DEFAULT_CONFIG = {
1469
1469
  port: 143
1470
1470
  },
1471
1471
  api: {
1472
- port: 3100,
1472
+ // Default API port: 3829.
1473
+ //
1474
+ // We deliberately avoid 3000 (React/Express default), 3100 (Grafana
1475
+ // Loki, also a common Express convention), 3200 (Grafana Tempo),
1476
+ // 3300 (LMS-style apps), 4000/5000/8000/8080 (too common). 3829 sits
1477
+ // in a quiet stretch — unassigned by IANA, and far enough from
1478
+ // common dev tooling that a fresh `agenticmail setup` rarely
1479
+ // collides. Users can override via the `AGENTICMAIL_API_PORT` env
1480
+ // var or by editing `~/.agenticmail/config.json` after install.
1481
+ port: 3829,
1473
1482
  host: "127.0.0.1"
1474
1483
  },
1475
1484
  masterKey: "",
@@ -3181,15 +3190,15 @@ function buildInboundSecurityAdvisory(security, attachments) {
3181
3190
  }
3182
3191
 
3183
3192
  // src/storage/db.ts
3184
- var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
3193
+ var import_node_sqlite = require("sqlite");
3185
3194
  var db = null;
3186
3195
  function getDatabase(config) {
3187
3196
  if (db) return db;
3188
3197
  ensureDataDir(config);
3189
3198
  const dbPath = `${config.dataDir}/agenticmail.db`;
3190
- db = new import_better_sqlite3.default(dbPath);
3191
- db.pragma("journal_mode = WAL");
3192
- db.pragma("foreign_keys = ON");
3199
+ db = new import_node_sqlite.DatabaseSync(dbPath);
3200
+ db.exec("PRAGMA journal_mode = WAL");
3201
+ db.exec("PRAGMA foreign_keys = ON");
3193
3202
  runMigrations(db);
3194
3203
  return db;
3195
3204
  }
@@ -3199,6 +3208,19 @@ function closeDatabase() {
3199
3208
  db = null;
3200
3209
  }
3201
3210
  }
3211
+ function runTransactionally(database, fn) {
3212
+ database.exec("BEGIN");
3213
+ try {
3214
+ fn();
3215
+ database.exec("COMMIT");
3216
+ } catch (err) {
3217
+ try {
3218
+ database.exec("ROLLBACK");
3219
+ } catch {
3220
+ }
3221
+ throw err;
3222
+ }
3223
+ }
3202
3224
  var MIGRATIONS = {
3203
3225
  "001_init.sql": `
3204
3226
  CREATE TABLE IF NOT EXISTS agents (
@@ -3459,19 +3481,18 @@ function runMigrations(database) {
3459
3481
  const applied = new Set(appliedStmt.all().map((r) => r.name));
3460
3482
  const insertStmt = database.prepare("INSERT INTO _migrations (name) VALUES (?)");
3461
3483
  const sortedMigrations = Object.entries(MIGRATIONS).sort(([a], [b]) => a.localeCompare(b));
3462
- const runMigration = database.transaction((name, sql) => {
3463
- database.exec(sql);
3464
- insertStmt.run(name);
3465
- });
3466
3484
  for (const [name, sql] of sortedMigrations) {
3467
3485
  if (applied.has(name)) continue;
3468
- runMigration(name, sql);
3486
+ runTransactionally(database, () => {
3487
+ database.exec(sql);
3488
+ insertStmt.run(name);
3489
+ });
3469
3490
  }
3470
3491
  }
3471
3492
  function createTestDatabase() {
3472
- const testDb = new import_better_sqlite3.default(":memory:");
3473
- testDb.pragma("journal_mode = WAL");
3474
- testDb.pragma("foreign_keys = ON");
3493
+ const testDb = new import_node_sqlite.DatabaseSync(":memory:");
3494
+ testDb.exec("PRAGMA journal_mode = WAL");
3495
+ testDb.exec("PRAGMA foreign_keys = ON");
3475
3496
  for (const sql of Object.values(MIGRATIONS)) {
3476
3497
  testDb.exec(sql);
3477
3498
  }
@@ -7756,7 +7777,7 @@ var SetupManager = class {
7756
7777
  },
7757
7778
  smtp: { host: "localhost", port: 587 },
7758
7779
  imap: { host: "localhost", port: 143 },
7759
- api: { port: 3100, host: "127.0.0.1" },
7780
+ api: { port: 3829, host: "127.0.0.1" },
7760
7781
  dataDir
7761
7782
  };
7762
7783
  (0, import_node_fs7.writeFileSync)(configPath, JSON.stringify(config, null, 2));
@@ -7767,7 +7788,7 @@ STALWART_ADMIN_PASSWORD=${stalwartPassword}
7767
7788
  STALWART_URL=http://localhost:8080
7768
7789
 
7769
7790
  AGENTICMAIL_MASTER_KEY=${masterKey}
7770
- AGENTICMAIL_API_PORT=3100
7791
+ AGENTICMAIL_API_PORT=3829
7771
7792
  AGENTICMAIL_DATA_DIR=${dataDir}
7772
7793
 
7773
7794
  SMTP_HOST=localhost
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import Database, { Database as Database$1 } from 'better-sqlite3';
2
+ import { DatabaseSync } from 'node:sqlite';
3
3
  import { ImapFlow } from 'imapflow';
4
4
 
5
5
  interface SendMailOptions {
@@ -291,6 +291,50 @@ declare class StalwartAdmin {
291
291
  }): Promise<void>;
292
292
  }
293
293
 
294
+ /**
295
+ * SQLite storage layer for AgenticMail.
296
+ *
297
+ * Migrated from `better-sqlite3` to Node's built-in `node:sqlite` module
298
+ * (stable since Node 22). The migration eliminates native compilation
299
+ * entirely — `better-sqlite3` ships pre-built binaries per
300
+ * NODE_MODULE_VERSION and intermittently lags new Node releases (Node
301
+ * 25.5.0 was a real example: prebuilds missing, node-gyp fails on the
302
+ * fallback compile-from-source path, fresh `npm install -g
303
+ * @agenticmail/cli` fails for users on bleeding-edge Node). `node:sqlite`
304
+ * is part of Node itself, so by definition it always matches the
305
+ * runtime — no prebuilds, no gyp, no binding errors.
306
+ *
307
+ * # API shape differences this file accommodates
308
+ *
309
+ * - `new DatabaseSync(path)` instead of `new Database(path)`.
310
+ * - No `db.pragma(x)` — use `db.exec("PRAGMA " + x)`.
311
+ * - No `db.transaction(fn)` — wrap in BEGIN/COMMIT manually (see
312
+ * `runTransactionally` below). Migrations are the only transaction
313
+ * site in core right now; if more callers need transactions later
314
+ * they should reuse the same helper.
315
+ * - `stmt.run(...)` still returns `{ changes, lastInsertRowid }`.
316
+ * One subtle gotcha: `lastInsertRowid` is a `bigint` in node:sqlite
317
+ * where better-sqlite3 returned a `number`. Consumers that compare
318
+ * with `===` or pass it to `Number(...)` need to be aware, but no
319
+ * site inside AgenticMail today does that — all our rowids are
320
+ * opaque or string-typed.
321
+ * - The class type is `DatabaseSync`; we re-export it as `Database`
322
+ * so consumer files can keep saying `Database` instead of plumbing
323
+ * `DatabaseSync` through everywhere.
324
+ */
325
+
326
+ /**
327
+ * Public type alias for the database instance. Consumers should
328
+ * `import { type Database } from '@agenticmail/core'` rather than
329
+ * importing from `node:sqlite` directly — this insulates them from any
330
+ * future swap (back to better-sqlite3, or to a remote driver) without
331
+ * a cascade of changes across the workspace.
332
+ */
333
+ type Database = DatabaseSync;
334
+ declare function getDatabase(config: AgenticMailConfig): Database;
335
+ declare function closeDatabase(): void;
336
+ declare function createTestDatabase(): Database;
337
+
294
338
  /** Predefined agent roles */
295
339
  type AgentRole = 'secretary' | 'assistant' | 'researcher' | 'writer' | 'custom';
296
340
  declare const AGENT_ROLES: readonly AgentRole[];
@@ -319,7 +363,7 @@ interface CreateAgentOptions {
319
363
  declare class AccountManager {
320
364
  private db;
321
365
  private stalwart;
322
- constructor(db: Database.Database, stalwart: StalwartAdmin);
366
+ constructor(db: Database, stalwart: StalwartAdmin);
323
367
  create(options: CreateAgentOptions): Promise<Agent>;
324
368
  getById(id: string): Promise<Agent | null>;
325
369
  getByApiKey(apiKey: string): Promise<Agent | null>;
@@ -399,7 +443,7 @@ declare class AgentDeletionService {
399
443
  private db;
400
444
  private accountManager;
401
445
  private config;
402
- constructor(db: Database.Database, accountManager: AccountManager, config: AgenticMailConfig);
446
+ constructor(db: Database, accountManager: AccountManager, config: AgenticMailConfig);
403
447
  archiveAndDelete(agentId: string, options?: ArchiveAndDeleteOptions): Promise<DeletionReport>;
404
448
  getReport(deletionId: string): DeletionReport | null;
405
449
  listReports(): DeletionSummary[];
@@ -615,10 +659,6 @@ declare function buildInboundSecurityAdvisory(security: {
615
659
  size?: number;
616
660
  }> | undefined): SecurityAdvisory;
617
661
 
618
- declare function getDatabase(config: AgenticMailConfig): Database.Database;
619
- declare function closeDatabase(): void;
620
- declare function createTestDatabase(): Database.Database;
621
-
622
662
  interface SearchableEmail {
623
663
  agentId: string;
624
664
  messageId: string;
@@ -630,7 +670,7 @@ interface SearchableEmail {
630
670
  }
631
671
  declare class EmailSearchIndex {
632
672
  private db;
633
- constructor(db: Database.Database);
673
+ constructor(db: Database);
634
674
  index(email: SearchableEmail): void;
635
675
  search(agentId: string, query: string, limit?: number): SearchableEmail[];
636
676
  deleteByAgent(agentId: string): void;
@@ -658,7 +698,7 @@ interface DomainSetupResult {
658
698
  declare class DomainManager {
659
699
  private db;
660
700
  private stalwart;
661
- constructor(db: Database.Database, stalwart: StalwartAdmin);
701
+ constructor(db: Database, stalwart: StalwartAdmin);
662
702
  setup(domain: string): Promise<DomainSetupResult>;
663
703
  private generateDnsRecords;
664
704
  get(domain: string): Promise<DomainInfo | null>;
@@ -1097,7 +1137,7 @@ interface LocalSmtpConfig {
1097
1137
  pass: string;
1098
1138
  }
1099
1139
  interface GatewayManagerOptions {
1100
- db: Database.Database;
1140
+ db: Database;
1101
1141
  stalwart: StalwartAdmin;
1102
1142
  accountManager?: AccountManager;
1103
1143
  localSmtp?: LocalSmtpConfig;
@@ -1367,7 +1407,7 @@ declare function extractVerificationCode(smsBody: string): string | null;
1367
1407
  declare class SmsManager {
1368
1408
  private db;
1369
1409
  private initialized;
1370
- constructor(db: Database$1);
1410
+ constructor(db: Database);
1371
1411
  private ensureTable;
1372
1412
  /** Get SMS config from agent metadata */
1373
1413
  getSmsConfig(agentId: string): SmsConfig | null;
@@ -1753,4 +1793,4 @@ declare class SetupManager {
1753
1793
  isInitialized(): boolean;
1754
1794
  }
1755
1795
 
1756
- export { AGENT_ROLES, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, CloudflareClient, type CreateAgentOptions, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DNSConfigurator, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type InboundEmail, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, type LinkAdvisory, type LocalSmtpConfig, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, type ParsedAttachment, type ParsedEmail, type ParsedSms, type PurchasedDomain, RELAY_PRESETS, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, SPAM_THRESHOLD, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, ServiceManager, type ServiceStatus, type SetupConfig, SetupManager, type SetupResult, type Severity, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type TunnelConfig, TunnelManager, WARNING_THRESHOLD, type WatcherOptions, buildInboundSecurityAdvisory, classifyEmailRoute, closeDatabase, createTestDatabase, debug, debugWarn, ensureDataDir, extractVerificationCode, flushTelemetry, getDatabase, isInternalEmail, isValidPhoneNumber, normalizePhoneNumber, parseEmail, parseGoogleVoiceSms, recordToolCall, resolveConfig, sanitizeEmail, saveConfig, scanOutboundEmail, scoreEmail, setTelemetryVersion, startRelayBridge };
1796
+ export { AGENT_ROLES, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, CloudflareClient, type CreateAgentOptions, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type InboundEmail, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, type LinkAdvisory, type LocalSmtpConfig, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, type ParsedAttachment, type ParsedEmail, type ParsedSms, type PurchasedDomain, RELAY_PRESETS, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, SPAM_THRESHOLD, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, ServiceManager, type ServiceStatus, type SetupConfig, SetupManager, type SetupResult, type Severity, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type TunnelConfig, TunnelManager, WARNING_THRESHOLD, type WatcherOptions, buildInboundSecurityAdvisory, classifyEmailRoute, closeDatabase, createTestDatabase, debug, debugWarn, ensureDataDir, extractVerificationCode, flushTelemetry, getDatabase, isInternalEmail, isValidPhoneNumber, normalizePhoneNumber, parseEmail, parseGoogleVoiceSms, recordToolCall, resolveConfig, sanitizeEmail, saveConfig, scanOutboundEmail, scoreEmail, setTelemetryVersion, startRelayBridge };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import Database, { Database as Database$1 } from 'better-sqlite3';
2
+ import { DatabaseSync } from 'node:sqlite';
3
3
  import { ImapFlow } from 'imapflow';
4
4
 
5
5
  interface SendMailOptions {
@@ -291,6 +291,50 @@ declare class StalwartAdmin {
291
291
  }): Promise<void>;
292
292
  }
293
293
 
294
+ /**
295
+ * SQLite storage layer for AgenticMail.
296
+ *
297
+ * Migrated from `better-sqlite3` to Node's built-in `node:sqlite` module
298
+ * (stable since Node 22). The migration eliminates native compilation
299
+ * entirely — `better-sqlite3` ships pre-built binaries per
300
+ * NODE_MODULE_VERSION and intermittently lags new Node releases (Node
301
+ * 25.5.0 was a real example: prebuilds missing, node-gyp fails on the
302
+ * fallback compile-from-source path, fresh `npm install -g
303
+ * @agenticmail/cli` fails for users on bleeding-edge Node). `node:sqlite`
304
+ * is part of Node itself, so by definition it always matches the
305
+ * runtime — no prebuilds, no gyp, no binding errors.
306
+ *
307
+ * # API shape differences this file accommodates
308
+ *
309
+ * - `new DatabaseSync(path)` instead of `new Database(path)`.
310
+ * - No `db.pragma(x)` — use `db.exec("PRAGMA " + x)`.
311
+ * - No `db.transaction(fn)` — wrap in BEGIN/COMMIT manually (see
312
+ * `runTransactionally` below). Migrations are the only transaction
313
+ * site in core right now; if more callers need transactions later
314
+ * they should reuse the same helper.
315
+ * - `stmt.run(...)` still returns `{ changes, lastInsertRowid }`.
316
+ * One subtle gotcha: `lastInsertRowid` is a `bigint` in node:sqlite
317
+ * where better-sqlite3 returned a `number`. Consumers that compare
318
+ * with `===` or pass it to `Number(...)` need to be aware, but no
319
+ * site inside AgenticMail today does that — all our rowids are
320
+ * opaque or string-typed.
321
+ * - The class type is `DatabaseSync`; we re-export it as `Database`
322
+ * so consumer files can keep saying `Database` instead of plumbing
323
+ * `DatabaseSync` through everywhere.
324
+ */
325
+
326
+ /**
327
+ * Public type alias for the database instance. Consumers should
328
+ * `import { type Database } from '@agenticmail/core'` rather than
329
+ * importing from `node:sqlite` directly — this insulates them from any
330
+ * future swap (back to better-sqlite3, or to a remote driver) without
331
+ * a cascade of changes across the workspace.
332
+ */
333
+ type Database = DatabaseSync;
334
+ declare function getDatabase(config: AgenticMailConfig): Database;
335
+ declare function closeDatabase(): void;
336
+ declare function createTestDatabase(): Database;
337
+
294
338
  /** Predefined agent roles */
295
339
  type AgentRole = 'secretary' | 'assistant' | 'researcher' | 'writer' | 'custom';
296
340
  declare const AGENT_ROLES: readonly AgentRole[];
@@ -319,7 +363,7 @@ interface CreateAgentOptions {
319
363
  declare class AccountManager {
320
364
  private db;
321
365
  private stalwart;
322
- constructor(db: Database.Database, stalwart: StalwartAdmin);
366
+ constructor(db: Database, stalwart: StalwartAdmin);
323
367
  create(options: CreateAgentOptions): Promise<Agent>;
324
368
  getById(id: string): Promise<Agent | null>;
325
369
  getByApiKey(apiKey: string): Promise<Agent | null>;
@@ -399,7 +443,7 @@ declare class AgentDeletionService {
399
443
  private db;
400
444
  private accountManager;
401
445
  private config;
402
- constructor(db: Database.Database, accountManager: AccountManager, config: AgenticMailConfig);
446
+ constructor(db: Database, accountManager: AccountManager, config: AgenticMailConfig);
403
447
  archiveAndDelete(agentId: string, options?: ArchiveAndDeleteOptions): Promise<DeletionReport>;
404
448
  getReport(deletionId: string): DeletionReport | null;
405
449
  listReports(): DeletionSummary[];
@@ -615,10 +659,6 @@ declare function buildInboundSecurityAdvisory(security: {
615
659
  size?: number;
616
660
  }> | undefined): SecurityAdvisory;
617
661
 
618
- declare function getDatabase(config: AgenticMailConfig): Database.Database;
619
- declare function closeDatabase(): void;
620
- declare function createTestDatabase(): Database.Database;
621
-
622
662
  interface SearchableEmail {
623
663
  agentId: string;
624
664
  messageId: string;
@@ -630,7 +670,7 @@ interface SearchableEmail {
630
670
  }
631
671
  declare class EmailSearchIndex {
632
672
  private db;
633
- constructor(db: Database.Database);
673
+ constructor(db: Database);
634
674
  index(email: SearchableEmail): void;
635
675
  search(agentId: string, query: string, limit?: number): SearchableEmail[];
636
676
  deleteByAgent(agentId: string): void;
@@ -658,7 +698,7 @@ interface DomainSetupResult {
658
698
  declare class DomainManager {
659
699
  private db;
660
700
  private stalwart;
661
- constructor(db: Database.Database, stalwart: StalwartAdmin);
701
+ constructor(db: Database, stalwart: StalwartAdmin);
662
702
  setup(domain: string): Promise<DomainSetupResult>;
663
703
  private generateDnsRecords;
664
704
  get(domain: string): Promise<DomainInfo | null>;
@@ -1097,7 +1137,7 @@ interface LocalSmtpConfig {
1097
1137
  pass: string;
1098
1138
  }
1099
1139
  interface GatewayManagerOptions {
1100
- db: Database.Database;
1140
+ db: Database;
1101
1141
  stalwart: StalwartAdmin;
1102
1142
  accountManager?: AccountManager;
1103
1143
  localSmtp?: LocalSmtpConfig;
@@ -1367,7 +1407,7 @@ declare function extractVerificationCode(smsBody: string): string | null;
1367
1407
  declare class SmsManager {
1368
1408
  private db;
1369
1409
  private initialized;
1370
- constructor(db: Database$1);
1410
+ constructor(db: Database);
1371
1411
  private ensureTable;
1372
1412
  /** Get SMS config from agent metadata */
1373
1413
  getSmsConfig(agentId: string): SmsConfig | null;
@@ -1753,4 +1793,4 @@ declare class SetupManager {
1753
1793
  isInitialized(): boolean;
1754
1794
  }
1755
1795
 
1756
- export { AGENT_ROLES, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, CloudflareClient, type CreateAgentOptions, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DNSConfigurator, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type InboundEmail, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, type LinkAdvisory, type LocalSmtpConfig, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, type ParsedAttachment, type ParsedEmail, type ParsedSms, type PurchasedDomain, RELAY_PRESETS, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, SPAM_THRESHOLD, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, ServiceManager, type ServiceStatus, type SetupConfig, SetupManager, type SetupResult, type Severity, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type TunnelConfig, TunnelManager, WARNING_THRESHOLD, type WatcherOptions, buildInboundSecurityAdvisory, classifyEmailRoute, closeDatabase, createTestDatabase, debug, debugWarn, ensureDataDir, extractVerificationCode, flushTelemetry, getDatabase, isInternalEmail, isValidPhoneNumber, normalizePhoneNumber, parseEmail, parseGoogleVoiceSms, recordToolCall, resolveConfig, sanitizeEmail, saveConfig, scanOutboundEmail, scoreEmail, setTelemetryVersion, startRelayBridge };
1796
+ export { AGENT_ROLES, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, CloudflareClient, type CreateAgentOptions, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type InboundEmail, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, type LinkAdvisory, type LocalSmtpConfig, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, type ParsedAttachment, type ParsedEmail, type ParsedSms, type PurchasedDomain, RELAY_PRESETS, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, SPAM_THRESHOLD, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, ServiceManager, type ServiceStatus, type SetupConfig, SetupManager, type SetupResult, type Severity, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type TunnelConfig, TunnelManager, WARNING_THRESHOLD, type WatcherOptions, buildInboundSecurityAdvisory, classifyEmailRoute, closeDatabase, createTestDatabase, debug, debugWarn, ensureDataDir, extractVerificationCode, flushTelemetry, getDatabase, isInternalEmail, isValidPhoneNumber, normalizePhoneNumber, parseEmail, parseGoogleVoiceSms, recordToolCall, resolveConfig, sanitizeEmail, saveConfig, scanOutboundEmail, scoreEmail, setTelemetryVersion, startRelayBridge };
package/dist/index.js CHANGED
@@ -715,7 +715,16 @@ var DEFAULT_CONFIG = {
715
715
  port: 143
716
716
  },
717
717
  api: {
718
- port: 3100,
718
+ // Default API port: 3829.
719
+ //
720
+ // We deliberately avoid 3000 (React/Express default), 3100 (Grafana
721
+ // Loki, also a common Express convention), 3200 (Grafana Tempo),
722
+ // 3300 (LMS-style apps), 4000/5000/8000/8080 (too common). 3829 sits
723
+ // in a quiet stretch — unassigned by IANA, and far enough from
724
+ // common dev tooling that a fresh `agenticmail setup` rarely
725
+ // collides. Users can override via the `AGENTICMAIL_API_PORT` env
726
+ // var or by editing `~/.agenticmail/config.json` after install.
727
+ port: 3829,
719
728
  host: "127.0.0.1"
720
729
  },
721
730
  masterKey: "",
@@ -2424,15 +2433,15 @@ function buildInboundSecurityAdvisory(security, attachments) {
2424
2433
  }
2425
2434
 
2426
2435
  // src/storage/db.ts
2427
- import Database from "better-sqlite3";
2436
+ import { DatabaseSync } from "sqlite";
2428
2437
  var db = null;
2429
2438
  function getDatabase(config) {
2430
2439
  if (db) return db;
2431
2440
  ensureDataDir(config);
2432
2441
  const dbPath = `${config.dataDir}/agenticmail.db`;
2433
- db = new Database(dbPath);
2434
- db.pragma("journal_mode = WAL");
2435
- db.pragma("foreign_keys = ON");
2442
+ db = new DatabaseSync(dbPath);
2443
+ db.exec("PRAGMA journal_mode = WAL");
2444
+ db.exec("PRAGMA foreign_keys = ON");
2436
2445
  runMigrations(db);
2437
2446
  return db;
2438
2447
  }
@@ -2442,6 +2451,19 @@ function closeDatabase() {
2442
2451
  db = null;
2443
2452
  }
2444
2453
  }
2454
+ function runTransactionally(database, fn) {
2455
+ database.exec("BEGIN");
2456
+ try {
2457
+ fn();
2458
+ database.exec("COMMIT");
2459
+ } catch (err) {
2460
+ try {
2461
+ database.exec("ROLLBACK");
2462
+ } catch {
2463
+ }
2464
+ throw err;
2465
+ }
2466
+ }
2445
2467
  var MIGRATIONS = {
2446
2468
  "001_init.sql": `
2447
2469
  CREATE TABLE IF NOT EXISTS agents (
@@ -2702,19 +2724,18 @@ function runMigrations(database) {
2702
2724
  const applied = new Set(appliedStmt.all().map((r) => r.name));
2703
2725
  const insertStmt = database.prepare("INSERT INTO _migrations (name) VALUES (?)");
2704
2726
  const sortedMigrations = Object.entries(MIGRATIONS).sort(([a], [b]) => a.localeCompare(b));
2705
- const runMigration = database.transaction((name, sql) => {
2706
- database.exec(sql);
2707
- insertStmt.run(name);
2708
- });
2709
2727
  for (const [name, sql] of sortedMigrations) {
2710
2728
  if (applied.has(name)) continue;
2711
- runMigration(name, sql);
2729
+ runTransactionally(database, () => {
2730
+ database.exec(sql);
2731
+ insertStmt.run(name);
2732
+ });
2712
2733
  }
2713
2734
  }
2714
2735
  function createTestDatabase() {
2715
- const testDb = new Database(":memory:");
2716
- testDb.pragma("journal_mode = WAL");
2717
- testDb.pragma("foreign_keys = ON");
2736
+ const testDb = new DatabaseSync(":memory:");
2737
+ testDb.exec("PRAGMA journal_mode = WAL");
2738
+ testDb.exec("PRAGMA foreign_keys = ON");
2718
2739
  for (const sql of Object.values(MIGRATIONS)) {
2719
2740
  testDb.exec(sql);
2720
2741
  }
@@ -6997,7 +7018,7 @@ var SetupManager = class {
6997
7018
  },
6998
7019
  smtp: { host: "localhost", port: 587 },
6999
7020
  imap: { host: "localhost", port: 143 },
7000
- api: { port: 3100, host: "127.0.0.1" },
7021
+ api: { port: 3829, host: "127.0.0.1" },
7001
7022
  dataDir
7002
7023
  };
7003
7024
  writeFileSync5(configPath, JSON.stringify(config, null, 2));
@@ -7008,7 +7029,7 @@ STALWART_ADMIN_PASSWORD=${stalwartPassword}
7008
7029
  STALWART_URL=http://localhost:8080
7009
7030
 
7010
7031
  AGENTICMAIL_MASTER_KEY=${masterKey}
7011
- AGENTICMAIL_API_PORT=3100
7032
+ AGENTICMAIL_API_PORT=3829
7012
7033
  AGENTICMAIL_DATA_DIR=${dataDir}
7013
7034
 
7014
7035
  SMTP_HOST=localhost
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Core SDK for AgenticMail — email, SMS, and phone number access for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -27,14 +27,12 @@
27
27
  "prepublishOnly": "npm run build"
28
28
  },
29
29
  "dependencies": {
30
- "better-sqlite3": "^11.8.0",
31
30
  "imapflow": "^1.0.170",
32
31
  "mailparser": "^3.7.2",
33
32
  "nodemailer": "^8.0.1",
34
33
  "uuid": "^11.1.0"
35
34
  },
36
35
  "devDependencies": {
37
- "@types/better-sqlite3": "^7.6.13",
38
36
  "@types/mailparser": "^3.4.6",
39
37
  "@types/nodemailer": "^6.4.17",
40
38
  "@types/uuid": "^10.0.0",
@@ -43,7 +41,7 @@
43
41
  "vitest": "^3.0.0"
44
42
  },
45
43
  "engines": {
46
- "node": ">=20"
44
+ "node": ">=22"
47
45
  },
48
46
  "repository": {
49
47
  "type": "git",