@agenticmail/enterprise 0.5.89 → 0.5.91

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,384 @@
1
+ import {
2
+ AGENTICMAIL_SKILL_DEFS,
3
+ ENTERPRISE_SKILL_DEFS,
4
+ GWS_SKILL_DEFS,
5
+ M365_SKILL_DEFS,
6
+ init_skills,
7
+ init_tool_catalog,
8
+ tool_catalog_exports
9
+ } from "./chunk-MINPSFLF.js";
10
+ import {
11
+ __toCommonJS
12
+ } from "./chunk-KFQGP6VL.js";
13
+
14
+ // src/engine/skills.ts
15
+ init_skills();
16
+ var SKILL_SUITES = [
17
+ {
18
+ id: "microsoft-365",
19
+ name: "Microsoft 365",
20
+ description: "Complete Microsoft 365 suite \u2014 Outlook, Teams, SharePoint, OneDrive, Word, Excel, PowerPoint, OneNote, Planner, Power BI, Power Automate, Forms, To Do, Bookings, Whiteboard, Admin Center, Copilot.",
21
+ icon: "\u{1F3E2}",
22
+ skills: [
23
+ "m365-outlook",
24
+ "m365-teams",
25
+ "m365-sharepoint",
26
+ "m365-onedrive",
27
+ "m365-word",
28
+ "m365-excel",
29
+ "m365-powerpoint",
30
+ "m365-onenote",
31
+ "m365-planner",
32
+ "m365-power-bi",
33
+ "m365-power-automate",
34
+ "m365-forms",
35
+ "m365-todo",
36
+ "m365-bookings",
37
+ "m365-whiteboard",
38
+ "m365-admin",
39
+ "m365-copilot"
40
+ ]
41
+ },
42
+ {
43
+ id: "google-workspace",
44
+ name: "Google Workspace",
45
+ description: "Complete Google Workspace suite \u2014 Gmail, Calendar, Drive, Docs, Sheets, Slides, Meet, Chat, Forms, Sites, Keep, Admin Console, Vault, Groups.",
46
+ icon: "\u{1F535}",
47
+ skills: [
48
+ "gws-gmail",
49
+ "gws-calendar",
50
+ "gws-drive",
51
+ "gws-docs",
52
+ "gws-sheets",
53
+ "gws-slides",
54
+ "gws-meet",
55
+ "gws-chat",
56
+ "gws-forms",
57
+ "gws-sites",
58
+ "gws-keep",
59
+ "gws-admin",
60
+ "gws-vault",
61
+ "gws-groups"
62
+ ]
63
+ },
64
+ {
65
+ id: "atlassian",
66
+ name: "Atlassian Suite",
67
+ description: "Jira, Confluence, Bitbucket, Trello, Statuspage, and Opsgenie.",
68
+ icon: "\u{1F537}",
69
+ skills: ["jira", "confluence", "bitbucket", "trello", "statuspage", "opsgenie"]
70
+ },
71
+ {
72
+ id: "aws",
73
+ name: "Amazon Web Services",
74
+ description: "AWS cloud infrastructure \u2014 S3, EC2, Lambda, RDS, CloudWatch, IAM, SES, SNS, SQS, DynamoDB, CloudFormation.",
75
+ icon: "\u2601\uFE0F",
76
+ skills: ["aws-s3", "aws-ec2", "aws-lambda", "aws-rds", "aws-cloudwatch", "aws-iam", "aws-ses", "aws-sns", "aws-sqs", "aws-dynamodb", "aws-cloudformation"]
77
+ },
78
+ {
79
+ id: "azure",
80
+ name: "Microsoft Azure",
81
+ description: "Azure cloud infrastructure \u2014 VMs, App Service, Functions, Storage, SQL, CosmosDB, DevOps, Active Directory.",
82
+ icon: "\u26C5",
83
+ skills: ["azure-vms", "azure-app-service", "azure-functions", "azure-storage", "azure-sql", "azure-cosmosdb", "azure-devops", "azure-ad"]
84
+ },
85
+ {
86
+ id: "gcp",
87
+ name: "Google Cloud Platform",
88
+ description: "GCP cloud infrastructure \u2014 Compute Engine, Cloud Functions, Cloud Storage, BigQuery, Cloud Run, Pub/Sub, Firestore.",
89
+ icon: "\u{1F324}\uFE0F",
90
+ skills: ["gcp-compute", "gcp-functions", "gcp-storage", "gcp-bigquery", "gcp-run", "gcp-pubsub", "gcp-firestore"]
91
+ },
92
+ {
93
+ id: "salesforce-suite",
94
+ name: "Salesforce Suite",
95
+ description: "Salesforce CRM, Service Cloud, Marketing Cloud, and Commerce Cloud.",
96
+ icon: "\u2601",
97
+ skills: ["salesforce", "salesforce-service", "salesforce-marketing", "salesforce-commerce"]
98
+ },
99
+ {
100
+ id: "hubspot-suite",
101
+ name: "HubSpot Suite",
102
+ description: "HubSpot CRM, Marketing Hub, Sales Hub, Service Hub, and CMS.",
103
+ icon: "\u{1F7E0}",
104
+ skills: ["hubspot-crm", "hubspot-marketing", "hubspot-sales", "hubspot-service"]
105
+ },
106
+ {
107
+ id: "adobe-creative",
108
+ name: "Adobe Creative Cloud",
109
+ description: "Adobe Photoshop, Illustrator, Premiere Pro, After Effects, InDesign, and XD.",
110
+ icon: "\u{1F3A8}",
111
+ skills: ["adobe-photoshop", "adobe-illustrator", "adobe-premiere", "adobe-after-effects", "adobe-indesign", "adobe-xd"]
112
+ },
113
+ {
114
+ id: "enterprise-utility",
115
+ name: "Enterprise Utility Tools",
116
+ description: "Built-in enterprise productivity tools \u2014 database queries, spreadsheets, documents, calendar, knowledge search, web research, translation, logs, workflow, notifications, finance, HTTP, security scanning, code sandbox, diff, and vision.",
117
+ icon: "\u{1F3D7}\uFE0F",
118
+ skills: [
119
+ "enterprise-database",
120
+ "enterprise-spreadsheet",
121
+ "enterprise-documents",
122
+ "enterprise-calendar",
123
+ "enterprise-knowledge-search",
124
+ "enterprise-web-research",
125
+ "enterprise-translation",
126
+ "enterprise-logs",
127
+ "enterprise-workflow",
128
+ "enterprise-notifications",
129
+ "enterprise-finance",
130
+ "enterprise-http",
131
+ "enterprise-security-scan",
132
+ "enterprise-code-sandbox",
133
+ "enterprise-diff",
134
+ "enterprise-vision"
135
+ ]
136
+ }
137
+ ];
138
+ var PRESET_PROFILES = [
139
+ {
140
+ name: "Research Assistant",
141
+ description: "Can search the web, read files, and summarize content. Cannot send messages, run code, or modify anything.",
142
+ skills: { mode: "allowlist", list: ["research", "summarize", "data-read"] },
143
+ tools: { blocked: ["exec", "write", "edit"], allowed: ["web_search", "web_fetch", "read", "memory_search", "memory_get"] },
144
+ maxRiskLevel: "low",
145
+ blockedSideEffects: ["sends-email", "sends-message", "sends-sms", "posts-social", "runs-code", "modifies-files", "deletes-data", "controls-device", "financial"],
146
+ requireApproval: { enabled: false, forRiskLevels: [], forSideEffects: [], approvers: [], timeoutMinutes: 30 },
147
+ rateLimits: { toolCallsPerMinute: 30, toolCallsPerHour: 500, toolCallsPerDay: 5e3, externalActionsPerHour: 0 },
148
+ constraints: { maxConcurrentTasks: 3, maxSessionDurationMinutes: 480, sandboxMode: false }
149
+ },
150
+ {
151
+ name: "Customer Support Agent",
152
+ description: "Can read/send emails, search knowledge base, and manage tickets. Cannot run code or access files.",
153
+ skills: { mode: "allowlist", list: ["communication", "research", "agenticmail", "m365-outlook", "m365-teams", "gws-gmail", "gws-calendar", "zendesk", "intercom"] },
154
+ tools: { blocked: ["exec", "browser", "write", "edit"], allowed: ["agenticmail_send", "agenticmail_reply", "agenticmail_inbox", "agenticmail_read", "agenticmail_search", "web_search", "web_fetch"] },
155
+ maxRiskLevel: "medium",
156
+ blockedSideEffects: ["runs-code", "modifies-files", "deletes-data", "controls-device", "financial", "posts-social"],
157
+ requireApproval: { enabled: true, forRiskLevels: ["high", "critical"], forSideEffects: ["sends-email"], approvers: [], timeoutMinutes: 60 },
158
+ rateLimits: { toolCallsPerMinute: 20, toolCallsPerHour: 300, toolCallsPerDay: 3e3, externalActionsPerHour: 50 },
159
+ constraints: { maxConcurrentTasks: 5, maxSessionDurationMinutes: 480, sandboxMode: false }
160
+ },
161
+ {
162
+ name: "Developer Assistant",
163
+ description: "Full development capabilities: code, git, GitHub, shell. Cannot send external messages or access smart home.",
164
+ skills: { mode: "allowlist", list: ["development", "github", "coding-agent", "research", "data", "docker", "github-actions", "jira", "linear", "slack"] },
165
+ tools: { blocked: ["agenticmail_send", "message", "tts", "nodes"], allowed: ["exec", "read", "write", "edit", "web_search", "web_fetch", "browser"] },
166
+ maxRiskLevel: "high",
167
+ blockedSideEffects: ["sends-email", "sends-message", "sends-sms", "posts-social", "controls-device", "financial"],
168
+ requireApproval: { enabled: true, forRiskLevels: ["critical"], forSideEffects: [], approvers: [], timeoutMinutes: 15 },
169
+ rateLimits: { toolCallsPerMinute: 60, toolCallsPerHour: 1e3, toolCallsPerDay: 1e4, externalActionsPerHour: 100 },
170
+ constraints: { maxConcurrentTasks: 3, maxSessionDurationMinutes: 720, sandboxMode: false }
171
+ },
172
+ {
173
+ name: "Full Access (Owner)",
174
+ description: "Unrestricted access to all skills and tools. Use with caution.",
175
+ skills: { mode: "blocklist", list: [] },
176
+ tools: { blocked: [], allowed: [] },
177
+ maxRiskLevel: "critical",
178
+ blockedSideEffects: [],
179
+ requireApproval: { enabled: false, forRiskLevels: [], forSideEffects: [], approvers: [], timeoutMinutes: 30 },
180
+ rateLimits: { toolCallsPerMinute: 120, toolCallsPerHour: 5e3, toolCallsPerDay: 5e4, externalActionsPerHour: 500 },
181
+ constraints: { maxConcurrentTasks: 10, maxSessionDurationMinutes: 1440, sandboxMode: false }
182
+ },
183
+ {
184
+ name: "Sandbox (Testing)",
185
+ description: "All tools available but in simulation mode. No real external actions are taken.",
186
+ skills: { mode: "blocklist", list: [] },
187
+ tools: { blocked: [], allowed: [] },
188
+ maxRiskLevel: "critical",
189
+ blockedSideEffects: [],
190
+ requireApproval: { enabled: false, forRiskLevels: [], forSideEffects: [], approvers: [], timeoutMinutes: 30 },
191
+ rateLimits: { toolCallsPerMinute: 60, toolCallsPerHour: 1e3, toolCallsPerDay: 1e4, externalActionsPerHour: 500 },
192
+ constraints: { maxConcurrentTasks: 5, maxSessionDurationMinutes: 480, sandboxMode: true }
193
+ }
194
+ ];
195
+ var BUILTIN_SKILLS = [
196
+ // ═══ AgenticMail — Core Product (always available) ═══
197
+ ...AGENTICMAIL_SKILL_DEFS,
198
+ // ═══ Microsoft 365 Suite ═══
199
+ ...M365_SKILL_DEFS,
200
+ // ═══ Google Workspace Suite ═══
201
+ ...GWS_SKILL_DEFS,
202
+ // ═══ Enterprise Utility Tools ═══
203
+ ...ENTERPRISE_SKILL_DEFS
204
+ ];
205
+ var PermissionEngine = class {
206
+ skills = /* @__PURE__ */ new Map();
207
+ profiles = /* @__PURE__ */ new Map();
208
+ engineDb;
209
+ constructor(skills) {
210
+ if (skills) {
211
+ for (const s of skills) this.skills.set(s.id, s);
212
+ }
213
+ }
214
+ /**
215
+ * Set the database adapter and load existing profiles from DB
216
+ */
217
+ async setDb(db) {
218
+ this.engineDb = db;
219
+ try {
220
+ const profiles = await db.getAllPermissionProfiles();
221
+ for (const profile of profiles) {
222
+ if (profile && profile.id) {
223
+ this.profiles.set(profile.id, profile);
224
+ }
225
+ }
226
+ if (profiles.length > 0) console.log(`[permissions] Loaded ${profiles.length} permission profiles from DB`);
227
+ } catch {
228
+ }
229
+ }
230
+ registerSkill(skill) {
231
+ this.skills.set(skill.id, skill);
232
+ }
233
+ setProfile(agentId, profile, orgId) {
234
+ this.profiles.set(agentId, profile);
235
+ if (this.engineDb && orgId) {
236
+ this.engineDb.upsertPermissionProfile(orgId, profile).catch((err) => {
237
+ console.error(`[permissions] Failed to persist profile for agent ${agentId}:`, err);
238
+ });
239
+ }
240
+ }
241
+ getProfile(agentId) {
242
+ return this.profiles.get(agentId);
243
+ }
244
+ /**
245
+ * Core permission check: Can this agent use this tool right now?
246
+ * Returns { allowed, reason, requiresApproval }
247
+ */
248
+ checkPermission(agentId, toolId, context) {
249
+ const profile = this.profiles.get(agentId);
250
+ if (!profile) {
251
+ return { allowed: false, reason: "No permission profile assigned", requiresApproval: false };
252
+ }
253
+ if (profile.constraints.sandboxMode) {
254
+ return { allowed: true, reason: "Sandbox mode \u2014 action will be simulated", requiresApproval: false, sandbox: true };
255
+ }
256
+ if (profile.constraints.allowedWorkingHours) {
257
+ const now = context?.timestamp || /* @__PURE__ */ new Date();
258
+ const { start, end, timezone } = profile.constraints.allowedWorkingHours;
259
+ const hour = parseInt(new Intl.DateTimeFormat("en-US", { hour: "numeric", hour12: false, timeZone: timezone }).format(now));
260
+ const startHour = parseInt(start.split(":")[0]);
261
+ const endHour = parseInt(end.split(":")[0]);
262
+ if (hour < startHour || hour >= endHour) {
263
+ return { allowed: false, reason: `Outside working hours (${start}-${end} ${timezone})`, requiresApproval: false };
264
+ }
265
+ }
266
+ if (profile.constraints.allowedIPs?.length && context?.ip) {
267
+ if (!profile.constraints.allowedIPs.includes(context.ip)) {
268
+ return { allowed: false, reason: `IP ${context.ip} not in allowlist`, requiresApproval: false };
269
+ }
270
+ }
271
+ if (profile.tools.blocked.includes(toolId)) {
272
+ return { allowed: false, reason: `Tool "${toolId}" is explicitly blocked`, requiresApproval: false };
273
+ }
274
+ if (profile.tools.allowed.includes(toolId)) {
275
+ return this._checkApproval(profile, toolId);
276
+ }
277
+ const tool = this._findTool(toolId);
278
+ if (!tool) {
279
+ return { allowed: false, reason: `Unknown tool "${toolId}"`, requiresApproval: false };
280
+ }
281
+ const skillAllowed = profile.skills.mode === "allowlist" ? profile.skills.list.includes(tool.skillId) : !profile.skills.list.includes(tool.skillId);
282
+ if (!skillAllowed) {
283
+ return { allowed: false, reason: `Skill "${tool.skillId}" is not permitted`, requiresApproval: false };
284
+ }
285
+ const riskOrder = ["low", "medium", "high", "critical"];
286
+ const toolRiskIdx = riskOrder.indexOf(tool.risk);
287
+ const maxRiskIdx = riskOrder.indexOf(profile.maxRiskLevel);
288
+ if (toolRiskIdx > maxRiskIdx) {
289
+ return { allowed: false, reason: `Tool risk "${tool.risk}" exceeds max allowed "${profile.maxRiskLevel}"`, requiresApproval: false };
290
+ }
291
+ for (const effect of tool.sideEffects) {
292
+ if (profile.blockedSideEffects.includes(effect)) {
293
+ return { allowed: false, reason: `Side effect "${effect}" is blocked`, requiresApproval: false };
294
+ }
295
+ }
296
+ return this._checkApproval(profile, toolId, tool);
297
+ }
298
+ _checkApproval(profile, toolId, tool) {
299
+ if (!profile.requireApproval.enabled) {
300
+ return { allowed: true, reason: "Permitted", requiresApproval: false };
301
+ }
302
+ if (tool) {
303
+ if (profile.requireApproval.forRiskLevels.includes(tool.risk)) {
304
+ return { allowed: true, reason: "Requires human approval (risk level)", requiresApproval: true };
305
+ }
306
+ for (const effect of tool.sideEffects) {
307
+ if (profile.requireApproval.forSideEffects.includes(effect)) {
308
+ return { allowed: true, reason: `Requires human approval (${effect})`, requiresApproval: true };
309
+ }
310
+ }
311
+ }
312
+ return { allowed: true, reason: "Permitted", requiresApproval: false };
313
+ }
314
+ _findTool(toolId) {
315
+ for (const skill of this.skills.values()) {
316
+ const tool = skill.tools.find((t) => t.id === toolId);
317
+ if (tool) return tool;
318
+ }
319
+ try {
320
+ const { TOOL_INDEX } = (init_tool_catalog(), __toCommonJS(tool_catalog_exports));
321
+ return TOOL_INDEX.get(toolId);
322
+ } catch {
323
+ return void 0;
324
+ }
325
+ }
326
+ /**
327
+ * Get the full resolved tool list for an agent — what they can actually use
328
+ */
329
+ getAvailableTools(agentId) {
330
+ const result = [];
331
+ for (const skill of this.skills.values()) {
332
+ for (const tool of skill.tools) {
333
+ const perm = this.checkPermission(agentId, tool.id);
334
+ if (perm.allowed) {
335
+ result.push({
336
+ tool,
337
+ status: perm.sandbox ? "sandbox" : perm.requiresApproval ? "approval-required" : "allowed"
338
+ });
339
+ }
340
+ }
341
+ }
342
+ return result;
343
+ }
344
+ /**
345
+ * Generate the tool policy config for an agent based on their profile
346
+ */
347
+ generateToolPolicy(agentId) {
348
+ const profile = this.profiles.get(agentId);
349
+ if (!profile) return { allowedTools: [], blockedTools: [], approvalRequired: [], rateLimits: { toolCallsPerMinute: 10, toolCallsPerHour: 100, toolCallsPerDay: 1e3, externalActionsPerHour: 10 } };
350
+ const allowed = [];
351
+ const blocked = [];
352
+ const approval = [];
353
+ for (const skill of this.skills.values()) {
354
+ for (const tool of skill.tools) {
355
+ const perm = this.checkPermission(agentId, tool.id);
356
+ if (perm.allowed) {
357
+ allowed.push(tool.id);
358
+ if (perm.requiresApproval) approval.push(tool.id);
359
+ } else {
360
+ blocked.push(tool.id);
361
+ }
362
+ }
363
+ }
364
+ return { allowedTools: allowed, blockedTools: blocked, approvalRequired: approval, rateLimits: profile.rateLimits };
365
+ }
366
+ getAllSkills() {
367
+ return Array.from(this.skills.values());
368
+ }
369
+ getSkillsByCategory() {
370
+ const result = {};
371
+ for (const skill of this.skills.values()) {
372
+ if (!result[skill.category]) result[skill.category] = [];
373
+ result[skill.category].push(skill);
374
+ }
375
+ return result;
376
+ }
377
+ };
378
+
379
+ export {
380
+ SKILL_SUITES,
381
+ PRESET_PROFILES,
382
+ BUILTIN_SKILLS,
383
+ PermissionEngine
384
+ };