@agenticmail/enterprise 0.5.180 → 0.5.181

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,34 @@
1
+ import "./chunk-KFQGP6VL.js";
2
+
3
+ // src/cli-serve.ts
4
+ async function runServe(_args) {
5
+ const DATABASE_URL = process.env.DATABASE_URL;
6
+ const JWT_SECRET = process.env.JWT_SECRET;
7
+ const PORT = parseInt(process.env.PORT || "8080", 10);
8
+ if (!DATABASE_URL) {
9
+ console.error("ERROR: DATABASE_URL environment variable is required");
10
+ process.exit(1);
11
+ }
12
+ if (!JWT_SECRET) {
13
+ console.error("ERROR: JWT_SECRET environment variable is required");
14
+ process.exit(1);
15
+ }
16
+ const { createAdapter } = await import("./factory-MBP7N2OQ.js");
17
+ const { createServer } = await import("./server-2QS7B6JT.js");
18
+ const db = await createAdapter({
19
+ type: DATABASE_URL.startsWith("postgres") ? "postgres" : "sqlite",
20
+ connectionString: DATABASE_URL
21
+ });
22
+ await db.migrate();
23
+ const server = createServer({
24
+ port: PORT,
25
+ db,
26
+ jwtSecret: JWT_SECRET,
27
+ corsOrigins: ["*"]
28
+ });
29
+ await server.start();
30
+ console.log(`AgenticMail Enterprise server running on :${PORT}`);
31
+ }
32
+ export {
33
+ runServe
34
+ };
package/dist/cli.js CHANGED
@@ -47,14 +47,14 @@ Skill Development:
47
47
  `);
48
48
  break;
49
49
  case "serve":
50
- import("./cli-serve-XT4JQGAO.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
50
+ import("./cli-serve-CRLCU5IN.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
51
51
  break;
52
52
  case "agent":
53
- import("./cli-agent-RYEBQAJP.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
53
+ import("./cli-agent-PR4GTHBL.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
54
54
  break;
55
55
  case "setup":
56
56
  default:
57
- import("./setup-N52HK3ID.js").then((m) => m.runSetupWizard()).catch(fatal);
57
+ import("./setup-AS56DZLZ.js").then((m) => m.runSetupWizard()).catch(fatal);
58
58
  break;
59
59
  }
60
60
  function fatal(err) {
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  provision,
9
9
  runSetupWizard
10
- } from "./chunk-QRKMDW4Q.js";
10
+ } from "./chunk-AATBO7XZ.js";
11
11
  import {
12
12
  ActionJournal,
13
13
  ActivityTracker,
@@ -54,7 +54,7 @@ import {
54
54
  executeTool,
55
55
  runAgentLoop,
56
56
  toolsToDefinitions
57
- } from "./chunk-IEBZONQA.js";
57
+ } from "./chunk-6JBOFRV4.js";
58
58
  import "./chunk-AQH4DFYV.js";
59
59
  import {
60
60
  ValidationError,
@@ -69,7 +69,7 @@ import {
69
69
  requireRole,
70
70
  securityHeaders,
71
71
  validate
72
- } from "./chunk-WMNZBOIZ.js";
72
+ } from "./chunk-CY7ZE4F7.js";
73
73
  import "./chunk-3SMTCIR4.js";
74
74
  import {
75
75
  CircuitBreaker,
@@ -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-6JBOFRV4.js";
18
+ import "./chunk-AQH4DFYV.js";
19
+ import "./chunk-JLSQOQ5L.js";
20
+ import {
21
+ PROVIDER_REGISTRY,
22
+ listAllProviders,
23
+ resolveApiKeyForProvider,
24
+ resolveProvider
25
+ } from "./chunk-67KZYSLU.js";
26
+ import "./chunk-NRF3YRF7.js";
27
+ import "./chunk-TYW5XTOW.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-CY7ZE4F7.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-AATBO7XZ.js";
10
+ import "./chunk-MHIFVS5L.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.180",
3
+ "version": "0.5.181",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5,9 +5,12 @@
5
5
  * send messages, create spaces, manage memberships.
6
6
  * Uses Google Chat API v1.
7
7
  *
8
- * Required OAuth scope: https://www.googleapis.com/auth/chat.spaces
9
- * https://www.googleapis.com/auth/chat.messages
10
- * https://www.googleapis.com/auth/chat.memberships
8
+ * IMPORTANT: Google Chat API requires a Chat app to be configured in Google Cloud Console.
9
+ * Go to: APIs & Services > Google Chat API > Configuration, then enable the app and set it up.
10
+ * Without this, all calls will return 401/404 "app not found".
11
+ * See: https://developers.google.com/workspace/chat/authenticate-authorize
12
+ *
13
+ * Required OAuth scopes: chat.spaces, chat.messages, chat.memberships
11
14
  */
12
15
 
13
16
  import type { AnyAgentTool, ToolCreationOptions } from '../../types.js';
@@ -44,7 +47,7 @@ export function createGoogleChatTools(config: GoogleToolsConfig, _options?: Tool
44
47
  // ─── List Spaces ────────────────────────────────────
45
48
  {
46
49
  name: 'google_chat_list_spaces',
47
- description: 'List Google Chat spaces (rooms, DMs, group conversations) the agent has access to. Returns space names, display names, and types.',
50
+ description: 'List Google Chat spaces (rooms, DMs, group conversations) the agent has access to. NOTE: Requires a Chat app configured in Google Cloud Console — without it, this returns 401/404.',
48
51
  category: 'communication' as const,
49
52
  parameters: {
50
53
  type: 'object' as const,
@@ -42,27 +42,132 @@ export function createGoogleSlidesTools(config: GoogleToolsConfig, _options?: To
42
42
  // ─── Create Presentation ────────────────────────────
43
43
  {
44
44
  name: 'google_slides_create',
45
- description: 'Create a new blank Google Slides presentation with a given title.',
45
+ description: 'Create a new Google Slides presentation with a title slide and optional subtitle. Also accepts an array of content slides to populate the presentation upfront (each with a title and body text). This is the recommended way to create presentations — avoids creating blank decks.',
46
46
  category: 'productivity' as const,
47
47
  parameters: {
48
48
  type: 'object' as const,
49
49
  properties: {
50
- title: { type: 'string', description: 'Presentation title' },
50
+ title: { type: 'string', description: 'Presentation title (shown on title slide)' },
51
+ subtitle: { type: 'string', description: 'Subtitle text for the title slide (e.g. author, date, team)' },
52
+ slides: { type: 'string', description: 'JSON array of content slides: [{"title":"Slide Title","body":"Bullet points or text"},...]' },
51
53
  },
52
54
  required: ['title'],
53
55
  },
54
56
  async execute(_id: string, input: any) {
55
57
  try {
56
58
  const token = await tp.getAccessToken();
59
+ // 1. Create the presentation
57
60
  const result = await slidesApi(token, '/presentations', {
58
61
  method: 'POST',
59
62
  body: { title: input.title },
60
63
  });
64
+ const presentationId = result.presentationId;
65
+ const firstSlide = result.slides?.[0];
66
+
67
+ // 2. Populate the title slide (the default blank slide)
68
+ if (firstSlide) {
69
+ const requests: any[] = [];
70
+ // Find or create a title text box and subtitle text box on the first slide
71
+ const pageElements = firstSlide.pageElements || [];
72
+ // Try to find existing placeholders
73
+ let titlePlaceholder: string | null = null;
74
+ let subtitlePlaceholder: string | null = null;
75
+ for (const el of pageElements) {
76
+ const ph = el.shape?.placeholder;
77
+ if (ph?.type === 'CENTERED_TITLE' || ph?.type === 'TITLE') titlePlaceholder = el.objectId;
78
+ if (ph?.type === 'SUBTITLE') subtitlePlaceholder = el.objectId;
79
+ }
80
+
81
+ // If no placeholders (truly blank), create text boxes
82
+ const PT = 12700; // 1pt in EMU
83
+ if (!titlePlaceholder) {
84
+ const tid = 'title_' + Date.now();
85
+ requests.push({
86
+ createShape: {
87
+ objectId: tid, shapeType: 'TEXT_BOX',
88
+ elementProperties: {
89
+ pageObjectId: firstSlide.objectId,
90
+ size: { width: { magnitude: 600 * PT, unit: 'EMU' }, height: { magnitude: 60 * PT, unit: 'EMU' } },
91
+ transform: { scaleX: 1, scaleY: 1, translateX: 60 * PT, translateY: 150 * PT, unit: 'EMU' },
92
+ },
93
+ },
94
+ });
95
+ requests.push({ insertText: { objectId: tid, text: input.title, insertionIndex: 0 } });
96
+ requests.push({ updateTextStyle: { objectId: tid, style: { fontSize: { magnitude: 36, unit: 'PT' }, bold: true }, textRange: { type: 'ALL' }, fields: 'fontSize,bold' } });
97
+ } else {
98
+ requests.push({ insertText: { objectId: titlePlaceholder, text: input.title, insertionIndex: 0 } });
99
+ }
100
+
101
+ if (input.subtitle) {
102
+ if (!subtitlePlaceholder) {
103
+ const sid = 'subtitle_' + Date.now();
104
+ requests.push({
105
+ createShape: {
106
+ objectId: sid, shapeType: 'TEXT_BOX',
107
+ elementProperties: {
108
+ pageObjectId: firstSlide.objectId,
109
+ size: { width: { magnitude: 500 * PT, unit: 'EMU' }, height: { magnitude: 40 * PT, unit: 'EMU' } },
110
+ transform: { scaleX: 1, scaleY: 1, translateX: 110 * PT, translateY: 240 * PT, unit: 'EMU' },
111
+ },
112
+ },
113
+ });
114
+ requests.push({ insertText: { objectId: sid, text: input.subtitle, insertionIndex: 0 } });
115
+ requests.push({ updateTextStyle: { objectId: sid, style: { fontSize: { magnitude: 20, unit: 'PT' } }, textRange: { type: 'ALL' }, fields: 'fontSize' } });
116
+ } else {
117
+ requests.push({ insertText: { objectId: subtitlePlaceholder, text: input.subtitle, insertionIndex: 0 } });
118
+ }
119
+ }
120
+
121
+ if (requests.length > 0) {
122
+ await slidesApi(token, `/presentations/${presentationId}:batchUpdate`, {
123
+ method: 'POST', body: { requests },
124
+ });
125
+ }
126
+ }
127
+
128
+ // 3. Add content slides if provided
129
+ let contentSlides: any[] = [];
130
+ if (input.slides) {
131
+ try { contentSlides = JSON.parse(input.slides); } catch {}
132
+ }
133
+
134
+ for (const slide of contentSlides) {
135
+ const PT = 12700;
136
+ // Create slide with TITLE_AND_BODY layout
137
+ const addReq: any = { createSlide: { slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' } } };
138
+ const addResult = await slidesApi(token, `/presentations/${presentationId}:batchUpdate`, {
139
+ method: 'POST', body: { requests: [addReq] },
140
+ });
141
+ const newSlideId = addResult.replies?.[0]?.createSlide?.objectId;
142
+ if (!newSlideId) continue;
143
+
144
+ // Get the new slide's placeholders
145
+ const pageResult = await slidesApi(token, `/presentations/${presentationId}/pages/${newSlideId}`);
146
+ const reqs: any[] = [];
147
+ for (const el of (pageResult.pageElements || [])) {
148
+ const ph = el.shape?.placeholder;
149
+ if ((ph?.type === 'TITLE' || ph?.type === 'CENTERED_TITLE') && slide.title) {
150
+ reqs.push({ insertText: { objectId: el.objectId, text: slide.title, insertionIndex: 0 } });
151
+ }
152
+ if (ph?.type === 'BODY' && slide.body) {
153
+ reqs.push({ insertText: { objectId: el.objectId, text: slide.body, insertionIndex: 0 } });
154
+ }
155
+ }
156
+ if (reqs.length > 0) {
157
+ await slidesApi(token, `/presentations/${presentationId}:batchUpdate`, {
158
+ method: 'POST', body: { requests: reqs },
159
+ });
160
+ }
161
+ }
162
+
163
+ // 4. Get final slide count
164
+ const final = await slidesApi(token, `/presentations/${presentationId}`);
61
165
  return jsonResult({
62
- presentationId: result.presentationId,
166
+ presentationId,
63
167
  title: result.title,
64
- url: `https://docs.google.com/presentation/d/${result.presentationId}/edit`,
65
- slideCount: (result.slides || []).length,
168
+ url: `https://docs.google.com/presentation/d/${presentationId}/edit`,
169
+ slideCount: (final.slides || []).length,
170
+ contentSlidesAdded: contentSlides.length,
66
171
  });
67
172
  } catch (e: any) { return errorResult(e.message); }
68
173
  },