@agenticmail/enterprise 0.5.92 → 0.5.94

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.
@@ -0,0 +1,49 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-ACYJBORO.js";
18
+ import "./chunk-NRF3YRF7.js";
19
+ import "./chunk-TYW5XTOW.js";
20
+ import "./chunk-AQH4DFYV.js";
21
+ import "./chunk-JLSQOQ5L.js";
22
+ import {
23
+ PROVIDER_REGISTRY,
24
+ listAllProviders,
25
+ resolveApiKeyForProvider,
26
+ resolveProvider
27
+ } from "./chunk-67KZYSLU.js";
28
+ import "./chunk-KFQGP6VL.js";
29
+ export {
30
+ AgentRuntime,
31
+ EmailChannel,
32
+ FollowUpScheduler,
33
+ PROVIDER_REGISTRY,
34
+ SessionManager,
35
+ SubAgentManager,
36
+ ToolRegistry,
37
+ callLLM,
38
+ createAgentRuntime,
39
+ createNoopHooks,
40
+ createRuntimeHooks,
41
+ estimateMessageTokens,
42
+ estimateTokens,
43
+ executeTool,
44
+ listAllProviders,
45
+ resolveApiKeyForProvider,
46
+ resolveProvider,
47
+ runAgentLoop,
48
+ toolsToDefinitions
49
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-D32BZJ7N.js";
4
+ import "./chunk-3SMTCIR4.js";
5
+ import "./chunk-JLSQOQ5L.js";
6
+ import "./chunk-RO537U6H.js";
7
+ import "./chunk-DRXMYYKN.js";
8
+ import "./chunk-67KZYSLU.js";
9
+ import "./chunk-KFQGP6VL.js";
10
+ export {
11
+ createServer
12
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-RKF2TYZA.js";
10
+ import "./chunk-QDXUZP7Y.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.92",
3
+ "version": "0.5.94",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -298,29 +298,36 @@ function OverviewSection(props) {
298
298
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 } },
299
299
  onboardingStatus?.onboarded
300
300
  ? h('span', { className: 'badge badge-success' }, I.check(), ' Onboarded')
301
- : onboardingStatus?.status === 'in_progress'
302
- ? h('span', { className: 'badge badge-info' }, I.clock(), ' In Progress')
301
+ : onboardingStatus?.totalPolicies > 0
302
+ ? h('span', { className: 'badge badge-info' }, I.clock(), ' In Progress (' + (onboardingStatus.acknowledgedPolicies || 0) + '/' + onboardingStatus.totalPolicies + ')')
303
303
  : h('span', { className: 'badge badge-warning' }, 'Not Onboarded')
304
304
  ),
305
- onboardingStatus?.status === 'in_progress' && h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginBottom: 8 } },
306
- 'Policies: ' + (onboardingStatus.acknowledgedPolicies || 0) + '/' + (onboardingStatus.totalPolicies || 0) + ' acknowledged'
305
+ onboardingStatus?.totalPolicies > 0 && !onboardingStatus?.onboarded && h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginBottom: 4 } },
306
+ 'Agent will complete onboarding automatically on first run.'
307
307
  ),
308
- !onboardingStatus?.onboarded && onboardingStatus?.status !== 'in_progress' && h('button', {
309
- className: 'btn btn-primary btn-sm',
310
- disabled: acting === 'onboard',
311
- onClick: initiateOnboarding
312
- }, acting === 'onboard' ? 'Starting...' : 'Start Onboarding'),
313
- onboardingStatus?.status === 'in_progress' && h('button', {
314
- className: 'btn btn-ghost btn-sm', style: { marginTop: 4 },
315
- disabled: acting === 'forceComplete',
316
- onClick: function() {
317
- setActing('forceComplete');
318
- engineCall('/onboarding/force-complete/' + agentId, { method: 'POST', body: JSON.stringify({ adminId: 'admin' }) })
319
- .then(function() { toast('Onboarding force-completed', 'success'); reload(); })
320
- .catch(function(err) { toast(err.message, 'error'); })
321
- .finally(function() { setActing(null); });
322
- }
323
- }, acting === 'forceComplete' ? 'Completing...' : 'Force Complete')
308
+ !onboardingStatus?.onboarded && h('div', { style: { display: 'flex', gap: 8, marginTop: 8 } },
309
+ !onboardingStatus?.totalPolicies && h('button', {
310
+ className: 'btn btn-primary btn-sm',
311
+ disabled: acting === 'onboard',
312
+ onClick: initiateOnboarding
313
+ }, acting === 'onboard' ? 'Starting...' : 'Start Onboarding'),
314
+ h('button', {
315
+ className: 'btn btn-ghost btn-sm',
316
+ disabled: acting === 'forceComplete',
317
+ onClick: function() {
318
+ setActing('forceComplete');
319
+ var initFirst = !onboardingStatus?.totalPolicies
320
+ ? engineCall('/onboarding/initiate/' + agentId, { method: 'POST', body: JSON.stringify({ orgId: getOrgId() }) })
321
+ : Promise.resolve();
322
+ initFirst.then(function() {
323
+ return engineCall('/onboarding/force-complete/' + agentId, { method: 'POST', body: JSON.stringify({ adminId: 'admin' }) });
324
+ })
325
+ .then(function() { toast('Onboarding completed', 'success'); reload(); })
326
+ .catch(function(err) { toast(err.message, 'error'); })
327
+ .finally(function() { setActing(null); });
328
+ }
329
+ }, acting === 'forceComplete' ? 'Completing...' : 'Skip — Force Complete')
330
+ )
324
331
  )
325
332
  ),
326
333
 
@@ -3739,35 +3746,36 @@ function DeploymentSection(props) {
3739
3746
 
3740
3747
  var startDeployEdit = function() {
3741
3748
  setDeployForm({
3742
- target: deployment.target || 'docker',
3743
- region: deployment.region || 'iad',
3749
+ target: deployment.target || 'fly',
3750
+ region: deployment.region || deployment.config?.cloud?.region || 'iad',
3744
3751
  imageTag: (deployment.config?.docker?.tag) || deployment.imageTag || 'latest',
3745
3752
  memory: (deployment.config?.docker?.memory) || deployment.memory || '512m',
3746
3753
  cpu: (deployment.config?.docker?.cpu) || deployment.cpu || '0.5',
3747
3754
  ports: (deployment.config?.docker?.ports || [3000]).join(', '),
3755
+ flyApiToken: deployment.config?.cloud?.apiToken || '',
3756
+ flyAppName: deployment.config?.cloud?.appName || '',
3757
+ vpsHost: deployment.config?.vps?.host || '',
3758
+ vpsUser: deployment.config?.vps?.user || 'root',
3759
+ vpsKeyPath: deployment.config?.vps?.keyPath || '',
3748
3760
  });
3749
3761
  setEditingDeploy(true);
3750
3762
  };
3751
3763
 
3752
3764
  var saveDeploy = function() {
3753
3765
  setSavingDeploy(true);
3766
+ var deployConfig = {};
3767
+ if (deployForm.target === 'fly') {
3768
+ deployConfig = { cloud: { provider: 'fly', region: deployForm.region || 'iad', apiToken: deployForm.flyApiToken || undefined, appName: deployForm.flyAppName || undefined } };
3769
+ } else if (deployForm.target === 'docker') {
3770
+ deployConfig = { docker: { image: 'agenticmail/agent', tag: deployForm.imageTag, ports: deployForm.ports.split(',').map(function(p) { return parseInt(p.trim()) || 3000; }), memory: deployForm.memory, cpu: deployForm.cpu, restart: 'unless-stopped' } };
3771
+ } else if (deployForm.target === 'vps') {
3772
+ deployConfig = { vps: { host: deployForm.vpsHost || '', user: deployForm.vpsUser || 'root', keyPath: deployForm.vpsKeyPath || '' } };
3773
+ }
3754
3774
  var updates = {
3755
3775
  deployment: {
3756
3776
  target: deployForm.target,
3757
3777
  region: deployForm.region,
3758
- imageTag: deployForm.imageTag,
3759
- memory: deployForm.memory,
3760
- cpu: deployForm.cpu,
3761
- config: {
3762
- docker: {
3763
- image: 'agenticmail/agent',
3764
- tag: deployForm.imageTag,
3765
- ports: deployForm.ports.split(',').map(function(p) { return parseInt(p.trim()) || 3000; }),
3766
- memory: deployForm.memory,
3767
- cpu: deployForm.cpu,
3768
- restart: 'unless-stopped',
3769
- }
3770
- }
3778
+ config: deployConfig
3771
3779
  }
3772
3780
  };
3773
3781
  var isRunning = ea.state === 'running' || ea.state === 'active' || ea.state === 'degraded';
@@ -3854,7 +3862,18 @@ function DeploymentSection(props) {
3854
3862
  )
3855
3863
  )
3856
3864
  ),
3857
- (deployForm.target === 'docker' || deployForm.target === 'fly') && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 16 } },
3865
+ deployForm.target === 'fly' && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 } },
3866
+ h('div', { className: 'form-group' },
3867
+ h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'Fly.io API Token'),
3868
+ h('input', { className: 'input', type: 'password', value: deployForm.flyApiToken, onChange: function(e) { setDf('flyApiToken', e.target.value); }, placeholder: 'fo1_...' }),
3869
+ h('div', { style: { fontSize: 11, color: 'var(--text-muted)', marginTop: 2 } }, 'From fly.io/user/personal_access_tokens')
3870
+ ),
3871
+ h('div', { className: 'form-group' },
3872
+ h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'App Name (optional)'),
3873
+ h('input', { className: 'input', value: deployForm.flyAppName, onChange: function(e) { setDf('flyAppName', e.target.value); }, placeholder: 'Auto-generated if empty' })
3874
+ )
3875
+ ),
3876
+ deployForm.target === 'docker' && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 16 } },
3858
3877
  h('div', { className: 'form-group' },
3859
3878
  h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'Image Tag'),
3860
3879
  h('input', { className: 'input', value: deployForm.imageTag, onChange: function(e) { setDf('imageTag', e.target.value); } })
@@ -3871,6 +3890,20 @@ function DeploymentSection(props) {
3871
3890
  h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'Ports'),
3872
3891
  h('input', { className: 'input', value: deployForm.ports, onChange: function(e) { setDf('ports', e.target.value); }, placeholder: '3000' })
3873
3892
  )
3893
+ ),
3894
+ deployForm.target === 'vps' && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 } },
3895
+ h('div', { className: 'form-group' },
3896
+ h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'Host'),
3897
+ h('input', { className: 'input', value: deployForm.vpsHost, onChange: function(e) { setDf('vpsHost', e.target.value); }, placeholder: '192.168.1.100' })
3898
+ ),
3899
+ h('div', { className: 'form-group' },
3900
+ h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'User'),
3901
+ h('input', { className: 'input', value: deployForm.vpsUser, onChange: function(e) { setDf('vpsUser', e.target.value); }, placeholder: 'root' })
3902
+ ),
3903
+ h('div', { className: 'form-group' },
3904
+ h('label', { style: { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 } }, 'SSH Key Path'),
3905
+ h('input', { className: 'input', value: deployForm.vpsKeyPath, onChange: function(e) { setDf('vpsKeyPath', e.target.value); }, placeholder: '~/.ssh/id_rsa' })
3906
+ )
3874
3907
  )
3875
3908
  )
3876
3909
  ),
@@ -97,6 +97,9 @@ export class DeploymentEngine {
97
97
  case 'railway':
98
98
  result = await this.deployRailway(config, emit);
99
99
  break;
100
+ case 'local':
101
+ result = await this.deployLocal(config, emit);
102
+ break;
100
103
  default:
101
104
  throw new Error(`Unsupported deployment target: ${config.deployment.target}`);
102
105
  }
@@ -124,6 +127,8 @@ export class DeploymentEngine {
124
127
  return this.execSSH(config, `sudo systemctl stop agenticmail-${config.name}`);
125
128
  case 'fly':
126
129
  return this.execCommand(`fly apps destroy agenticmail-${config.name} --yes`);
130
+ case 'local':
131
+ return { success: true, message: 'Local agent stopped' };
127
132
  default:
128
133
  return { success: false, message: `Cannot stop: unsupported target ${config.deployment.target}` };
129
134
  }
@@ -140,6 +145,8 @@ export class DeploymentEngine {
140
145
  return this.execSSH(config, `sudo systemctl restart agenticmail-${config.name}`);
141
146
  case 'fly':
142
147
  return this.execCommand(`fly apps restart agenticmail-${config.name}`);
148
+ case 'local':
149
+ return { success: true, message: 'Local agent restarted' };
143
150
  default:
144
151
  return { success: false, message: `Cannot restart: unsupported target ${config.deployment.target}` };
145
152
  }
@@ -164,6 +171,8 @@ export class DeploymentEngine {
164
171
  return await this.getVPSStatus(config, base);
165
172
  case 'fly':
166
173
  return await this.getCloudStatus(config, base);
174
+ case 'local':
175
+ return { ...base, status: 'running', healthStatus: 'healthy', uptime: Math.floor((Date.now() - new Date(config.deployment?.config?.deployedAt || Date.now()).getTime()) / 1000) };
167
176
  default:
168
177
  return base;
169
178
  }
@@ -346,6 +355,33 @@ export class DeploymentEngine {
346
355
 
347
356
  // ─── Fly.io Deployment ────────────────────────────────
348
357
 
358
+ /**
359
+ * Local/in-process deployment — agent runs within the same enterprise server.
360
+ * No container or VM needed. Just mark as running.
361
+ */
362
+ private async deployLocal(config: AgentConfig, emit: (phase: string, status: string, msg: string) => void): Promise<DeploymentResult> {
363
+ emit('provision', 'started', 'Preparing local agent runtime...');
364
+ emit('provision', 'completed', 'Local runtime ready');
365
+
366
+ emit('configure', 'started', 'Applying agent configuration...');
367
+ emit('configure', 'completed', 'Configuration applied');
368
+
369
+ emit('start', 'started', 'Starting agent...');
370
+ // Agent runs in-process — nothing to actually spin up externally
371
+ emit('start', 'completed', 'Agent started in local runtime');
372
+
373
+ emit('healthcheck', 'started', 'Running health check...');
374
+ emit('healthcheck', 'completed', 'Agent is healthy');
375
+
376
+ emit('complete', 'completed', 'Local deployment successful');
377
+
378
+ return {
379
+ success: true,
380
+ url: undefined,
381
+ events: [],
382
+ };
383
+ }
384
+
349
385
  private async deployFly(config: AgentConfig, emit: Function): Promise<DeploymentResult> {
350
386
  const cloud = config.deployment.config.cloud;
351
387
  if (!cloud || cloud.provider !== 'fly') throw new Error('Fly.io config missing');
@@ -325,6 +325,7 @@ export class AgentLifecycleManager {
325
325
  if (healthy) {
326
326
  this.transition(agent, 'running', 'Agent is healthy and running', 'system');
327
327
  this.emitEvent(agent, 'started', { deployedBy });
328
+ this.emitEvent(agent, 'onboarding_required', { message: 'Agent should complete onboarding: read org policies, acknowledge each, and internalize knowledge.' });
328
329
  this.startHealthCheckLoop(agent);
329
330
  } else {
330
331
  this.transition(agent, 'degraded', 'Agent started but health check failed', 'system');