@aaronsb/google-workspace-mcp 2.1.0 → 2.3.0
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.
- package/build/__tests__/executor/workspace.test.js +39 -13
- package/build/__tests__/executor/workspace.test.js.map +1 -1
- package/build/__tests__/services/gmail/mime.test.js +1 -161
- package/build/__tests__/services/gmail/mime.test.js.map +1 -1
- package/build/executor/file-output.d.ts +12 -1
- package/build/executor/file-output.js +52 -1
- package/build/executor/file-output.js.map +1 -1
- package/build/executor/workspace.d.ts +8 -2
- package/build/executor/workspace.js +22 -3
- package/build/executor/workspace.js.map +1 -1
- package/build/factory/manifest.yaml +32 -3
- package/build/server/formatting/markdown.d.ts +8 -0
- package/build/server/formatting/markdown.js.map +1 -1
- package/build/server/handlers/workspace.d.ts +1 -1
- package/build/server/handlers/workspace.js +223 -23
- package/build/server/handlers/workspace.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email-draft.d.ts +1 -0
- package/build/server/scratchpad/adapters/send-email-draft.js +21 -20
- package/build/server/scratchpad/adapters/send-email-draft.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email.d.ts +2 -1
- package/build/server/scratchpad/adapters/send-email.js +25 -37
- package/build/server/scratchpad/adapters/send-email.js.map +1 -1
- package/build/server/server.js +7 -3
- package/build/server/server.js.map +1 -1
- package/build/server/tools.js +8 -5
- package/build/server/tools.js.map +1 -1
- package/build/services/drive/patch.js +47 -1
- package/build/services/drive/patch.js.map +1 -1
- package/build/services/gmail/attachments.d.ts +9 -10
- package/build/services/gmail/attachments.js +39 -17
- package/build/services/gmail/attachments.js.map +1 -1
- package/build/services/gmail/mime.d.ts +4 -24
- package/build/services/gmail/mime.js +4 -93
- package/build/services/gmail/mime.js.map +1 -1
- package/build/services/gmail/patch.js +31 -38
- package/build/services/gmail/patch.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
package/build/server/tools.js
CHANGED
|
@@ -29,17 +29,20 @@ const handCodedSchemas = [
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: 'manage_workspace',
|
|
32
|
-
description: '
|
|
32
|
+
description: 'Manage files and directories in the workspace sandbox. Supports nested paths (e.g. "reports/q1/summary.csv"). The workspace is the exchange point for file operations (attachments, downloads, exports).',
|
|
33
33
|
inputSchema: {
|
|
34
34
|
type: 'object',
|
|
35
35
|
properties: {
|
|
36
36
|
operation: {
|
|
37
37
|
type: 'string',
|
|
38
|
-
enum: ['list', 'read', 'write', 'delete'],
|
|
39
|
-
description: 'list: show files
|
|
38
|
+
enum: ['list', 'read', 'write', 'delete', 'move', 'mkdir', 'compress', 'decompress'],
|
|
39
|
+
description: 'list: show files (recursive) | read: get file content | write: save content to file | delete: remove file or directory | move: move or rename a file/directory | mkdir: create a directory | compress: gzip a file | decompress: gunzip a file',
|
|
40
40
|
},
|
|
41
|
-
filename: { type: 'string', description: 'File
|
|
41
|
+
filename: { type: 'string', description: 'File path, may include directories (for read, write, delete, compress, decompress). E.g. "reports/q1/summary.csv"' },
|
|
42
42
|
content: { type: 'string', description: 'File content to write (for write)' },
|
|
43
|
+
path: { type: 'string', description: 'Directory path (for list: scope to subdirectory, for mkdir: directory to create)' },
|
|
44
|
+
source: { type: 'string', description: 'Source path (for move)' },
|
|
45
|
+
destination: { type: 'string', description: 'Destination path (for move, compress, decompress). Defaults to filename.gz for compress, strips .gz for decompress.' },
|
|
43
46
|
},
|
|
44
47
|
required: ['operation'],
|
|
45
48
|
additionalProperties: false,
|
|
@@ -105,7 +108,7 @@ const handCodedSchemas = [
|
|
|
105
108
|
properties: {
|
|
106
109
|
tool: {
|
|
107
110
|
type: 'string',
|
|
108
|
-
enum: ['manage_email', 'manage_calendar', 'manage_drive', 'manage_accounts', 'manage_scratchpad'],
|
|
111
|
+
enum: ['manage_email', 'manage_calendar', 'manage_drive', 'manage_accounts', 'manage_scratchpad', 'manage_workspace'],
|
|
109
112
|
description: 'Tool to call',
|
|
110
113
|
},
|
|
111
114
|
args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAQxD,qDAAqD;AACrD,MAAM,gBAAgB,GAAiB;IACrC;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,sIAAsI;QACnJ,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC;oBACvF,WAAW,EAAE,+TAA+T;iBAC7U;gBACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8CAA8C,EAAE;gBACtF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,sCAAsC,EAAE;gBACtH,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;gBACjF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+EAA+E,EAAE;aAC3H;YACD,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,oBAAoB,EAAE,KAAK;SAC5B;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
* - Download/Export: save to workspace via gws --output, return inline for text
|
|
8
8
|
*/
|
|
9
9
|
import * as fs from 'node:fs/promises';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
import * as path from 'node:path';
|
|
10
12
|
import { execute } from '../../executor/gws.js';
|
|
11
13
|
import { formatFileList, formatFileDetail } from '../../server/formatting/markdown.js';
|
|
12
14
|
import { nextSteps } from '../../server/formatting/next-steps.js';
|
|
13
15
|
import { requireString } from '../../server/handlers/validate.js';
|
|
14
16
|
import { ensureWorkspaceDir, resolveWorkspacePath, verifyPathSafety } from '../../executor/workspace.js';
|
|
15
|
-
import { isTextFile, formatFileOutput } from '../../executor/file-output.js';
|
|
17
|
+
import { isTextFile, formatFileOutput, buildImageBlock, buildImageBlockFromFile, isImageFile } from '../../executor/file-output.js';
|
|
16
18
|
/** Read a file from workspace and build the output result with optional inline content. */
|
|
17
19
|
async function readWorkspaceFile(filePath, filename, mimeType) {
|
|
18
20
|
const stat = await fs.stat(filePath);
|
|
@@ -24,6 +26,11 @@ async function readWorkspaceFile(filePath, filename, mimeType) {
|
|
|
24
26
|
if (isTextFile(filename, mimeType) && stat.size < 100_000) {
|
|
25
27
|
result.content = await fs.readFile(filePath, 'utf-8');
|
|
26
28
|
}
|
|
29
|
+
else {
|
|
30
|
+
const imageBlock = await buildImageBlockFromFile(filePath, filename, mimeType);
|
|
31
|
+
if (imageBlock)
|
|
32
|
+
result.imageBlock = imageBlock;
|
|
33
|
+
}
|
|
27
34
|
return result;
|
|
28
35
|
}
|
|
29
36
|
export const drivePatch = {
|
|
@@ -77,8 +84,46 @@ export const drivePatch = {
|
|
|
77
84
|
size: output.size,
|
|
78
85
|
...(output.content ? { content: output.content } : {}),
|
|
79
86
|
},
|
|
87
|
+
...(output.imageBlock ? { content: [output.imageBlock] } : {}),
|
|
80
88
|
};
|
|
81
89
|
},
|
|
90
|
+
viewImage: async (params, account) => {
|
|
91
|
+
const fileId = requireString(params, 'fileId');
|
|
92
|
+
// Get file metadata
|
|
93
|
+
const metaResult = await execute([
|
|
94
|
+
'drive', 'files', 'get',
|
|
95
|
+
'--params', JSON.stringify({ fileId, fields: 'name,mimeType,size' }),
|
|
96
|
+
], { account });
|
|
97
|
+
const meta = metaResult.data;
|
|
98
|
+
const filename = String(meta.name || `image-${fileId}`);
|
|
99
|
+
const mimeType = String(meta.mimeType || '');
|
|
100
|
+
if (!isImageFile(filename, mimeType)) {
|
|
101
|
+
throw new Error(`File "${filename}" (${mimeType}) is not a viewable image type`);
|
|
102
|
+
}
|
|
103
|
+
// Download to temp file, read into memory, clean up
|
|
104
|
+
const safeId = fileId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
105
|
+
const tmpPath = path.join(os.tmpdir(), `gws-view-${safeId}-${Date.now()}`);
|
|
106
|
+
try {
|
|
107
|
+
await execute([
|
|
108
|
+
'drive', 'files', 'get',
|
|
109
|
+
'--params', JSON.stringify({ fileId, alt: 'media' }),
|
|
110
|
+
'--output', tmpPath,
|
|
111
|
+
], { account });
|
|
112
|
+
const buffer = await fs.readFile(tmpPath);
|
|
113
|
+
const imageBlock = buildImageBlock(buffer, filename, mimeType);
|
|
114
|
+
if (!imageBlock) {
|
|
115
|
+
throw new Error(`Image too large to view inline (${(buffer.length / 1024 / 1024).toFixed(1)} MB). Use download instead.`);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
text: `## ${filename}\n\n**Type:** ${mimeType}\n**Size:** ${buffer.length} bytes\n\n_Image displayed inline below. Use download to save to workspace._`,
|
|
119
|
+
refs: { fileId, filename, mimeType, size: buffer.length },
|
|
120
|
+
content: [imageBlock],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
await fs.unlink(tmpPath).catch(() => { });
|
|
125
|
+
}
|
|
126
|
+
},
|
|
82
127
|
export: async (params, account) => {
|
|
83
128
|
const fileId = requireString(params, 'fileId');
|
|
84
129
|
const mimeType = requireString(params, 'mimeType');
|
|
@@ -124,6 +169,7 @@ export const drivePatch = {
|
|
|
124
169
|
mimeType,
|
|
125
170
|
...(output.content ? { content: output.content } : {}),
|
|
126
171
|
},
|
|
172
|
+
...(output.imageBlock ? { content: [output.imageBlock] } : {}),
|
|
127
173
|
};
|
|
128
174
|
},
|
|
129
175
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../../../src/services/drive/patch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../../../src/services/drive/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Gmail attachment handler — downloads email attachments
|
|
2
|
+
* Gmail attachment handler — downloads or views email attachments.
|
|
3
3
|
*
|
|
4
4
|
* The agent discovers attachments via the `read` operation, which lists
|
|
5
|
-
* filenames and sizes. Then calls `getAttachment`
|
|
6
|
-
*
|
|
7
|
-
* the message payload. This keeps long Gmail attachment IDs out of the
|
|
8
|
-
* agent's context.
|
|
5
|
+
* filenames and sizes. Then calls `getAttachment` to save to workspace,
|
|
6
|
+
* or `viewAttachment` to view images inline without saving.
|
|
9
7
|
*
|
|
10
|
-
* Flow: read → see filenames → getAttachment(messageId, filename)
|
|
8
|
+
* Flow: read → see filenames → getAttachment/viewAttachment(messageId, filename)
|
|
11
9
|
*/
|
|
12
10
|
import type { HandlerResponse } from '../../server/formatting/markdown.js';
|
|
13
11
|
/**
|
|
14
|
-
* Download an email attachment by filename.
|
|
15
|
-
*
|
|
16
|
-
* Resolves the attachment ID internally by reading the message payload —
|
|
17
|
-
* the agent only needs to provide messageId and filename (from the read response).
|
|
12
|
+
* Download an email attachment by filename — saves to workspace.
|
|
18
13
|
*/
|
|
19
14
|
export declare function handleGetAttachment(params: Record<string, unknown>, account: string): Promise<HandlerResponse>;
|
|
15
|
+
/**
|
|
16
|
+
* View an image attachment inline without saving to workspace.
|
|
17
|
+
*/
|
|
18
|
+
export declare function handleViewAttachment(params: Record<string, unknown>, account: string): Promise<HandlerResponse>;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Gmail attachment handler — downloads email attachments
|
|
2
|
+
* Gmail attachment handler — downloads or views email attachments.
|
|
3
3
|
*
|
|
4
4
|
* The agent discovers attachments via the `read` operation, which lists
|
|
5
|
-
* filenames and sizes. Then calls `getAttachment`
|
|
6
|
-
*
|
|
7
|
-
* the message payload. This keeps long Gmail attachment IDs out of the
|
|
8
|
-
* agent's context.
|
|
5
|
+
* filenames and sizes. Then calls `getAttachment` to save to workspace,
|
|
6
|
+
* or `viewAttachment` to view images inline without saving.
|
|
9
7
|
*
|
|
10
|
-
* Flow: read → see filenames → getAttachment(messageId, filename)
|
|
8
|
+
* Flow: read → see filenames → getAttachment/viewAttachment(messageId, filename)
|
|
11
9
|
*/
|
|
12
10
|
import { execute } from '../../executor/gws.js';
|
|
13
11
|
import { requireString } from '../../server/handlers/validate.js';
|
|
14
|
-
import { saveToWorkspace, formatFileOutput } from '../../executor/file-output.js';
|
|
12
|
+
import { saveToWorkspace, formatFileOutput, isImageFile, buildImageBlock, getImageMimeType } from '../../executor/file-output.js';
|
|
15
13
|
/** Walk message parts recursively to find attachments. */
|
|
16
14
|
function findAttachments(parts) {
|
|
17
15
|
const attachments = [];
|
|
@@ -34,15 +32,8 @@ function findAttachments(parts) {
|
|
|
34
32
|
}
|
|
35
33
|
return attachments;
|
|
36
34
|
}
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
* Resolves the attachment ID internally by reading the message payload —
|
|
41
|
-
* the agent only needs to provide messageId and filename (from the read response).
|
|
42
|
-
*/
|
|
43
|
-
export async function handleGetAttachment(params, account) {
|
|
44
|
-
const messageId = requireString(params, 'messageId');
|
|
45
|
-
const filename = requireString(params, 'filename');
|
|
35
|
+
/** Fetch raw attachment data by messageId and filename. Returns the buffer and metadata. */
|
|
36
|
+
async function fetchAttachmentData(messageId, filename, account) {
|
|
46
37
|
// Read the message to find the attachment ID for this filename
|
|
47
38
|
const msgResult = await execute([
|
|
48
39
|
'gmail', 'users', 'messages', 'get',
|
|
@@ -74,7 +65,15 @@ export async function handleGetAttachment(params, account) {
|
|
|
74
65
|
// Decode base64url to buffer
|
|
75
66
|
const base64Standard = base64Data.replace(/-/g, '+').replace(/_/g, '/');
|
|
76
67
|
const buffer = Buffer.from(base64Standard, 'base64');
|
|
77
|
-
|
|
68
|
+
return { buffer, match };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Download an email attachment by filename — saves to workspace.
|
|
72
|
+
*/
|
|
73
|
+
export async function handleGetAttachment(params, account) {
|
|
74
|
+
const messageId = requireString(params, 'messageId');
|
|
75
|
+
const filename = requireString(params, 'filename');
|
|
76
|
+
const { buffer, match } = await fetchAttachmentData(messageId, filename, account);
|
|
78
77
|
const output = await saveToWorkspace(filename, buffer, match.mimeType);
|
|
79
78
|
return {
|
|
80
79
|
text: formatFileOutput(output),
|
|
@@ -85,6 +84,29 @@ export async function handleGetAttachment(params, account) {
|
|
|
85
84
|
messageId,
|
|
86
85
|
...(output.content ? { content: output.content } : {}),
|
|
87
86
|
},
|
|
87
|
+
...(output.imageBlock ? { content: [output.imageBlock] } : {}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* View an image attachment inline without saving to workspace.
|
|
92
|
+
*/
|
|
93
|
+
export async function handleViewAttachment(params, account) {
|
|
94
|
+
const messageId = requireString(params, 'messageId');
|
|
95
|
+
const filename = requireString(params, 'filename');
|
|
96
|
+
const { buffer, match } = await fetchAttachmentData(messageId, filename, account);
|
|
97
|
+
if (!isImageFile(filename, match.mimeType)) {
|
|
98
|
+
throw new Error(`"${filename}" (${match.mimeType}) is not a viewable image type. ` +
|
|
99
|
+
`Use getAttachment to download it instead.`);
|
|
100
|
+
}
|
|
101
|
+
const imageBlock = buildImageBlock(buffer, filename, match.mimeType);
|
|
102
|
+
if (!imageBlock) {
|
|
103
|
+
throw new Error(`Image too large to view inline (${(buffer.length / 1024 / 1024).toFixed(1)} MB). ` +
|
|
104
|
+
`Use getAttachment to download it instead.`);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
text: `## ${filename}\n\n**Type:** ${getImageMimeType(filename, match.mimeType)}\n**Size:** ${buffer.length} bytes\n\n_Image displayed inline below. Use getAttachment to save to workspace._`,
|
|
108
|
+
refs: { filename, messageId, mimeType: match.mimeType, size: buffer.length },
|
|
109
|
+
content: [imageBlock],
|
|
88
110
|
};
|
|
89
111
|
}
|
|
90
112
|
//# sourceMappingURL=attachments.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/services/gmail/attachments.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/services/gmail/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MIME
|
|
2
|
+
* MIME type lookup utility.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The MIME message builder that used to live here was removed when gws 0.18+
|
|
5
|
+
* added native --attach support to mail helpers. MIME construction is now
|
|
6
|
+
* handled by the gws CLI directly.
|
|
7
7
|
*/
|
|
8
|
-
export interface MimeAttachment {
|
|
9
|
-
filename: string;
|
|
10
|
-
mimeType: string;
|
|
11
|
-
content: Buffer;
|
|
12
|
-
}
|
|
13
|
-
export interface MimeMessageOptions {
|
|
14
|
-
to: string;
|
|
15
|
-
subject: string;
|
|
16
|
-
body: string;
|
|
17
|
-
html?: boolean;
|
|
18
|
-
cc?: string;
|
|
19
|
-
bcc?: string;
|
|
20
|
-
from?: string;
|
|
21
|
-
attachments: MimeAttachment[];
|
|
22
|
-
}
|
|
23
8
|
/** Look up MIME type by filename extension. */
|
|
24
9
|
export declare function lookupMimeType(filename: string): string;
|
|
25
|
-
/**
|
|
26
|
-
* Build a MIME multipart/mixed message and return it as a base64url string
|
|
27
|
-
* ready for the Gmail API `raw` field.
|
|
28
|
-
*/
|
|
29
|
-
export declare function buildMimeMessage(options: MimeMessageOptions): string;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MIME
|
|
2
|
+
* MIME type lookup utility.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The MIME message builder that used to live here was removed when gws 0.18+
|
|
5
|
+
* added native --attach support to mail helpers. MIME construction is now
|
|
6
|
+
* handled by the gws CLI directly.
|
|
7
7
|
*/
|
|
8
|
-
import { randomUUID } from 'node:crypto';
|
|
9
8
|
/** Common extension → MIME type map. Falls back to application/octet-stream. */
|
|
10
9
|
const MIME_TYPES = {
|
|
11
10
|
'.md': 'text/markdown',
|
|
@@ -47,92 +46,4 @@ export function lookupMimeType(filename) {
|
|
|
47
46
|
const ext = filename.slice(dotIndex).toLowerCase();
|
|
48
47
|
return MIME_TYPES[ext] ?? 'application/octet-stream';
|
|
49
48
|
}
|
|
50
|
-
/** Truncate at first CRLF to prevent MIME header injection. */
|
|
51
|
-
function sanitizeHeader(value) {
|
|
52
|
-
const crlfIndex = value.search(/[\r\n]/);
|
|
53
|
-
return crlfIndex === -1 ? value : value.slice(0, crlfIndex);
|
|
54
|
-
}
|
|
55
|
-
/** Encode a subject line per RFC 2047 if it contains non-ASCII characters. */
|
|
56
|
-
function encodeSubject(subject) {
|
|
57
|
-
const safe = sanitizeHeader(subject);
|
|
58
|
-
// eslint-disable-next-line no-control-regex
|
|
59
|
-
if (/^[\x20-\x7e]*$/.test(safe))
|
|
60
|
-
return safe;
|
|
61
|
-
const encoded = Buffer.from(safe, 'utf-8').toString('base64');
|
|
62
|
-
return `=?UTF-8?B?${encoded}?=`;
|
|
63
|
-
}
|
|
64
|
-
/** Wrap base64 string into 76-character lines per MIME spec. */
|
|
65
|
-
function wrapBase64(data) {
|
|
66
|
-
const lines = [];
|
|
67
|
-
for (let i = 0; i < data.length; i += 76) {
|
|
68
|
-
lines.push(data.slice(i, i + 76));
|
|
69
|
-
}
|
|
70
|
-
return lines.join('\r\n');
|
|
71
|
-
}
|
|
72
|
-
/** Gmail API maximum raw message size (simple upload). */
|
|
73
|
-
const MAX_RAW_SIZE = 5 * 1024 * 1024;
|
|
74
|
-
/**
|
|
75
|
-
* Build a MIME multipart/mixed message and return it as a base64url string
|
|
76
|
-
* ready for the Gmail API `raw` field.
|
|
77
|
-
*/
|
|
78
|
-
export function buildMimeMessage(options) {
|
|
79
|
-
const { to, subject, body, html, cc, bcc, from, attachments } = options;
|
|
80
|
-
const boundary = `----=_Part_${randomUUID()}`;
|
|
81
|
-
// Headers (sanitize all values to prevent CRLF injection)
|
|
82
|
-
const headers = [
|
|
83
|
-
`MIME-Version: 1.0`,
|
|
84
|
-
`Content-Type: multipart/mixed; boundary="${boundary}"`,
|
|
85
|
-
`To: ${sanitizeHeader(to)}`,
|
|
86
|
-
`Subject: ${encodeSubject(subject)}`,
|
|
87
|
-
];
|
|
88
|
-
if (from)
|
|
89
|
-
headers.push(`From: ${sanitizeHeader(from)}`);
|
|
90
|
-
if (cc)
|
|
91
|
-
headers.push(`Cc: ${sanitizeHeader(cc)}`);
|
|
92
|
-
if (bcc)
|
|
93
|
-
headers.push(`Bcc: ${sanitizeHeader(bcc)}`);
|
|
94
|
-
// Body part
|
|
95
|
-
const bodyContentType = html ? 'text/html; charset=UTF-8' : 'text/plain; charset=UTF-8';
|
|
96
|
-
const bodyBase64 = wrapBase64(Buffer.from(body, 'utf-8').toString('base64'));
|
|
97
|
-
const bodyPart = [
|
|
98
|
-
`--${boundary}`,
|
|
99
|
-
`Content-Type: ${bodyContentType}`,
|
|
100
|
-
`Content-Transfer-Encoding: base64`,
|
|
101
|
-
'',
|
|
102
|
-
bodyBase64,
|
|
103
|
-
].join('\r\n');
|
|
104
|
-
// Attachment parts (sanitize filenames for MIME headers)
|
|
105
|
-
const attachmentParts = attachments.map(att => {
|
|
106
|
-
const safeName = sanitizeHeader(att.filename).replace(/"/g, '\\"');
|
|
107
|
-
const attBase64 = wrapBase64(att.content.toString('base64'));
|
|
108
|
-
return [
|
|
109
|
-
`--${boundary}`,
|
|
110
|
-
`Content-Type: ${att.mimeType}; name="${safeName}"`,
|
|
111
|
-
`Content-Disposition: attachment; filename="${safeName}"`,
|
|
112
|
-
`Content-Transfer-Encoding: base64`,
|
|
113
|
-
'',
|
|
114
|
-
attBase64,
|
|
115
|
-
].join('\r\n');
|
|
116
|
-
});
|
|
117
|
-
// Assemble message
|
|
118
|
-
const message = [
|
|
119
|
-
headers.join('\r\n'),
|
|
120
|
-
'',
|
|
121
|
-
bodyPart,
|
|
122
|
-
...attachmentParts,
|
|
123
|
-
`--${boundary}--`,
|
|
124
|
-
].join('\r\n');
|
|
125
|
-
// Base64url encode for Gmail API
|
|
126
|
-
const raw = Buffer.from(message, 'utf-8')
|
|
127
|
-
.toString('base64')
|
|
128
|
-
.replace(/\+/g, '-')
|
|
129
|
-
.replace(/\//g, '_')
|
|
130
|
-
.replace(/=+$/, '');
|
|
131
|
-
if (raw.length > MAX_RAW_SIZE) {
|
|
132
|
-
const sizeMB = (raw.length / (1024 * 1024)).toFixed(1);
|
|
133
|
-
throw new Error(`Message size (${sizeMB}MB) exceeds Gmail's 5MB limit for simple upload. ` +
|
|
134
|
-
`Reduce attachment size or number of attachments.`);
|
|
135
|
-
}
|
|
136
|
-
return raw;
|
|
137
|
-
}
|
|
138
49
|
//# sourceMappingURL=mime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../../../src/services/gmail/mime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../../../src/services/gmail/mime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gFAAgF;AAChF,MAAM,UAAU,GAA2B;IACzC,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,kBAAkB;IACzB,MAAM,EAAE,mBAAmB;IAC3B,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,oBAAoB;IAC5B,OAAO,EAAE,yEAAyE;IAClF,MAAM,EAAE,0BAA0B;IAClC,OAAO,EAAE,mEAAmE;IAC5E,MAAM,EAAE,+BAA+B;IACvC,OAAO,EAAE,2EAA2E;IACpF,OAAO,EAAE,oBAAoB;IAC7B,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE,wBAAwB;IAC/B,KAAK,EAAE,mBAAmB;IAC1B,KAAK,EAAE,eAAe;IACtB,KAAK,EAAE,kBAAkB;CAC1B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,OAAO,0BAA0B,CAAC;IACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;AACvD,CAAC"}
|
|
@@ -6,14 +6,12 @@
|
|
|
6
6
|
* - Custom formatters: pipe-delimited list, header-extracted detail
|
|
7
7
|
* - Custom handlers: send/reply use specific response formatting
|
|
8
8
|
*/
|
|
9
|
-
import * as fs from 'node:fs/promises';
|
|
10
9
|
import { execute } from '../../executor/gws.js';
|
|
11
10
|
import { resolveWorkspacePath, verifyPathSafety } from '../../executor/workspace.js';
|
|
12
11
|
import { formatEmailList, formatEmailDetail, extractBodyFromPayload } from '../../server/formatting/markdown.js';
|
|
13
12
|
import { nextSteps } from '../../server/formatting/next-steps.js';
|
|
14
13
|
import { requireString } from '../../server/handlers/validate.js';
|
|
15
|
-
import { handleGetAttachment } from './attachments.js';
|
|
16
|
-
import { buildMimeMessage, lookupMimeType } from './mime.js';
|
|
14
|
+
import { handleGetAttachment, handleViewAttachment } from './attachments.js';
|
|
17
15
|
/**
|
|
18
16
|
* Hydrate message IDs with metadata (From, Subject, Date, snippet).
|
|
19
17
|
* Reused from the original email handler.
|
|
@@ -137,14 +135,12 @@ function formatThreadDetail(data) {
|
|
|
137
135
|
},
|
|
138
136
|
};
|
|
139
137
|
}
|
|
140
|
-
/**
|
|
141
|
-
async function
|
|
138
|
+
/** Resolve workspace attachment paths safely. Returns absolute paths. */
|
|
139
|
+
async function resolveAttachmentPaths(filenames) {
|
|
142
140
|
return Promise.all(filenames.map(async (name) => {
|
|
143
141
|
const filePath = resolveWorkspacePath(name);
|
|
144
142
|
await verifyPathSafety(filePath);
|
|
145
|
-
|
|
146
|
-
const mimeType = lookupMimeType(name);
|
|
147
|
-
return { filename: name, mimeType, content };
|
|
143
|
+
return filePath;
|
|
148
144
|
}));
|
|
149
145
|
}
|
|
150
146
|
export const gmailPatch = {
|
|
@@ -189,46 +185,42 @@ export const gmailPatch = {
|
|
|
189
185
|
const to = requireString(params, 'to');
|
|
190
186
|
const subject = requireString(params, 'subject');
|
|
191
187
|
const body = requireString(params, 'body');
|
|
188
|
+
const draft = params.draft === true || params.draft === 'true';
|
|
192
189
|
const attachmentNames = params.attachments
|
|
193
190
|
? String(params.attachments).split(',').map(s => s.trim()).filter(Boolean)
|
|
194
191
|
: [];
|
|
195
|
-
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const raw = buildMimeMessage({
|
|
211
|
-
to, subject, body,
|
|
212
|
-
html: params.html === true || params.html === 'true',
|
|
213
|
-
cc: params.cc ? String(params.cc) : undefined,
|
|
214
|
-
bcc: params.bcc ? String(params.bcc) : undefined,
|
|
215
|
-
from: account,
|
|
216
|
-
attachments,
|
|
217
|
-
});
|
|
218
|
-
result = await execute([
|
|
219
|
-
'gmail', 'users', 'messages', 'send',
|
|
220
|
-
'--params', JSON.stringify({ userId: 'me' }),
|
|
221
|
-
'--json', JSON.stringify({ raw }),
|
|
222
|
-
], { account });
|
|
192
|
+
const args = ['gmail', '+send', '--to', to, '--subject', subject, '--body', body];
|
|
193
|
+
if (params.cc)
|
|
194
|
+
args.push('--cc', String(params.cc));
|
|
195
|
+
if (params.bcc)
|
|
196
|
+
args.push('--bcc', String(params.bcc));
|
|
197
|
+
if (params.html === true || params.html === 'true')
|
|
198
|
+
args.push('--html');
|
|
199
|
+
if (draft || attachmentNames.length > 0)
|
|
200
|
+
args.push('--draft');
|
|
201
|
+
// Resolve and attach workspace files via gws --attach (uses upload endpoint, 35MB limit)
|
|
202
|
+
if (attachmentNames.length > 0) {
|
|
203
|
+
const paths = await resolveAttachmentPaths(attachmentNames);
|
|
204
|
+
for (const p of paths) {
|
|
205
|
+
args.push('--attach', p);
|
|
206
|
+
}
|
|
223
207
|
}
|
|
208
|
+
const result = await execute(args, { account });
|
|
224
209
|
const data = result.data;
|
|
225
210
|
const attachNote = attachmentNames.length > 0
|
|
226
211
|
? `\n**Attachments:** ${attachmentNames.join(', ')}`
|
|
227
212
|
: '';
|
|
213
|
+
if (draft || attachmentNames.length > 0) {
|
|
214
|
+
return {
|
|
215
|
+
text: `Draft created for ${to}.\n\n**Subject:** ${subject}${attachNote}\n**Draft ID:** ${data.id ?? 'unknown'}` +
|
|
216
|
+
nextSteps('email', 'draft', { email: account }),
|
|
217
|
+
refs: { id: data.id, draftId: data.id, to, subject, attachments: attachmentNames, isDraft: true },
|
|
218
|
+
};
|
|
219
|
+
}
|
|
228
220
|
return {
|
|
229
|
-
text: `Email sent to ${to}.\n\n**Subject:** ${subject}
|
|
221
|
+
text: `Email sent to ${to}.\n\n**Subject:** ${subject}\n**Message ID:** ${data.id ?? 'unknown'}` +
|
|
230
222
|
nextSteps('email', 'send', { email: account }),
|
|
231
|
-
refs: { id: data.id, threadId: data.threadId, to, subject
|
|
223
|
+
refs: { id: data.id, threadId: data.threadId, to, subject },
|
|
232
224
|
};
|
|
233
225
|
},
|
|
234
226
|
modify: async (params, account) => {
|
|
@@ -261,6 +253,7 @@ export const gmailPatch = {
|
|
|
261
253
|
};
|
|
262
254
|
},
|
|
263
255
|
getAttachment: handleGetAttachment,
|
|
256
|
+
viewAttachment: handleViewAttachment,
|
|
264
257
|
reply: async (params, account) => {
|
|
265
258
|
const messageId = requireString(params, 'messageId');
|
|
266
259
|
const body = requireString(params, 'body');
|