@agenticmail/enterprise 0.5.78 → 0.5.79

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 (95) hide show
  1. package/dist/chunk-7RNT4O5T.js +15198 -0
  2. package/dist/chunk-AGFOJCSB.js +2191 -0
  3. package/dist/chunk-F4GSFCM3.js +898 -0
  4. package/dist/chunk-PZA7YOJE.js +898 -0
  5. package/dist/chunk-Q3V7VZFQ.js +2191 -0
  6. package/dist/chunk-RRFB6G6M.js +15198 -0
  7. package/dist/chunk-VX3VFMVB.js +409 -0
  8. package/dist/cli.js +1 -1
  9. package/dist/dashboard/pages/agent-detail.js +313 -1
  10. package/dist/index.js +4 -3
  11. package/dist/pw-ai-KPETTB25.js +2212 -0
  12. package/dist/routes-PDHMCIXU.js +6676 -0
  13. package/dist/runtime-7HW4GX5L.js +48 -0
  14. package/dist/runtime-XXDCZZIK.js +48 -0
  15. package/dist/server-FMP4BFGW.js +12 -0
  16. package/dist/server-JRHDUNII.js +12 -0
  17. package/dist/setup-O5FPRLK4.js +20 -0
  18. package/dist/setup-S4Z4PPIJ.js +20 -0
  19. package/package.json +15 -2
  20. package/src/agent-tools/common.ts +25 -0
  21. package/src/agent-tools/index.ts +3 -0
  22. package/src/agent-tools/schema/typebox.ts +25 -0
  23. package/src/agent-tools/tools/browser-tool.schema.ts +112 -0
  24. package/src/agent-tools/tools/browser-tool.ts +388 -0
  25. package/src/agent-tools/tools/gateway.ts +126 -0
  26. package/src/agent-tools/tools/nodes-utils.ts +80 -0
  27. package/src/browser/bridge-auth-registry.ts +34 -0
  28. package/src/browser/bridge-server.ts +93 -0
  29. package/src/browser/cdp.helpers.ts +180 -0
  30. package/src/browser/cdp.ts +466 -0
  31. package/src/browser/chrome.executables.ts +625 -0
  32. package/src/browser/chrome.profile-decoration.ts +198 -0
  33. package/src/browser/chrome.ts +349 -0
  34. package/src/browser/client-actions-core.ts +259 -0
  35. package/src/browser/client-actions-observe.ts +184 -0
  36. package/src/browser/client-actions-state.ts +284 -0
  37. package/src/browser/client-actions-types.ts +16 -0
  38. package/src/browser/client-actions-url.ts +11 -0
  39. package/src/browser/client-actions.ts +4 -0
  40. package/src/browser/client-fetch.ts +253 -0
  41. package/src/browser/client.ts +337 -0
  42. package/src/browser/config.ts +296 -0
  43. package/src/browser/constants.ts +8 -0
  44. package/src/browser/control-auth.ts +94 -0
  45. package/src/browser/control-service.ts +81 -0
  46. package/src/browser/csrf.ts +87 -0
  47. package/src/browser/enterprise-compat.ts +518 -0
  48. package/src/browser/extension-relay.ts +834 -0
  49. package/src/browser/http-auth.ts +63 -0
  50. package/src/browser/navigation-guard.ts +50 -0
  51. package/src/browser/paths.ts +49 -0
  52. package/src/browser/profiles-service.ts +187 -0
  53. package/src/browser/profiles.ts +113 -0
  54. package/src/browser/proxy-files.ts +41 -0
  55. package/src/browser/pw-ai-module.ts +52 -0
  56. package/src/browser/pw-ai-state.ts +9 -0
  57. package/src/browser/pw-ai.ts +65 -0
  58. package/src/browser/pw-role-snapshot.ts +434 -0
  59. package/src/browser/pw-session.ts +810 -0
  60. package/src/browser/pw-tools-core.activity.ts +68 -0
  61. package/src/browser/pw-tools-core.downloads.ts +281 -0
  62. package/src/browser/pw-tools-core.interactions.ts +646 -0
  63. package/src/browser/pw-tools-core.responses.ts +124 -0
  64. package/src/browser/pw-tools-core.shared.ts +70 -0
  65. package/src/browser/pw-tools-core.snapshot.ts +213 -0
  66. package/src/browser/pw-tools-core.state.ts +209 -0
  67. package/src/browser/pw-tools-core.storage.ts +128 -0
  68. package/src/browser/pw-tools-core.trace.ts +37 -0
  69. package/src/browser/pw-tools-core.ts +8 -0
  70. package/src/browser/resolved-config-refresh.ts +59 -0
  71. package/src/browser/routes/agent.act.shared.ts +52 -0
  72. package/src/browser/routes/agent.act.ts +575 -0
  73. package/src/browser/routes/agent.debug.ts +149 -0
  74. package/src/browser/routes/agent.shared.ts +143 -0
  75. package/src/browser/routes/agent.snapshot.ts +333 -0
  76. package/src/browser/routes/agent.storage.ts +451 -0
  77. package/src/browser/routes/agent.ts +13 -0
  78. package/src/browser/routes/basic.ts +202 -0
  79. package/src/browser/routes/dispatcher.ts +126 -0
  80. package/src/browser/routes/index.ts +11 -0
  81. package/src/browser/routes/path-output.ts +1 -0
  82. package/src/browser/routes/tabs.ts +217 -0
  83. package/src/browser/routes/types.ts +26 -0
  84. package/src/browser/routes/utils.ts +73 -0
  85. package/src/browser/screenshot.ts +54 -0
  86. package/src/browser/server-context.ts +688 -0
  87. package/src/browser/server-context.types.ts +65 -0
  88. package/src/browser/server-lifecycle.ts +48 -0
  89. package/src/browser/server-middleware.ts +37 -0
  90. package/src/browser/server.ts +110 -0
  91. package/src/browser/target-id.ts +30 -0
  92. package/src/browser/trash.ts +21 -0
  93. package/src/dashboard/pages/agent-detail.js +313 -1
  94. package/src/engine/agent-routes.ts +46 -0
  95. package/src/security/external-content.ts +299 -0
@@ -3974,7 +3974,319 @@ function ToolsSection(props) {
3974
3974
  })
3975
3975
  ),
3976
3976
 
3977
- filtered.length === 0 && h('div', { style: { textAlign: 'center', padding: 40, color: 'var(--text-muted)' } }, 'No tools match this filter.')
3977
+ filtered.length === 0 && h('div', { style: { textAlign: 'center', padding: 40, color: 'var(--text-muted)' } }, 'No tools match this filter.'),
3978
+
3979
+ // ─── Browser Configuration ─────────────────────────
3980
+ h(BrowserConfigCard, { agentId: agentId }),
3981
+
3982
+ // ─── Tool Restrictions ─────────────────────────────
3983
+ h(ToolRestrictionsCard, { agentId: agentId })
3984
+ );
3985
+ }
3986
+
3987
+ // ════════════════════════════════════════════════════════════
3988
+ // BROWSER CONFIG CARD — Configurable browser settings per agent
3989
+ // ════════════════════════════════════════════════════════════
3990
+
3991
+ function BrowserConfigCard(props) {
3992
+ var agentId = props.agentId;
3993
+ var _d = useApp(); var toast = _d.toast;
3994
+ var _cfg = useState(null); var cfg = _cfg[0]; var setCfg = _cfg[1];
3995
+ var _saving = useState(false); var saving = _saving[0]; var setSaving = _saving[1];
3996
+ var _collapsed = useState(true); var collapsed = _collapsed[0]; var setCollapsed = _collapsed[1];
3997
+
3998
+ function load() {
3999
+ engineCall('/bridge/agents/' + agentId + '/browser-config')
4000
+ .then(function(d) { setCfg(d.config || {}); })
4001
+ .catch(function() { setCfg({}); });
4002
+ }
4003
+
4004
+ useEffect(function() { load(); }, [agentId]);
4005
+
4006
+ function save() {
4007
+ setSaving(true);
4008
+ engineCall('/bridge/agents/' + agentId + '/browser-config', {
4009
+ method: 'PUT',
4010
+ body: JSON.stringify(cfg),
4011
+ }).then(function() { toast('Browser config saved', 'success'); setSaving(false); })
4012
+ .catch(function(e) { toast(e.message, 'error'); setSaving(false); });
4013
+ }
4014
+
4015
+ function update(key, value) {
4016
+ setCfg(function(prev) { var n = Object.assign({}, prev); n[key] = value; return n; });
4017
+ }
4018
+
4019
+ if (!cfg) return null;
4020
+
4021
+ var labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 };
4022
+ var helpStyle = { fontSize: 11, color: 'var(--text-muted)', marginTop: 2 };
4023
+
4024
+ return h('div', { className: 'card', style: { marginTop: 16 } },
4025
+ h('div', {
4026
+ className: 'card-header',
4027
+ style: { cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'space-between' },
4028
+ onClick: function() { setCollapsed(!collapsed); }
4029
+ },
4030
+ h('span', null, '\uD83C\uDF10 Browser Configuration'),
4031
+ h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } }, collapsed ? '\u25BC' : '\u25B2')
4032
+ ),
4033
+ !collapsed && h('div', { style: { padding: 16, display: 'grid', gap: 16 } },
4034
+ // Headless mode
4035
+ h('div', { className: 'form-group' },
4036
+ h('label', { style: labelStyle }, 'Headless Mode'),
4037
+ h('select', {
4038
+ className: 'input', value: cfg.headless !== false ? 'true' : 'false',
4039
+ onChange: function(e) { update('headless', e.target.value === 'true'); }
4040
+ },
4041
+ h('option', { value: 'true' }, 'Headless (no visible browser window)'),
4042
+ h('option', { value: 'false' }, 'Headed (visible browser — needed for Meet/Teams)')
4043
+ ),
4044
+ h('div', { style: helpStyle }, 'Use headed mode for video calls (Google Meet, Teams) or visual debugging.')
4045
+ ),
4046
+
4047
+ // SSRF Protection
4048
+ h('div', { className: 'form-group' },
4049
+ h('label', { style: labelStyle }, 'URL Protection'),
4050
+ h('select', {
4051
+ className: 'input', value: cfg.ssrfProtection || 'permissive',
4052
+ onChange: function(e) { update('ssrfProtection', e.target.value); }
4053
+ },
4054
+ h('option', { value: 'off' }, 'Off — No restrictions (full internet access)'),
4055
+ h('option', { value: 'permissive' }, 'Permissive — Block known dangerous URLs only'),
4056
+ h('option', { value: 'strict' }, 'Strict — Block private IPs, require allowlist')
4057
+ ),
4058
+ h('div', { style: helpStyle }, 'Controls which URLs the agent can navigate to.')
4059
+ ),
4060
+
4061
+ // Allow JS Evaluation
4062
+ h('div', { className: 'form-group' },
4063
+ h('label', { style: labelStyle }, 'JavaScript Evaluation'),
4064
+ h('select', {
4065
+ className: 'input', value: cfg.allowEvaluate !== false ? 'true' : 'false',
4066
+ onChange: function(e) { update('allowEvaluate', e.target.value === 'true'); }
4067
+ },
4068
+ h('option', { value: 'true' }, 'Allowed — Agent can run JS in page context'),
4069
+ h('option', { value: 'false' }, 'Blocked — No arbitrary JS execution')
4070
+ )
4071
+ ),
4072
+
4073
+ // Allow File URLs
4074
+ h('div', { className: 'form-group' },
4075
+ h('label', { style: labelStyle }, 'File URLs (file://)'),
4076
+ h('select', {
4077
+ className: 'input', value: cfg.allowFileUrls ? 'true' : 'false',
4078
+ onChange: function(e) { update('allowFileUrls', e.target.value === 'true'); }
4079
+ },
4080
+ h('option', { value: 'false' }, 'Blocked — Cannot access local files'),
4081
+ h('option', { value: 'true' }, 'Allowed — Can open local file:// URLs')
4082
+ )
4083
+ ),
4084
+
4085
+ // Max Contexts
4086
+ h('div', { className: 'form-group' },
4087
+ h('label', { style: labelStyle }, 'Max Browser Contexts'),
4088
+ h('input', {
4089
+ className: 'input', type: 'number', min: 1, max: 50,
4090
+ value: cfg.maxContexts || 10,
4091
+ onChange: function(e) { update('maxContexts', parseInt(e.target.value) || 10); }
4092
+ }),
4093
+ h('div', { style: helpStyle }, 'Maximum concurrent browser windows/tabs.')
4094
+ ),
4095
+
4096
+ // Navigation Timeout
4097
+ h('div', { className: 'form-group' },
4098
+ h('label', { style: labelStyle }, 'Navigation Timeout (ms)'),
4099
+ h('input', {
4100
+ className: 'input', type: 'number', min: 5000, max: 120000, step: 1000,
4101
+ value: cfg.navigationTimeoutMs || 30000,
4102
+ onChange: function(e) { update('navigationTimeoutMs', parseInt(e.target.value) || 30000); }
4103
+ }),
4104
+ h('div', { style: helpStyle }, 'Maximum time to wait for page loads.')
4105
+ ),
4106
+
4107
+ // Idle Timeout
4108
+ h('div', { className: 'form-group' },
4109
+ h('label', { style: labelStyle }, 'Idle Timeout (minutes)'),
4110
+ h('input', {
4111
+ className: 'input', type: 'number', min: 1, max: 60,
4112
+ value: Math.round((cfg.idleTimeoutMs || 300000) / 60000),
4113
+ onChange: function(e) { update('idleTimeoutMs', (parseInt(e.target.value) || 5) * 60000); }
4114
+ }),
4115
+ h('div', { style: helpStyle }, 'Close browser after this many minutes of inactivity.')
4116
+ ),
4117
+
4118
+ // Blocked URL Patterns
4119
+ h('div', { className: 'form-group' },
4120
+ h('label', { style: labelStyle }, 'Blocked URL Patterns'),
4121
+ h('input', {
4122
+ className: 'input', placeholder: '*://169.254.*, *://metadata.google.*',
4123
+ value: (cfg.blockedUrlPatterns || []).join(', '),
4124
+ onChange: function(e) { update('blockedUrlPatterns', e.target.value.split(',').map(function(s) { return s.trim(); }).filter(Boolean)); }
4125
+ }),
4126
+ h('div', { style: helpStyle }, 'Comma-separated URL patterns to block (supports *).')
4127
+ ),
4128
+
4129
+ // Allowed URL Patterns (only for strict mode)
4130
+ cfg.ssrfProtection === 'strict' && h('div', { className: 'form-group' },
4131
+ h('label', { style: labelStyle }, 'Allowed URL Patterns (Strict Mode)'),
4132
+ h('input', {
4133
+ className: 'input', placeholder: '*://example.com/*, *://api.service.com/*',
4134
+ value: (cfg.allowedUrlPatterns || []).join(', '),
4135
+ onChange: function(e) { update('allowedUrlPatterns', e.target.value.split(',').map(function(s) { return s.trim(); }).filter(Boolean)); }
4136
+ }),
4137
+ h('div', { style: helpStyle }, 'Only these URLs are allowed in strict mode.')
4138
+ ),
4139
+
4140
+ // Save button
4141
+ h('div', { style: { display: 'flex', justifyContent: 'flex-end', paddingTop: 8 } },
4142
+ h('button', { className: 'btn', disabled: saving, onClick: save }, saving ? 'Saving...' : 'Save Browser Config')
4143
+ )
4144
+ )
4145
+ );
4146
+ }
4147
+
4148
+ // ════════════════════════════════════════════════════════════
4149
+ // TOOL RESTRICTIONS CARD — Per-agent restrictions
4150
+ // ════════════════════════════════════════════════════════════
4151
+
4152
+ function ToolRestrictionsCard(props) {
4153
+ var agentId = props.agentId;
4154
+ var _d = useApp(); var toast = _d.toast;
4155
+ var _cfg = useState(null); var cfg = _cfg[0]; var setCfg = _cfg[1];
4156
+ var _saving = useState(false); var saving = _saving[0]; var setSaving = _saving[1];
4157
+ var _collapsed = useState(true); var collapsed = _collapsed[0]; var setCollapsed = _collapsed[1];
4158
+
4159
+ function load() {
4160
+ engineCall('/bridge/agents/' + agentId + '/tool-restrictions')
4161
+ .then(function(d) { setCfg(d.restrictions || {}); })
4162
+ .catch(function() { setCfg({}); });
4163
+ }
4164
+
4165
+ useEffect(function() { load(); }, [agentId]);
4166
+
4167
+ function save() {
4168
+ setSaving(true);
4169
+ engineCall('/bridge/agents/' + agentId + '/tool-restrictions', {
4170
+ method: 'PUT',
4171
+ body: JSON.stringify(cfg),
4172
+ }).then(function() { toast('Restrictions saved', 'success'); setSaving(false); })
4173
+ .catch(function(e) { toast(e.message, 'error'); setSaving(false); });
4174
+ }
4175
+
4176
+ function update(key, value) {
4177
+ setCfg(function(prev) { var n = Object.assign({}, prev); n[key] = value; return n; });
4178
+ }
4179
+
4180
+ if (!cfg) return null;
4181
+
4182
+ var labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: 'var(--text-secondary)', marginBottom: 4 };
4183
+ var helpStyle = { fontSize: 11, color: 'var(--text-muted)', marginTop: 2 };
4184
+
4185
+ return h('div', { className: 'card', style: { marginTop: 16 } },
4186
+ h('div', {
4187
+ className: 'card-header',
4188
+ style: { cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'space-between' },
4189
+ onClick: function() { setCollapsed(!collapsed); }
4190
+ },
4191
+ h('span', null, '\uD83D\uDD12 Tool Restrictions'),
4192
+ h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } }, collapsed ? '\u25BC' : '\u25B2')
4193
+ ),
4194
+ !collapsed && h('div', { style: { padding: 16, display: 'grid', gap: 16 } },
4195
+ // Max file size for read/write
4196
+ h('div', { className: 'form-group' },
4197
+ h('label', { style: labelStyle }, 'Max File Size (MB)'),
4198
+ h('input', {
4199
+ className: 'input', type: 'number', min: 1, max: 1000,
4200
+ value: cfg.maxFileSizeMb || 50,
4201
+ onChange: function(e) { update('maxFileSizeMb', parseInt(e.target.value) || 50); }
4202
+ }),
4203
+ h('div', { style: helpStyle }, 'Maximum file size the agent can read or write.')
4204
+ ),
4205
+
4206
+ // Shell command execution
4207
+ h('div', { className: 'form-group' },
4208
+ h('label', { style: labelStyle }, 'Shell Command Execution'),
4209
+ h('select', {
4210
+ className: 'input', value: cfg.shellExecution || 'allowed',
4211
+ onChange: function(e) { update('shellExecution', e.target.value); }
4212
+ },
4213
+ h('option', { value: 'allowed' }, 'Allowed — Full shell access'),
4214
+ h('option', { value: 'sandboxed' }, 'Sandboxed — Limited to safe commands'),
4215
+ h('option', { value: 'blocked' }, 'Blocked — No shell execution')
4216
+ ),
4217
+ h('div', { style: helpStyle }, 'Controls whether the agent can run shell commands.')
4218
+ ),
4219
+
4220
+ // Web fetch restrictions
4221
+ h('div', { className: 'form-group' },
4222
+ h('label', { style: labelStyle }, 'Web Fetch'),
4223
+ h('select', {
4224
+ className: 'input', value: cfg.webFetch || 'allowed',
4225
+ onChange: function(e) { update('webFetch', e.target.value); }
4226
+ },
4227
+ h('option', { value: 'allowed' }, 'Allowed — Can fetch any URL'),
4228
+ h('option', { value: 'restricted' }, 'Restricted — Only allowed domains'),
4229
+ h('option', { value: 'blocked' }, 'Blocked — No web fetching')
4230
+ )
4231
+ ),
4232
+
4233
+ // Email sending restrictions
4234
+ h('div', { className: 'form-group' },
4235
+ h('label', { style: labelStyle }, 'Email Sending'),
4236
+ h('select', {
4237
+ className: 'input', value: cfg.emailSending || 'allowed',
4238
+ onChange: function(e) { update('emailSending', e.target.value); }
4239
+ },
4240
+ h('option', { value: 'allowed' }, 'Allowed — Can send to anyone'),
4241
+ h('option', { value: 'internal' }, 'Internal Only — Same domain only'),
4242
+ h('option', { value: 'approval' }, 'Requires Approval — Manager must approve'),
4243
+ h('option', { value: 'blocked' }, 'Blocked — No email sending')
4244
+ ),
4245
+ h('div', { style: helpStyle }, 'Controls who the agent can email.')
4246
+ ),
4247
+
4248
+ // Database access
4249
+ h('div', { className: 'form-group' },
4250
+ h('label', { style: labelStyle }, 'Database Access'),
4251
+ h('select', {
4252
+ className: 'input', value: cfg.databaseAccess || 'readwrite',
4253
+ onChange: function(e) { update('databaseAccess', e.target.value); }
4254
+ },
4255
+ h('option', { value: 'readwrite' }, 'Read + Write — Full database access'),
4256
+ h('option', { value: 'readonly' }, 'Read Only — SELECT queries only'),
4257
+ h('option', { value: 'blocked' }, 'Blocked — No database access')
4258
+ )
4259
+ ),
4260
+
4261
+ // Drive/file sharing
4262
+ h('div', { className: 'form-group' },
4263
+ h('label', { style: labelStyle }, 'File Sharing (Drive)'),
4264
+ h('select', {
4265
+ className: 'input', value: cfg.fileSharing || 'allowed',
4266
+ onChange: function(e) { update('fileSharing', e.target.value); }
4267
+ },
4268
+ h('option', { value: 'allowed' }, 'Allowed — Can share files externally'),
4269
+ h('option', { value: 'internal' }, 'Internal Only — Share within org only'),
4270
+ h('option', { value: 'blocked' }, 'Blocked — No file sharing')
4271
+ )
4272
+ ),
4273
+
4274
+ // Rate limiting
4275
+ h('div', { className: 'form-group' },
4276
+ h('label', { style: labelStyle }, 'Rate Limit (calls per minute)'),
4277
+ h('input', {
4278
+ className: 'input', type: 'number', min: 0, max: 1000,
4279
+ value: cfg.rateLimit || 0,
4280
+ onChange: function(e) { update('rateLimit', parseInt(e.target.value) || 0); }
4281
+ }),
4282
+ h('div', { style: helpStyle }, '0 = no limit. Applies across all tool calls.')
4283
+ ),
4284
+
4285
+ // Save button
4286
+ h('div', { style: { display: 'flex', justifyContent: 'flex-end', paddingTop: 8 } },
4287
+ h('button', { className: 'btn', disabled: saving, onClick: save }, saving ? 'Saving...' : 'Save Restrictions')
4288
+ )
4289
+ )
3978
4290
  );
3979
4291
  }
3980
4292
 
package/dist/index.js CHANGED
@@ -35,8 +35,9 @@ import {
35
35
  executeTool,
36
36
  runAgentLoop,
37
37
  toolsToDefinitions
38
- } from "./chunk-GINZ56GG.js";
38
+ } from "./chunk-7RNT4O5T.js";
39
39
  import "./chunk-TYW5XTOW.js";
40
+ import "./chunk-VX3VFMVB.js";
40
41
  import {
41
42
  ValidationError,
42
43
  auditLogger,
@@ -50,11 +51,11 @@ import {
50
51
  requireRole,
51
52
  securityHeaders,
52
53
  validate
53
- } from "./chunk-CYABMD5B.js";
54
+ } from "./chunk-Q3V7VZFQ.js";
54
55
  import {
55
56
  provision,
56
57
  runSetupWizard
57
- } from "./chunk-NRKB2KGD.js";
58
+ } from "./chunk-PZA7YOJE.js";
58
59
  import {
59
60
  ENGINE_TABLES,
60
61
  ENGINE_TABLES_POSTGRES,