apple-mail-mcp 1.5.2 → 1.5.4
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.
|
@@ -13,6 +13,23 @@
|
|
|
13
13
|
* @module services/appleMailManager
|
|
14
14
|
*/
|
|
15
15
|
import type { Message, MessageContent, Mailbox, Account, Attachment, HealthCheckResult, MailStats, BatchOperationResult, SyncStatus, RecentlyReceivedStats, MailRule, Contact, EmailTemplate, SerialEmailRecipient, SerialEmailResult } from "../types.js";
|
|
16
|
+
/**
|
|
17
|
+
* Emits AppleScript that builds a date into the variable `varName` from numeric
|
|
18
|
+
* components.
|
|
19
|
+
*
|
|
20
|
+
* This is locale-independent, unlike `date "May 30, 2026"` string coercion,
|
|
21
|
+
* which AppleScript parses using the system locale. On a non-English locale
|
|
22
|
+
* (e.g. pt_PT) the English month name throws "Invalid date and time (-30720)";
|
|
23
|
+
* because the comparison happens inside the per-message `try` in searchMessages,
|
|
24
|
+
* that error is swallowed and every message is skipped, so the search returns
|
|
25
|
+
* zero results even when matches exist. See issue #15.
|
|
26
|
+
*
|
|
27
|
+
* `day` is reset to 1 before assigning month/year so an existing day-of-month
|
|
28
|
+
* (e.g. 31) cannot overflow into the next month when the month is changed.
|
|
29
|
+
*
|
|
30
|
+
* Exported for unit testing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildAppleScriptDate(varName: string, d: Date): string;
|
|
16
33
|
/**
|
|
17
34
|
* Manager class for Apple Mail operations.
|
|
18
35
|
*
|
|
@@ -237,6 +254,25 @@ export declare class AppleMailManager {
|
|
|
237
254
|
/**
|
|
238
255
|
* Move a message to a different mailbox.
|
|
239
256
|
*/
|
|
257
|
+
/**
|
|
258
|
+
* Move a message to a destination mailbox, with full nested-mailbox support.
|
|
259
|
+
*
|
|
260
|
+
* Resolving the destination as `mailbox "X" of account "Y"` only finds
|
|
261
|
+
* top-level mailboxes, so nested destinations (e.g. a "Moore" subfolder)
|
|
262
|
+
* silently failed. Instead we walk the target account's full mailbox tree and
|
|
263
|
+
* match by name. Resolution is:
|
|
264
|
+
* - account-scoped (won't move to a same-named mailbox in another account)
|
|
265
|
+
* - ambiguity-aware: if the name matches more than one mailbox in the
|
|
266
|
+
* account we refuse to guess and return an error — silently moving mail to
|
|
267
|
+
* the wrong folder is worse than failing.
|
|
268
|
+
* The source message is located by walking every account's tree breadth-first
|
|
269
|
+
* (top-level mailboxes like Inbox are checked first), so messages in nested
|
|
270
|
+
* mailboxes are found too.
|
|
271
|
+
*
|
|
272
|
+
* Returns a result object so batch callers can surface the specific failure
|
|
273
|
+
* (destination not found / ambiguous / message not found).
|
|
274
|
+
*/
|
|
275
|
+
private moveMessageInternal;
|
|
240
276
|
moveMessage(id: string, mailbox: string, account?: string): boolean;
|
|
241
277
|
/**
|
|
242
278
|
* Delete multiple messages at once.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,OAAO,EACP,OAAO,EACP,UAAU,EACV,iBAAiB,EACjB,SAAS,EAET,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,QAAQ,EACR,OAAO,EACP,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,6 +89,34 @@ function parseAppleScriptDate(dateStr) {
|
|
|
89
89
|
const parsed = new Date(normalized);
|
|
90
90
|
return isNaN(parsed.getTime()) ? new Date() : parsed;
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Emits AppleScript that builds a date into the variable `varName` from numeric
|
|
94
|
+
* components.
|
|
95
|
+
*
|
|
96
|
+
* This is locale-independent, unlike `date "May 30, 2026"` string coercion,
|
|
97
|
+
* which AppleScript parses using the system locale. On a non-English locale
|
|
98
|
+
* (e.g. pt_PT) the English month name throws "Invalid date and time (-30720)";
|
|
99
|
+
* because the comparison happens inside the per-message `try` in searchMessages,
|
|
100
|
+
* that error is swallowed and every message is skipped, so the search returns
|
|
101
|
+
* zero results even when matches exist. See issue #15.
|
|
102
|
+
*
|
|
103
|
+
* `day` is reset to 1 before assigning month/year so an existing day-of-month
|
|
104
|
+
* (e.g. 31) cannot overflow into the next month when the month is changed.
|
|
105
|
+
*
|
|
106
|
+
* Exported for unit testing.
|
|
107
|
+
*/
|
|
108
|
+
export function buildAppleScriptDate(varName, d) {
|
|
109
|
+
return [
|
|
110
|
+
`set ${varName} to current date`,
|
|
111
|
+
`set day of ${varName} to 1`,
|
|
112
|
+
`set year of ${varName} to ${d.getFullYear()}`,
|
|
113
|
+
`set month of ${varName} to ${d.getMonth() + 1}`,
|
|
114
|
+
`set day of ${varName} to ${d.getDate()}`,
|
|
115
|
+
`set hours of ${varName} to ${d.getHours()}`,
|
|
116
|
+
`set minutes of ${varName} to ${d.getMinutes()}`,
|
|
117
|
+
`set seconds of ${varName} to ${d.getSeconds()}`,
|
|
118
|
+
].join("\n ");
|
|
119
|
+
}
|
|
92
120
|
/**
|
|
93
121
|
* Builds an AppleScript command scoped to a specific account.
|
|
94
122
|
*/
|
|
@@ -326,18 +354,28 @@ export class AppleMailManager {
|
|
|
326
354
|
// are additional AND filters. Date filtering stays post-fetch below — `whose`
|
|
327
355
|
// date comparisons are unreliable in Mail.app AppleScript. See buildSearchCondition.
|
|
328
356
|
const searchCondition = buildSearchCondition({ query, from, subject, isRead, isFlagged });
|
|
329
|
-
// Build date
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
//
|
|
357
|
+
// Build the date-bound comparison. The comparison dates are constructed in
|
|
358
|
+
// AppleScript from numeric components (see buildAppleScriptDate) and compared
|
|
359
|
+
// against `msgDate` (set per-message below) rather than coerced from a
|
|
360
|
+
// locale-formatted string — `date "May 30, 2026"` throws on non-English system
|
|
361
|
+
// locales, and that swallowed error silently zeroes out results. See issue #15.
|
|
362
|
+
// dateFrom/dateTo are already validated by DATE_FILTER_SCHEMA as parseable dates.
|
|
363
|
+
let dateSetup = "";
|
|
333
364
|
let dateFilter = "";
|
|
334
365
|
if (dateFrom || dateTo) {
|
|
335
366
|
const dateChecks = [];
|
|
336
367
|
if (dateFrom) {
|
|
337
|
-
|
|
368
|
+
dateSetup += buildAppleScriptDate("_dateFrom", new Date(dateFrom)) + "\n ";
|
|
369
|
+
dateChecks.push("msgDate >= _dateFrom");
|
|
338
370
|
}
|
|
339
371
|
if (dateTo) {
|
|
340
|
-
|
|
372
|
+
const to = new Date(dateTo);
|
|
373
|
+
// A date-only upper bound (no time component) is treated as end-of-day so
|
|
374
|
+
// messages received later that same day are still included.
|
|
375
|
+
if (!/\d:\d/.test(dateTo))
|
|
376
|
+
to.setHours(23, 59, 59, 0);
|
|
377
|
+
dateSetup += buildAppleScriptDate("_dateTo", to) + "\n ";
|
|
378
|
+
dateChecks.push("msgDate <= _dateTo");
|
|
341
379
|
}
|
|
342
380
|
dateFilter = dateChecks.join(" and ");
|
|
343
381
|
}
|
|
@@ -346,7 +384,7 @@ export class AppleMailManager {
|
|
|
346
384
|
// Search a specific mailbox
|
|
347
385
|
const targetMailbox = this.resolveMailbox(mailbox, targetAccount);
|
|
348
386
|
searchCommand = `
|
|
349
|
-
set outputText to ""
|
|
387
|
+
${dateSetup}set outputText to ""
|
|
350
388
|
set theMailbox to mailbox "${escapeForAppleScript(targetMailbox)}"
|
|
351
389
|
set allMessages to messages of theMailbox ${searchCondition}
|
|
352
390
|
set msgCount to 0
|
|
@@ -373,7 +411,7 @@ export class AppleMailManager {
|
|
|
373
411
|
else {
|
|
374
412
|
// Search ALL mailboxes — iterate every mailbox in the account, dedup by message ID
|
|
375
413
|
searchCommand = `
|
|
376
|
-
set outputText to ""
|
|
414
|
+
${dateSetup}set outputText to ""
|
|
377
415
|
set msgCount to 0
|
|
378
416
|
set seenIds to {}
|
|
379
417
|
repeat with mb in mailboxes
|
|
@@ -1096,21 +1134,53 @@ export class AppleMailManager {
|
|
|
1096
1134
|
/**
|
|
1097
1135
|
* Move a message to a different mailbox.
|
|
1098
1136
|
*/
|
|
1099
|
-
|
|
1137
|
+
/**
|
|
1138
|
+
* Move a message to a destination mailbox, with full nested-mailbox support.
|
|
1139
|
+
*
|
|
1140
|
+
* Resolving the destination as `mailbox "X" of account "Y"` only finds
|
|
1141
|
+
* top-level mailboxes, so nested destinations (e.g. a "Moore" subfolder)
|
|
1142
|
+
* silently failed. Instead we walk the target account's full mailbox tree and
|
|
1143
|
+
* match by name. Resolution is:
|
|
1144
|
+
* - account-scoped (won't move to a same-named mailbox in another account)
|
|
1145
|
+
* - ambiguity-aware: if the name matches more than one mailbox in the
|
|
1146
|
+
* account we refuse to guess and return an error — silently moving mail to
|
|
1147
|
+
* the wrong folder is worse than failing.
|
|
1148
|
+
* The source message is located by walking every account's tree breadth-first
|
|
1149
|
+
* (top-level mailboxes like Inbox are checked first), so messages in nested
|
|
1150
|
+
* mailboxes are found too.
|
|
1151
|
+
*
|
|
1152
|
+
* Returns a result object so batch callers can surface the specific failure
|
|
1153
|
+
* (destination not found / ambiguous / message not found).
|
|
1154
|
+
*/
|
|
1155
|
+
moveMessageInternal(id, mailbox, account) {
|
|
1100
1156
|
const targetAccount = this.resolveAccount(account);
|
|
1101
1157
|
const targetMailbox = this.resolveMailbox(mailbox, targetAccount);
|
|
1102
1158
|
const safeMailbox = escapeForAppleScript(targetMailbox);
|
|
1103
1159
|
const safeAccount = escapeForAppleScript(targetAccount);
|
|
1104
1160
|
const script = buildAppLevelScript(`
|
|
1105
1161
|
try
|
|
1162
|
+
-- \`mailboxes of account\` is already flat: it includes nested mailboxes
|
|
1163
|
+
-- (named by path, e.g. "Processed/Vendors"). Descending via \`mailboxes of mb\`
|
|
1164
|
+
-- is unreliable (it double-prepends the parent path), so we DON'T recurse —
|
|
1165
|
+
-- we match against this flat list by exact name and use the reference directly
|
|
1166
|
+
-- (addressing \`mailbox "X" of account "Y"\` only finds some top-level mailboxes).
|
|
1167
|
+
set destName to "${safeMailbox}"
|
|
1168
|
+
set destMatches to {}
|
|
1169
|
+
repeat with mb in (mailboxes of account "${safeAccount}")
|
|
1170
|
+
if (name of mb) is destName then set end of destMatches to mb
|
|
1171
|
+
end repeat
|
|
1172
|
+
if (count of destMatches) is 0 then return "error:Destination mailbox \\"" & destName & "\\" not found in account \\"${safeAccount}\\""
|
|
1173
|
+
if (count of destMatches) > 1 then return "error:Destination mailbox \\"" & destName & "\\" is ambiguous (" & (count of destMatches) & " matches) in account \\"${safeAccount}\\"; disambiguate or move by full path"
|
|
1174
|
+
set destMailbox to item 1 of destMatches
|
|
1175
|
+
|
|
1176
|
+
-- Find the message by id. The flat mailbox list already covers nested
|
|
1177
|
+
-- mailboxes, so this reaches messages in subfolders without recursing.
|
|
1106
1178
|
repeat with acct in accounts
|
|
1107
|
-
repeat with mb in mailboxes of acct
|
|
1179
|
+
repeat with mb in (mailboxes of acct)
|
|
1108
1180
|
try
|
|
1109
1181
|
set matchingMsgs to (messages of mb whose id is ${Number(id)})
|
|
1110
1182
|
if (count of matchingMsgs) > 0 then
|
|
1111
|
-
|
|
1112
|
-
set destMailbox to mailbox "${safeMailbox}" of account "${safeAccount}"
|
|
1113
|
-
move msg to destMailbox
|
|
1183
|
+
move (item 1 of matchingMsgs) to destMailbox
|
|
1114
1184
|
return "ok"
|
|
1115
1185
|
end if
|
|
1116
1186
|
end try
|
|
@@ -1121,12 +1191,21 @@ export class AppleMailManager {
|
|
|
1121
1191
|
return "error:" & errMsg
|
|
1122
1192
|
end try
|
|
1123
1193
|
`);
|
|
1124
|
-
const result = executeAppleScript(script, { timeoutMs:
|
|
1125
|
-
if (!result.success
|
|
1126
|
-
|
|
1127
|
-
return false;
|
|
1194
|
+
const result = executeAppleScript(script, { timeoutMs: 90000 });
|
|
1195
|
+
if (!result.success) {
|
|
1196
|
+
return { success: false, error: result.error || "AppleScript execution failed" };
|
|
1128
1197
|
}
|
|
1129
|
-
|
|
1198
|
+
if (result.output.startsWith("error:")) {
|
|
1199
|
+
return { success: false, error: result.output.slice("error:".length) };
|
|
1200
|
+
}
|
|
1201
|
+
return { success: true };
|
|
1202
|
+
}
|
|
1203
|
+
moveMessage(id, mailbox, account) {
|
|
1204
|
+
const { success, error } = this.moveMessageInternal(id, mailbox, account);
|
|
1205
|
+
if (!success) {
|
|
1206
|
+
console.error(`Failed to move message: ${error}`);
|
|
1207
|
+
}
|
|
1208
|
+
return success;
|
|
1130
1209
|
}
|
|
1131
1210
|
// ===========================================================================
|
|
1132
1211
|
// Batch Operations
|
|
@@ -1160,11 +1239,11 @@ export class AppleMailManager {
|
|
|
1160
1239
|
batchMoveMessages(ids, mailbox, account) {
|
|
1161
1240
|
const results = [];
|
|
1162
1241
|
for (const id of ids) {
|
|
1163
|
-
const success = this.
|
|
1242
|
+
const { success, error } = this.moveMessageInternal(id, mailbox, account);
|
|
1164
1243
|
results.push({
|
|
1165
1244
|
id,
|
|
1166
1245
|
success,
|
|
1167
|
-
error: success ? undefined : "Failed to move message",
|
|
1246
|
+
error: success ? undefined : error || "Failed to move message",
|
|
1168
1247
|
});
|
|
1169
1248
|
}
|
|
1170
1249
|
return results;
|