@agenticmail/enterprise 0.5.52 → 0.5.54

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 (53) hide show
  1. package/dist/chunk-4ZVC4XJY.js +3563 -0
  2. package/dist/chunk-CPYEURFL.js +2115 -0
  3. package/dist/chunk-G54QH5PZ.js +9085 -0
  4. package/dist/chunk-GI5RMYH6.js +37 -0
  5. package/dist/chunk-HAN6MNXJ.js +374 -0
  6. package/dist/chunk-L447KLHG.js +13099 -0
  7. package/dist/chunk-ORN3ILZD.js +48 -0
  8. package/dist/chunk-QIBEF5G3.js +898 -0
  9. package/dist/chunk-WA6WJN3D.js +2115 -0
  10. package/dist/chunk-WUWGI4C2.js +898 -0
  11. package/dist/chunk-ZVCBP4IS.js +13099 -0
  12. package/dist/cidr-MQSAKEA6.js +17 -0
  13. package/dist/cli-build-skill-ZD5FURGY.js +235 -0
  14. package/dist/cli-recover-XKHGIGGR.js +97 -0
  15. package/dist/cli-submit-skill-R7HUAMYR.js +162 -0
  16. package/dist/cli-validate-BDWKT6KH.js +148 -0
  17. package/dist/cli-verify-RTYVUWD7.js +98 -0
  18. package/dist/cli.js +1 -1
  19. package/dist/config-store-44Y6KOVX.js +58 -0
  20. package/dist/dashboard/pages/agent-detail.js +387 -2
  21. package/dist/dashboard/pages/agents.js +1 -1
  22. package/dist/db-adapter-FJZ5BESQ.js +7 -0
  23. package/dist/domain-lock-7EMDJXFQ.js +7 -0
  24. package/dist/dynamodb-CDDPVEXF.js +424 -0
  25. package/dist/factory-2SRP3B3U.js +9 -0
  26. package/dist/firewall-RTIDM4NY.js +10 -0
  27. package/dist/imap-flow-QTNT4Y75.js +44953 -0
  28. package/dist/index.js +325 -4
  29. package/dist/managed-2CZ3CSGR.js +17 -0
  30. package/dist/mongodb-UEHZUXYD.js +320 -0
  31. package/dist/mysql-4BBS773W.js +575 -0
  32. package/dist/nodemailer-JCKCTRMI.js +11711 -0
  33. package/dist/postgres-BCVODZLS.js +597 -0
  34. package/dist/providers-VPFJNW4H.js +17 -0
  35. package/dist/resolve-driver-ZLJYEK72.js +27 -0
  36. package/dist/routes-4QSVCR2K.js +6041 -0
  37. package/dist/routes-M5J73UQY.js +5783 -0
  38. package/dist/runtime-73YSHUJC.js +47 -0
  39. package/dist/runtime-KQFFAIFR.js +47 -0
  40. package/dist/server-4FHO44MK.js +12 -0
  41. package/dist/server-AQJO3PRA.js +12 -0
  42. package/dist/setup-AYIBPFNQ.js +20 -0
  43. package/dist/setup-ZWEA6MUM.js +20 -0
  44. package/dist/skills-WMCZVXBK.js +14 -0
  45. package/dist/sqlite-K6HN7XRU.js +491 -0
  46. package/dist/turso-BBUTZACL.js +496 -0
  47. package/package.json +2 -2
  48. package/src/agenticmail/index.ts +2 -0
  49. package/src/agenticmail/providers/imap.ts +454 -0
  50. package/src/agenticmail/providers/index.ts +4 -2
  51. package/src/dashboard/pages/agent-detail.js +387 -2
  52. package/src/dashboard/pages/agents.js +1 -1
  53. package/src/engine/agent-routes.ts +308 -0
@@ -0,0 +1,98 @@
1
+ import {
2
+ DomainLock
3
+ } from "./chunk-UPU23ZRG.js";
4
+ import "./chunk-GI5RMYH6.js";
5
+
6
+ // src/domain-lock/cli-verify.ts
7
+ function getFlag(args, name) {
8
+ const idx = args.indexOf(name);
9
+ if (idx !== -1 && args[idx + 1]) return args[idx + 1];
10
+ return void 0;
11
+ }
12
+ async function runVerifyDomain(args) {
13
+ const { default: chalk } = await import("chalk");
14
+ const { default: ora } = await import("ora");
15
+ console.log("");
16
+ console.log(chalk.bold(" AgenticMail Enterprise \u2014 Domain Verification"));
17
+ console.log("");
18
+ let domain = getFlag(args, "--domain");
19
+ let dnsChallenge;
20
+ let dbConnected = false;
21
+ let db = null;
22
+ if (!domain) {
23
+ const dbPath = getFlag(args, "--db");
24
+ const dbType = getFlag(args, "--db-type") || "sqlite";
25
+ if (dbPath) {
26
+ try {
27
+ const { createAdapter } = await import("./factory-2SRP3B3U.js");
28
+ db = await createAdapter({ type: dbType, connectionString: dbPath });
29
+ await db.migrate();
30
+ const settings = await db.getSettings();
31
+ domain = settings?.domain;
32
+ dnsChallenge = settings?.domainDnsChallenge;
33
+ dbConnected = true;
34
+ } catch {
35
+ }
36
+ }
37
+ }
38
+ if (!domain) {
39
+ const { default: inquirer } = await import("inquirer");
40
+ const answer = await inquirer.prompt([{
41
+ type: "input",
42
+ name: "domain",
43
+ message: "Domain to verify:",
44
+ suffix: chalk.dim(" (e.g. agents.agenticmail.io)"),
45
+ validate: (v) => v.includes(".") || "Enter a valid domain"
46
+ }]);
47
+ domain = answer.domain;
48
+ }
49
+ const spinner = ora("Checking DNS verification...").start();
50
+ const lock = new DomainLock();
51
+ const result = await lock.checkVerification(domain);
52
+ if (!result.success) {
53
+ spinner.fail("Verification check failed");
54
+ console.log("");
55
+ console.error(chalk.red(` ${result.error}`));
56
+ console.log("");
57
+ if (db) await db.disconnect();
58
+ process.exit(1);
59
+ }
60
+ if (result.verified) {
61
+ spinner.succeed("Domain verified!");
62
+ if (dbConnected && db) {
63
+ try {
64
+ await db.updateSettings({
65
+ domainStatus: "verified",
66
+ domainVerifiedAt: (/* @__PURE__ */ new Date()).toISOString()
67
+ });
68
+ } catch {
69
+ }
70
+ }
71
+ console.log("");
72
+ console.log(chalk.green.bold(` ${domain} is verified and protected.`));
73
+ console.log(chalk.dim(" Your deployment domain is locked. No other instance can claim it."));
74
+ console.log("");
75
+ } else {
76
+ spinner.info("DNS record not found yet");
77
+ console.log("");
78
+ console.log(chalk.yellow(" The DNS TXT record has not been detected."));
79
+ console.log("");
80
+ console.log(chalk.bold(" Make sure this record exists:"));
81
+ console.log("");
82
+ console.log(` ${chalk.bold("Host:")} ${chalk.cyan(`_agenticmail-verify.${domain}`)}`);
83
+ console.log(` ${chalk.bold("Type:")} ${chalk.cyan("TXT")}`);
84
+ if (dnsChallenge) {
85
+ console.log(` ${chalk.bold("Value:")} ${chalk.cyan(dnsChallenge)}`);
86
+ } else {
87
+ console.log(` ${chalk.bold("Value:")} ${chalk.dim("(check your setup records or dashboard)")}`);
88
+ }
89
+ console.log("");
90
+ console.log(chalk.dim(" DNS changes can take up to 48 hours to propagate."));
91
+ console.log(chalk.dim(" Run this command again after adding the record."));
92
+ console.log("");
93
+ }
94
+ if (db) await db.disconnect();
95
+ }
96
+ export {
97
+ runVerifyDomain
98
+ };
package/dist/cli.js CHANGED
@@ -48,7 +48,7 @@ Skill Development:
48
48
  break;
49
49
  case "setup":
50
50
  default:
51
- import("./setup-RJE5Y2RQ.js").then((m) => m.runSetupWizard()).catch(fatal);
51
+ import("./setup-AYIBPFNQ.js").then((m) => m.runSetupWizard()).catch(fatal);
52
52
  break;
53
53
  }
54
54
  function fatal(err) {
@@ -0,0 +1,58 @@
1
+ import "./chunk-GI5RMYH6.js";
2
+
3
+ // src/lib/config-store.ts
4
+ import { scryptSync, randomBytes, createCipheriv, createDecipheriv } from "crypto";
5
+ import { readFileSync, writeFileSync, existsSync } from "fs";
6
+ import { join } from "path";
7
+ var CONFIG_FILE = ".agenticmail.enc";
8
+ var ALGORITHM = "aes-256-gcm";
9
+ var SCRYPT_KEYLEN = 32;
10
+ var SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };
11
+ function deriveKey(secret, salt) {
12
+ return scryptSync(secret, salt, SCRYPT_KEYLEN, SCRYPT_PARAMS);
13
+ }
14
+ function getConfigPath() {
15
+ return join(process.cwd(), CONFIG_FILE);
16
+ }
17
+ async function saveDbConfig(config, secret) {
18
+ const salt = randomBytes(16);
19
+ const key = deriveKey(secret, salt);
20
+ const iv = randomBytes(12);
21
+ const cipher = createCipheriv(ALGORITHM, key, iv);
22
+ const plaintext = JSON.stringify(config);
23
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
24
+ const tag = cipher.getAuthTag();
25
+ const payload = {
26
+ iv: iv.toString("base64"),
27
+ tag: tag.toString("base64"),
28
+ salt: salt.toString("base64"),
29
+ data: encrypted.toString("base64")
30
+ };
31
+ writeFileSync(getConfigPath(), JSON.stringify(payload, null, 2), "utf-8");
32
+ }
33
+ async function loadDbConfig(secret) {
34
+ const path = getConfigPath();
35
+ if (!existsSync(path)) return null;
36
+ try {
37
+ const raw = JSON.parse(readFileSync(path, "utf-8"));
38
+ const salt = Buffer.from(raw.salt, "base64");
39
+ const iv = Buffer.from(raw.iv, "base64");
40
+ const tag = Buffer.from(raw.tag, "base64");
41
+ const data = Buffer.from(raw.data, "base64");
42
+ const key = deriveKey(secret, salt);
43
+ const decipher = createDecipheriv(ALGORITHM, key, iv);
44
+ decipher.setAuthTag(tag);
45
+ const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
46
+ return JSON.parse(decrypted.toString("utf-8"));
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+ function configFileExists() {
52
+ return existsSync(getConfigPath());
53
+ }
54
+ export {
55
+ configFileExists,
56
+ loadDbConfig,
57
+ saveDbConfig
58
+ };
@@ -3800,6 +3800,390 @@ var _tsCardTitle = { fontSize: 15, fontWeight: 600, marginBottom: 4, display: 'f
3800
3800
  var _tsCardDesc = { fontSize: 12, color: 'var(--text-muted)', marginBottom: 16 };
3801
3801
  var _tsToggleRow = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 };
3802
3802
  var _tsGrid = { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 };
3803
+ // --- EmailSection -------------------------------------------------------
3804
+
3805
+ function EmailSection(props) {
3806
+ var agentId = props.agentId;
3807
+ var engineAgent = props.engineAgent || {};
3808
+ var reload = props.reload;
3809
+
3810
+ var app = useApp();
3811
+ var toast = app.toast;
3812
+
3813
+ var _config = useState(null);
3814
+ var emailConfig = _config[0]; var setEmailConfig = _config[1];
3815
+ var _loading = useState(true);
3816
+ var loading = _loading[0]; var setLoading = _loading[1];
3817
+ var _testing = useState(false);
3818
+ var testing = _testing[0]; var setTesting = _testing[1];
3819
+ var _testResult = useState(null);
3820
+ var testResult = _testResult[0]; var setTestResult = _testResult[1];
3821
+ var _saving = useState(false);
3822
+ var saving = _saving[0]; var setSaving = _saving[1];
3823
+ var _showOauthHelp = useState(false);
3824
+ var showOauthHelp = _showOauthHelp[0]; var setShowOauthHelp = _showOauthHelp[1];
3825
+
3826
+ // Form state
3827
+ var _form = useState({
3828
+ provider: 'imap',
3829
+ preset: '',
3830
+ email: '',
3831
+ password: '',
3832
+ imapHost: '',
3833
+ imapPort: 993,
3834
+ smtpHost: '',
3835
+ smtpPort: 587,
3836
+ oauthClientId: '',
3837
+ oauthClientSecret: '',
3838
+ oauthTenantId: 'common',
3839
+ });
3840
+ var form = _form[0]; var setForm = _form[1];
3841
+
3842
+ function set(key, val) {
3843
+ setForm(function(prev) { var n = Object.assign({}, prev); n[key] = val; return n; });
3844
+ }
3845
+
3846
+ // Load current config
3847
+ function loadConfig() {
3848
+ setLoading(true);
3849
+ engineCall('/bridge/agents/' + agentId + '/email-config')
3850
+ .then(function(d) {
3851
+ setEmailConfig(d);
3852
+ if (d.configured) {
3853
+ setForm(function(prev) { return Object.assign({}, prev, {
3854
+ provider: d.provider || 'imap',
3855
+ email: d.email || '',
3856
+ imapHost: d.imapHost || '',
3857
+ imapPort: d.imapPort || 993,
3858
+ smtpHost: d.smtpHost || '',
3859
+ smtpPort: d.smtpPort || 587,
3860
+ oauthClientId: d.oauthClientId || '',
3861
+ oauthTenantId: d.oauthTenantId || 'common',
3862
+ }); });
3863
+ } else {
3864
+ // Pre-fill email from agent identity
3865
+ var identity = (engineAgent.config || {}).identity || {};
3866
+ var agentEmail = identity.email || (engineAgent.config || {}).email || '';
3867
+ if (agentEmail && agentEmail.indexOf('@agenticmail.local') === -1) {
3868
+ set('email', agentEmail);
3869
+ }
3870
+ }
3871
+ setLoading(false);
3872
+ })
3873
+ .catch(function() { setLoading(false); });
3874
+ }
3875
+
3876
+ useEffect(function() { loadConfig(); }, [agentId]);
3877
+
3878
+ // Preset changed → auto-fill hosts
3879
+ var PRESETS = {
3880
+ microsoft365: { label: 'Microsoft 365 / Outlook', imapHost: 'outlook.office365.com', imapPort: 993, smtpHost: 'smtp.office365.com', smtpPort: 587 },
3881
+ gmail: { label: 'Google Workspace / Gmail', imapHost: 'imap.gmail.com', imapPort: 993, smtpHost: 'smtp.gmail.com', smtpPort: 587 },
3882
+ yahoo: { label: 'Yahoo Mail', imapHost: 'imap.mail.yahoo.com', imapPort: 993, smtpHost: 'smtp.mail.yahoo.com', smtpPort: 465 },
3883
+ zoho: { label: 'Zoho Mail', imapHost: 'imap.zoho.com', imapPort: 993, smtpHost: 'smtp.zoho.com', smtpPort: 587 },
3884
+ fastmail: { label: 'Fastmail', imapHost: 'imap.fastmail.com', imapPort: 993, smtpHost: 'smtp.fastmail.com', smtpPort: 587 },
3885
+ custom: { label: 'Custom IMAP/SMTP', imapHost: '', imapPort: 993, smtpHost: '', smtpPort: 587 },
3886
+ };
3887
+
3888
+ function applyPreset(key) {
3889
+ var p = PRESETS[key];
3890
+ if (p) {
3891
+ setForm(function(prev) { return Object.assign({}, prev, { preset: key, imapHost: p.imapHost, imapPort: p.imapPort, smtpHost: p.smtpHost, smtpPort: p.smtpPort }); });
3892
+ }
3893
+ }
3894
+
3895
+ // Save
3896
+ async function handleSave() {
3897
+ setSaving(true);
3898
+ try {
3899
+ var body = { provider: form.provider, email: form.email };
3900
+ if (form.provider === 'imap') {
3901
+ Object.assign(body, {
3902
+ password: form.password || undefined,
3903
+ preset: form.preset !== 'custom' ? form.preset : undefined,
3904
+ imapHost: form.imapHost,
3905
+ imapPort: form.imapPort,
3906
+ smtpHost: form.smtpHost,
3907
+ smtpPort: form.smtpPort,
3908
+ });
3909
+ } else if (form.provider === 'microsoft') {
3910
+ var baseUrl = window.location.origin;
3911
+ Object.assign(body, {
3912
+ oauthClientId: form.oauthClientId,
3913
+ oauthClientSecret: form.oauthClientSecret,
3914
+ oauthTenantId: form.oauthTenantId,
3915
+ oauthRedirectUri: baseUrl + '/oauth/callback',
3916
+ });
3917
+ } else if (form.provider === 'google') {
3918
+ var gBaseUrl = window.location.origin;
3919
+ Object.assign(body, {
3920
+ oauthClientId: form.oauthClientId,
3921
+ oauthClientSecret: form.oauthClientSecret,
3922
+ oauthRedirectUri: gBaseUrl + '/oauth/callback',
3923
+ });
3924
+ }
3925
+
3926
+ var result = await engineCall('/bridge/agents/' + agentId + '/email-config', {
3927
+ method: 'PUT',
3928
+ body: JSON.stringify(body),
3929
+ });
3930
+
3931
+ if (result.emailConfig && result.emailConfig.oauthAuthUrl) {
3932
+ toast('OAuth configured — click "Authorize" to complete setup', 'info');
3933
+ } else {
3934
+ toast('Email configuration saved', 'success');
3935
+ }
3936
+ loadConfig();
3937
+ if (reload) reload();
3938
+ } catch (err) {
3939
+ toast(err.message, 'error');
3940
+ }
3941
+ setSaving(false);
3942
+ }
3943
+
3944
+ // Test connection
3945
+ async function handleTest() {
3946
+ setTesting(true);
3947
+ setTestResult(null);
3948
+ try {
3949
+ var result = await engineCall('/bridge/agents/' + agentId + '/email-config/test', { method: 'POST' });
3950
+ setTestResult(result);
3951
+ if (result.success) toast('Connection successful!', 'success');
3952
+ else toast('Connection failed: ' + (result.error || 'Unknown error'), 'error');
3953
+ } catch (err) {
3954
+ setTestResult({ success: false, error: err.message });
3955
+ toast('Test failed: ' + err.message, 'error');
3956
+ }
3957
+ setTesting(false);
3958
+ }
3959
+
3960
+ // Disconnect
3961
+ async function handleDisconnect() {
3962
+ try {
3963
+ await engineCall('/bridge/agents/' + agentId + '/email-config', { method: 'DELETE' });
3964
+ toast('Email disconnected', 'success');
3965
+ setEmailConfig(null);
3966
+ setTestResult(null);
3967
+ loadConfig();
3968
+ if (reload) reload();
3969
+ } catch (err) {
3970
+ toast(err.message, 'error');
3971
+ }
3972
+ }
3973
+
3974
+ // Open OAuth window
3975
+ function openOAuth() {
3976
+ if (emailConfig && emailConfig.oauthAuthUrl) {
3977
+ window.open(emailConfig.oauthAuthUrl, '_blank', 'width=600,height=700');
3978
+ }
3979
+ }
3980
+
3981
+ if (loading) return h('div', { className: 'card', style: { padding: 40, textAlign: 'center' } }, 'Loading email config...');
3982
+
3983
+ var statusBadge = !emailConfig || !emailConfig.configured
3984
+ ? h('span', { className: 'badge badge-neutral' }, 'Not Connected')
3985
+ : emailConfig.status === 'connected'
3986
+ ? h('span', { className: 'badge badge-success' }, 'Connected')
3987
+ : emailConfig.status === 'configured'
3988
+ ? h('span', { className: 'badge badge-info' }, 'Configured')
3989
+ : emailConfig.status === 'awaiting_oauth'
3990
+ ? h('span', { className: 'badge badge-warning' }, 'Awaiting Authorization')
3991
+ : emailConfig.status === 'error'
3992
+ ? h('span', { className: 'badge badge-danger' }, 'Error')
3993
+ : h('span', { className: 'badge badge-neutral' }, emailConfig.status || 'Unknown');
3994
+
3995
+ var labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, marginBottom: 4, color: 'var(--text-secondary)' };
3996
+ var inputStyle = { width: '100%', padding: '8px 10px', borderRadius: 'var(--radius)', border: '1px solid var(--border)', background: 'var(--bg-primary)', fontSize: 13, fontFamily: 'inherit' };
3997
+ var helpStyle = { fontSize: 11, color: 'var(--text-muted)', margin: '4px 0 0' };
3998
+
3999
+ return h('div', { className: 'card' },
4000
+ h('div', { className: 'card-header', style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' } },
4001
+ h('div', null,
4002
+ h('h3', { className: 'card-title' }, 'Email Connection'),
4003
+ h('p', { style: { fontSize: 12, color: 'var(--text-muted)', margin: '2px 0 0' } }, 'Connect this agent to an email account so it can send and receive emails.')
4004
+ ),
4005
+ statusBadge
4006
+ ),
4007
+ h('div', { className: 'card-body' },
4008
+
4009
+ // ─── Provider Selection ─────────────────────────
4010
+ h('div', { style: { marginBottom: 20 } },
4011
+ h('label', { style: labelStyle }, 'Connection Method'),
4012
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 } },
4013
+ [
4014
+ { id: 'imap', label: 'Email + Password', desc: 'IMAP/SMTP — works with any email provider', icon: '📧' },
4015
+ { id: 'microsoft', label: 'Microsoft OAuth', desc: 'Azure AD / Entra ID — for M365 orgs', icon: '🏢' },
4016
+ { id: 'google', label: 'Google OAuth', desc: 'Google Workspace — for GWS orgs', icon: '🔵' },
4017
+ ].map(function(m) {
4018
+ var selected = form.provider === m.id;
4019
+ return h('div', {
4020
+ key: m.id,
4021
+ onClick: function() { set('provider', m.id); },
4022
+ style: {
4023
+ padding: '14px 16px', borderRadius: 'var(--radius-lg)',
4024
+ border: selected ? '2px solid var(--accent)' : '1px solid var(--border)',
4025
+ background: selected ? 'var(--accent-soft)' : 'var(--bg-secondary)',
4026
+ cursor: 'pointer', transition: 'all 0.15s',
4027
+ }
4028
+ },
4029
+ h('div', { style: { fontSize: 20, marginBottom: 4 } }, m.icon),
4030
+ h('div', { style: { fontWeight: 600, fontSize: 13, marginBottom: 2 } }, m.label),
4031
+ h('div', { style: { fontSize: 11, color: 'var(--text-muted)' } }, m.desc)
4032
+ );
4033
+ })
4034
+ )
4035
+ ),
4036
+
4037
+ // ─── IMAP/SMTP Config ───────────────────────────
4038
+ form.provider === 'imap' && h(Fragment, null,
4039
+ h('div', { style: { marginBottom: 16 } },
4040
+ h('label', { style: labelStyle }, 'Email Provider'),
4041
+ h('select', { style: inputStyle, value: form.preset, onChange: function(e) { applyPreset(e.target.value); } },
4042
+ h('option', { value: '' }, '-- Select your email provider --'),
4043
+ Object.entries(PRESETS).map(function(entry) {
4044
+ return h('option', { key: entry[0], value: entry[0] }, entry[1].label);
4045
+ })
4046
+ )
4047
+ ),
4048
+
4049
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 } },
4050
+ h('div', null,
4051
+ h('label', { style: labelStyle }, 'Email Address *'),
4052
+ h('input', { style: inputStyle, type: 'email', value: form.email, placeholder: 'agent@company.com', onChange: function(e) { set('email', e.target.value); } }),
4053
+ h('p', { style: helpStyle }, 'The email address created for this agent in your email system')
4054
+ ),
4055
+ h('div', null,
4056
+ h('label', { style: labelStyle }, form.password ? 'App Password *' : 'App Password * (enter to set/update)'),
4057
+ h('input', { style: inputStyle, type: 'password', value: form.password, placeholder: emailConfig && emailConfig.configured ? '•••••••• (leave blank to keep current)' : 'Enter app password', onChange: function(e) { set('password', e.target.value); } }),
4058
+ h('p', { style: helpStyle }, 'For Microsoft 365: ', h('a', { href: 'https://mysignins.microsoft.com/security-info', target: '_blank', style: { color: 'var(--accent)' } }, 'Create app password'), ' | For Gmail: ', h('a', { href: 'https://myaccount.google.com/apppasswords', target: '_blank', style: { color: 'var(--accent)' } }, 'Create app password'))
4059
+ )
4060
+ ),
4061
+
4062
+ // Server settings (auto-filled by preset, expandable for custom)
4063
+ (form.preset === 'custom' || form.preset === '') && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr auto 1fr auto', gap: 12, marginBottom: 16 } },
4064
+ h('div', null,
4065
+ h('label', { style: labelStyle }, 'IMAP Host *'),
4066
+ h('input', { style: inputStyle, value: form.imapHost, placeholder: 'imap.example.com', onChange: function(e) { set('imapHost', e.target.value); } })
4067
+ ),
4068
+ h('div', { style: { width: 80 } },
4069
+ h('label', { style: labelStyle }, 'Port'),
4070
+ h('input', { style: inputStyle, type: 'number', value: form.imapPort, onChange: function(e) { set('imapPort', parseInt(e.target.value) || 993); } })
4071
+ ),
4072
+ h('div', null,
4073
+ h('label', { style: labelStyle }, 'SMTP Host *'),
4074
+ h('input', { style: inputStyle, value: form.smtpHost, placeholder: 'smtp.example.com', onChange: function(e) { set('smtpHost', e.target.value); } })
4075
+ ),
4076
+ h('div', { style: { width: 80 } },
4077
+ h('label', { style: labelStyle }, 'Port'),
4078
+ h('input', { style: inputStyle, type: 'number', value: form.smtpPort, onChange: function(e) { set('smtpPort', parseInt(e.target.value) || 587); } })
4079
+ )
4080
+ ),
4081
+
4082
+ form.preset && form.preset !== 'custom' && form.preset !== '' && h('div', { style: { padding: '8px 12px', background: 'var(--bg-secondary)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--text-muted)', marginBottom: 16 } },
4083
+ 'Server: ', h('strong', null, form.imapHost), ':', form.imapPort, ' (IMAP) / ', h('strong', null, form.smtpHost), ':', form.smtpPort, ' (SMTP)',
4084
+ ' — ', h('a', { href: '#', onClick: function(e) { e.preventDefault(); set('preset', 'custom'); }, style: { color: 'var(--accent)' } }, 'Edit manually')
4085
+ ),
4086
+
4087
+ h('div', { style: { padding: '12px 16px', background: 'var(--info-soft)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--info)', marginBottom: 16 } },
4088
+ h('strong', null, 'How to set up:'), h('br'),
4089
+ '1. Create an email account for this agent in your email system (e.g., Microsoft 365 Admin Center or Google Admin Console)', h('br'),
4090
+ '2. Create an app password for that account (regular passwords may not work with 2FA enabled)', h('br'),
4091
+ '3. Enter the email and app password above, select your provider, and hit Save', h('br'),
4092
+ '4. Click "Test Connection" to verify everything works'
4093
+ )
4094
+ ),
4095
+
4096
+ // ─── Microsoft OAuth Config ─────────────────────
4097
+ form.provider === 'microsoft' && h(Fragment, null,
4098
+ h('div', { style: { padding: '12px 16px', background: 'var(--info-soft)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--info)', marginBottom: 16 } },
4099
+ h('strong', null, 'Setup Instructions:'), h('br'),
4100
+ '1. Go to ', h('a', { href: 'https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade', target: '_blank', style: { color: 'var(--accent)' } }, 'Azure Portal → App Registrations'), h('br'),
4101
+ '2. Click "New Registration" → name it (e.g., "AgenticMail Agent") → set redirect URI to: ', h('code', { style: { background: 'var(--bg-tertiary)', padding: '1px 4px', borderRadius: 3 } }, window.location.origin + '/oauth/callback'), h('br'),
4102
+ '3. Under "Certificates & Secrets" → create a Client Secret', h('br'),
4103
+ '4. Under "API Permissions" → add Microsoft Graph: Mail.ReadWrite, Mail.Send, offline_access', h('br'),
4104
+ '5. Copy the Application (client) ID and Client Secret below'
4105
+ ),
4106
+
4107
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 } },
4108
+ h('div', null,
4109
+ h('label', { style: labelStyle }, 'Application (Client) ID *'),
4110
+ h('input', { style: inputStyle, value: form.oauthClientId, placeholder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', onChange: function(e) { set('oauthClientId', e.target.value); } })
4111
+ ),
4112
+ h('div', null,
4113
+ h('label', { style: labelStyle }, 'Client Secret *'),
4114
+ h('input', { style: inputStyle, type: 'password', value: form.oauthClientSecret, placeholder: 'Enter client secret', onChange: function(e) { set('oauthClientSecret', e.target.value); } })
4115
+ )
4116
+ ),
4117
+ h('div', { style: { marginBottom: 16 } },
4118
+ h('label', { style: labelStyle }, 'Tenant ID'),
4119
+ h('input', { style: Object.assign({}, inputStyle, { maxWidth: 400 }), value: form.oauthTenantId, placeholder: 'common (or your tenant ID)', onChange: function(e) { set('oauthTenantId', e.target.value); } }),
4120
+ h('p', { style: helpStyle }, 'Use "common" for multi-tenant, or your org\'s tenant ID for single-tenant apps')
4121
+ ),
4122
+
4123
+ emailConfig && emailConfig.status === 'awaiting_oauth' && h('div', { style: { padding: '12px 16px', background: 'var(--warning-soft)', borderRadius: 'var(--radius)', marginBottom: 16 } },
4124
+ h('div', { style: { fontWeight: 600, marginBottom: 4, fontSize: 13 } }, 'Authorization Required'),
4125
+ h('p', { style: { fontSize: 12, margin: '0 0 8px', color: 'var(--text-secondary)' } }, 'Click the button below to sign in with the agent\'s Microsoft account and grant email permissions.'),
4126
+ h('button', { className: 'btn btn-primary btn-sm', onClick: openOAuth }, 'Authorize with Microsoft')
4127
+ )
4128
+ ),
4129
+
4130
+ // ─── Google OAuth Config ────────────────────────
4131
+ form.provider === 'google' && h(Fragment, null,
4132
+ h('div', { style: { padding: '12px 16px', background: 'var(--info-soft)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--info)', marginBottom: 16 } },
4133
+ h('strong', null, 'Setup Instructions:'), h('br'),
4134
+ '1. Go to ', h('a', { href: 'https://console.cloud.google.com/apis/credentials', target: '_blank', style: { color: 'var(--accent)' } }, 'Google Cloud Console → Credentials'), h('br'),
4135
+ '2. Create an OAuth 2.0 Client ID (Web application) → add redirect URI: ', h('code', { style: { background: 'var(--bg-tertiary)', padding: '1px 4px', borderRadius: 3 } }, window.location.origin + '/oauth/callback'), h('br'),
4136
+ '3. Enable the Gmail API in your project', h('br'),
4137
+ '4. Copy the Client ID and Client Secret below'
4138
+ ),
4139
+
4140
+ h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 } },
4141
+ h('div', null,
4142
+ h('label', { style: labelStyle }, 'OAuth Client ID *'),
4143
+ h('input', { style: inputStyle, value: form.oauthClientId, placeholder: 'xxxx.apps.googleusercontent.com', onChange: function(e) { set('oauthClientId', e.target.value); } })
4144
+ ),
4145
+ h('div', null,
4146
+ h('label', { style: labelStyle }, 'Client Secret *'),
4147
+ h('input', { style: inputStyle, type: 'password', value: form.oauthClientSecret, placeholder: 'Enter client secret', onChange: function(e) { set('oauthClientSecret', e.target.value); } })
4148
+ )
4149
+ ),
4150
+
4151
+ emailConfig && emailConfig.status === 'awaiting_oauth' && h('div', { style: { padding: '12px 16px', background: 'var(--warning-soft)', borderRadius: 'var(--radius)', marginBottom: 16 } },
4152
+ h('div', { style: { fontWeight: 600, marginBottom: 4, fontSize: 13 } }, 'Authorization Required'),
4153
+ h('p', { style: { fontSize: 12, margin: '0 0 8px', color: 'var(--text-secondary)' } }, 'Click the button below to sign in with the agent\'s Google account and grant Gmail permissions.'),
4154
+ h('button', { className: 'btn btn-primary btn-sm', onClick: openOAuth }, 'Authorize with Google')
4155
+ )
4156
+ ),
4157
+
4158
+ // ─── Test Result ─────────────────────────────────
4159
+ testResult && h('div', { style: { padding: '12px 16px', borderRadius: 'var(--radius)', marginBottom: 16, background: testResult.success ? 'var(--success-soft)' : 'var(--danger-soft)' } },
4160
+ testResult.success
4161
+ ? h(Fragment, null,
4162
+ h('div', { style: { fontWeight: 600, color: 'var(--success)', marginBottom: 4, fontSize: 13 } }, 'Connection Successful'),
4163
+ testResult.inbox && h('div', { style: { fontSize: 12, color: 'var(--text-secondary)' } }, 'Inbox: ', testResult.inbox.total, ' messages (', testResult.inbox.unread, ' unread)'),
4164
+ testResult.email && h('div', { style: { fontSize: 12, color: 'var(--text-secondary)' } }, 'Email: ', testResult.email)
4165
+ )
4166
+ : h(Fragment, null,
4167
+ h('div', { style: { fontWeight: 600, color: 'var(--danger)', marginBottom: 4, fontSize: 13 } }, 'Connection Failed'),
4168
+ h('div', { style: { fontSize: 12, color: 'var(--text-secondary)' } }, testResult.error || 'Unknown error')
4169
+ )
4170
+ ),
4171
+
4172
+ // ─── Error display ────────────────────────────────
4173
+ emailConfig && emailConfig.lastError && h('div', { style: { padding: '8px 12px', background: 'var(--danger-soft)', borderRadius: 'var(--radius)', fontSize: 12, color: 'var(--danger)', marginBottom: 16 } },
4174
+ h('strong', null, 'Last Error: '), emailConfig.lastError
4175
+ ),
4176
+
4177
+ // ─── Actions ──────────────────────────────────────
4178
+ h('div', { style: { display: 'flex', gap: 8, borderTop: '1px solid var(--border)', paddingTop: 16 } },
4179
+ h('button', { className: 'btn btn-primary', disabled: saving, onClick: handleSave }, saving ? 'Saving...' : 'Save Configuration'),
4180
+ emailConfig && emailConfig.configured && h('button', { className: 'btn btn-secondary', disabled: testing, onClick: handleTest }, testing ? 'Testing...' : 'Test Connection'),
4181
+ emailConfig && emailConfig.configured && h('button', { className: 'btn btn-danger btn-ghost', onClick: function() { if (confirm('Disconnect email? The agent will no longer be able to send/receive.')) handleDisconnect(); } }, 'Disconnect')
4182
+ )
4183
+ )
4184
+ );
4185
+ }
4186
+
3803
4187
  var _tsSectionTitle = { fontSize: 14, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 12, marginTop: 8 };
3804
4188
 
3805
4189
  function TSToggle(props) {
@@ -4166,8 +4550,8 @@ function AgentDetailPage(props) {
4166
4550
  var _agents = useState([]);
4167
4551
  var agents = _agents[0]; var setAgents = _agents[1];
4168
4552
 
4169
- var TABS = ['overview', 'personal', 'configuration', 'manager', 'skills', 'permissions', 'activity', 'communication', 'workforce', 'memory', 'guardrails', 'budget', 'tool-security', 'deployment'];
4170
- var TAB_LABELS = { 'tool-security': 'Tool Security', 'manager': 'Manager & Catch-Up' };
4553
+ var TABS = ['overview', 'personal', 'email', 'configuration', 'manager', 'skills', 'permissions', 'activity', 'communication', 'workforce', 'memory', 'guardrails', 'budget', 'tool-security', 'deployment'];
4554
+ var TAB_LABELS = { 'tool-security': 'Tool Security', 'manager': 'Manager & Catch-Up', 'email': 'Email' };
4171
4555
 
4172
4556
  var load = function() {
4173
4557
  setLoading(true);
@@ -4288,6 +4672,7 @@ function AgentDetailPage(props) {
4288
4672
  // ─── Tab Content ────────────────────────────────────
4289
4673
  tab === 'overview' && h(OverviewSection, { agentId: agentId, agent: agent, engineAgent: engineAgent, profile: profile, reload: load, agents: agents, onBack: onBack }),
4290
4674
  tab === 'personal' && h(PersonalDetailsSection, { agentId: agentId, agent: agent, engineAgent: engineAgent, reload: load }),
4675
+ tab === 'email' && h(EmailSection, { agentId: agentId, engineAgent: engineAgent, reload: load }),
4291
4676
  tab === 'configuration' && h(ConfigurationSection, { agentId: agentId, engineAgent: engineAgent, reload: load }),
4292
4677
  tab === 'manager' && h(ManagerCatchUpSection, { agentId: agentId, engineAgent: engineAgent, agents: agents, reload: load }),
4293
4678
  tab === 'skills' && h(SkillsSection, { agentId: agentId, engineAgent: engineAgent, reload: load }),
@@ -764,7 +764,7 @@ export function CreateAgentWizard({ onClose, onCreated, toast }) {
764
764
  h('div', { className: 'form-group' },
765
765
  h('label', { className: 'form-label' }, 'Email Address'),
766
766
  h('input', { className: 'input', value: form.email, onChange: e => set('email', e.target.value), placeholder: form.name ? form.name.toLowerCase().replace(/\s+/g, '.') + '@yourdomain.com' : 'first.last@yourdomain.com' }),
767
- h('p', { className: 'form-help' }, 'Leave blank for auto-generated from their name')
767
+ h('p', { className: 'form-help' }, 'The email address created for this agent in your email system. Configure credentials in the Email tab after creation.')
768
768
  )
769
769
  ),
770
770
  h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 } },
@@ -0,0 +1,7 @@
1
+ import {
2
+ EngineDatabase
3
+ } from "./chunk-5DDNXWPN.js";
4
+ import "./chunk-GI5RMYH6.js";
5
+ export {
6
+ EngineDatabase
7
+ };
@@ -0,0 +1,7 @@
1
+ import {
2
+ DomainLock
3
+ } from "./chunk-UPU23ZRG.js";
4
+ import "./chunk-GI5RMYH6.js";
5
+ export {
6
+ DomainLock
7
+ };