apple-mail-mcp 1.6.9 → 1.6.10
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/README.md
CHANGED
|
@@ -800,6 +800,7 @@ The entrypoint is written as:
|
|
|
800
800
|
| Attachments require absolute paths | File attachments must use full absolute paths (e.g., `/Users/me/file.pdf`) |
|
|
801
801
|
| No smart mailboxes | Cannot access Smart Mailboxes via AppleScript |
|
|
802
802
|
| Very large mailboxes not searchable | Apple Mail's AppleScript bridge times out on mailboxes with tens of thousands of messages, so unscoped `search-messages` skips mailboxes above `APPLE_MAIL_MAX_SEARCH_MAILBOX` (default 5000) and reports them as a partial result. Scope with `mailbox` + a date window to search inside one. ([#24](https://github.com/sweetrb/apple-mail-mcp/issues/24)) |
|
|
803
|
+
| Can't delete/rename server-side mailboxes or mutate drafts | Mail.app's AppleScript bridge can only `delete`/`rename` **local "On My Mac"** mailboxes and cannot delete/move drafts — it throws `AppleEvent handler failed` for IMAP/Gmail/Workspace/iCloud/Exchange mailboxes and drafts (the GUI can do it). `delete-mailbox`/`rename-mailbox`/`delete-message`/`move-message` now return a clear "do it in Mail.app directly" error in that case instead of a generic failure. ([#42](https://github.com/sweetrb/apple-mail-mcp/issues/42)) |
|
|
803
804
|
| In-memory templates | Email templates are not persisted across server restarts |
|
|
804
805
|
| Numeric-only message IDs | Message IDs must contain only digits (validated by schema) |
|
|
805
806
|
| Batch size cap | Batch operations are limited to 100 messages per request |
|
package/build/index.js
CHANGED
|
@@ -383,9 +383,9 @@ server.tool("unflag-message", {
|
|
|
383
383
|
server.tool("delete-message", {
|
|
384
384
|
id: MESSAGE_ID_SCHEMA,
|
|
385
385
|
}, withErrorHandling(({ id }) => {
|
|
386
|
-
const success = mailManager.deleteMessage(id);
|
|
386
|
+
const { success, error } = mailManager.deleteMessage(id);
|
|
387
387
|
if (!success) {
|
|
388
|
-
return errorResponse(`Failed to delete message "${id}"`);
|
|
388
|
+
return errorResponse(error || `Failed to delete message "${id}"`);
|
|
389
389
|
}
|
|
390
390
|
return successResponse("Message deleted");
|
|
391
391
|
}, "Error deleting message"));
|
|
@@ -395,9 +395,9 @@ server.tool("move-message", {
|
|
|
395
395
|
mailbox: z.string().min(1, "Destination mailbox is required"),
|
|
396
396
|
account: z.string().optional().describe("Account containing the destination mailbox"),
|
|
397
397
|
}, withErrorHandling(({ id, mailbox, account }) => {
|
|
398
|
-
const success = mailManager.moveMessage(id, mailbox, account);
|
|
398
|
+
const { success, error } = mailManager.moveMessage(id, mailbox, account);
|
|
399
399
|
if (!success) {
|
|
400
|
-
return errorResponse(`Failed to move message to "${mailbox}"`);
|
|
400
|
+
return errorResponse(error || `Failed to move message to "${mailbox}"`);
|
|
401
401
|
}
|
|
402
402
|
return successResponse(`Message moved to "${mailbox}"`);
|
|
403
403
|
}, "Error moving message"));
|
|
@@ -572,9 +572,9 @@ server.tool("delete-mailbox", {
|
|
|
572
572
|
name: z.string().min(1, "Mailbox name is required"),
|
|
573
573
|
account: z.string().optional().describe("Account containing the mailbox"),
|
|
574
574
|
}, withErrorHandling(({ name, account }) => {
|
|
575
|
-
const success = mailManager.deleteMailbox(name, account);
|
|
575
|
+
const { success, error } = mailManager.deleteMailbox(name, account);
|
|
576
576
|
if (!success) {
|
|
577
|
-
return errorResponse(`Failed to delete mailbox "${name}"`);
|
|
577
|
+
return errorResponse(error || `Failed to delete mailbox "${name}"`);
|
|
578
578
|
}
|
|
579
579
|
return successResponse(`Mailbox "${name}" deleted`);
|
|
580
580
|
}, "Error deleting mailbox"));
|
|
@@ -584,9 +584,9 @@ server.tool("rename-mailbox", {
|
|
|
584
584
|
newName: z.string().min(1, "New mailbox name is required"),
|
|
585
585
|
account: z.string().optional().describe("Account containing the mailbox"),
|
|
586
586
|
}, withErrorHandling(({ oldName, newName, account }) => {
|
|
587
|
-
const success = mailManager.renameMailbox(oldName, newName, account);
|
|
587
|
+
const { success, error } = mailManager.renameMailbox(oldName, newName, account);
|
|
588
588
|
if (!success) {
|
|
589
|
-
return errorResponse(`Failed to rename mailbox "${oldName}" to "${newName}"`);
|
|
589
|
+
return errorResponse(error || `Failed to rename mailbox "${oldName}" to "${newName}"`);
|
|
590
590
|
}
|
|
591
591
|
return successResponse(`Mailbox renamed from "${oldName}" to "${newName}"`);
|
|
592
592
|
}, "Error renaming mailbox"));
|
|
@@ -46,6 +46,14 @@ export declare function splitSearchDiagnostics(output: string, account: string):
|
|
|
46
46
|
* (caller passes `resolve(...)` output).
|
|
47
47
|
*/
|
|
48
48
|
export declare function isPathWithinAllowedRoots(resolvedPath: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Turn a raw mailbox delete/rename failure into an actionable, non-retryable
|
|
51
|
+
* message when it's the known server-side-mailbox limitation (#42); otherwise
|
|
52
|
+
* return the raw error unchanged.
|
|
53
|
+
*
|
|
54
|
+
* Exported for unit testing.
|
|
55
|
+
*/
|
|
56
|
+
export declare function describeMailboxOpError(op: "delete" | "rename", raw: string): string;
|
|
49
57
|
export declare function escapeForAppleScript(text: string): string;
|
|
50
58
|
/**
|
|
51
59
|
* Emits AppleScript that builds a date into the variable `varName` from numeric
|
|
@@ -328,7 +336,21 @@ export declare class AppleMailManager {
|
|
|
328
336
|
/**
|
|
329
337
|
* Delete a message.
|
|
330
338
|
*/
|
|
331
|
-
deleteMessage(id: string):
|
|
339
|
+
deleteMessage(id: string): {
|
|
340
|
+
success: boolean;
|
|
341
|
+
error?: string;
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* Classify a failed message mutation (delete/move) into an actionable error.
|
|
345
|
+
*
|
|
346
|
+
* Mail.app's scripting bridge cannot delete or move drafts, and cannot mutate
|
|
347
|
+
* messages in some server-side special mailboxes — it throws `AppleEvent
|
|
348
|
+
* handler failed` rather than a useful message (#42). When that pattern is
|
|
349
|
+
* seen, look up the message's mailbox (cheap, indexed `whose id is`) to give a
|
|
350
|
+
* draft-specific or server-specific hint. Other errors (e.g. "Message not
|
|
351
|
+
* found", "ambiguous destination") pass through unchanged.
|
|
352
|
+
*/
|
|
353
|
+
private classifyMessageMutationError;
|
|
332
354
|
/**
|
|
333
355
|
* Move a message to a different mailbox.
|
|
334
356
|
*/
|
|
@@ -351,7 +373,10 @@ export declare class AppleMailManager {
|
|
|
351
373
|
* (destination not found / ambiguous / message not found).
|
|
352
374
|
*/
|
|
353
375
|
private moveMessageInternal;
|
|
354
|
-
moveMessage(id: string, mailbox: string, account?: string):
|
|
376
|
+
moveMessage(id: string, mailbox: string, account?: string): {
|
|
377
|
+
success: boolean;
|
|
378
|
+
error?: string;
|
|
379
|
+
};
|
|
355
380
|
/**
|
|
356
381
|
* Run one operation over many message IDs in a SINGLE osascript invocation.
|
|
357
382
|
*
|
|
@@ -424,11 +449,17 @@ export declare class AppleMailManager {
|
|
|
424
449
|
/**
|
|
425
450
|
* Delete a mailbox.
|
|
426
451
|
*/
|
|
427
|
-
deleteMailbox(name: string, account?: string):
|
|
452
|
+
deleteMailbox(name: string, account?: string): {
|
|
453
|
+
success: boolean;
|
|
454
|
+
error?: string;
|
|
455
|
+
};
|
|
428
456
|
/**
|
|
429
457
|
* Rename a mailbox by creating a new one, moving messages, and deleting the old one.
|
|
430
458
|
*/
|
|
431
|
-
renameMailbox(oldName: string, newName: string, account?: string):
|
|
459
|
+
renameMailbox(oldName: string, newName: string, account?: string): {
|
|
460
|
+
success: boolean;
|
|
461
|
+
error?: string;
|
|
462
|
+
};
|
|
432
463
|
/**
|
|
433
464
|
* List all mail accounts (uses cache).
|
|
434
465
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"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
|
|
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,EACjB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AA2DpB;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAK7F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,CAsCrD;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAKtE;AAWD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAczD;AAiED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAWrE;AA2CD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAoB5E;AAED,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,OAAO,CAAC,cAAc,CAAuB;IAE7C;;;;OAIG;IACH,OAAO,CAAC,KAAK,CAGX;IAEF,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IAEvC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAKvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAwCtB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,cAAc;IAyCtB;;;;;;;;OAQG;IACH,cAAc,CACZ,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,SAAK,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,EAAE;IAeZ;;;;;;;;;;;;;;;;;OAiBG;IACH,6BAA6B,CAC3B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,SAAK,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,OAAO,GAClB,YAAY;IAgMf;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,mBAAmB,UAAQ,GAAG,OAAO,GAAG,IAAI;IA4EvE;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,cAAc,GAAG,IAAI;IAyDzE;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA6BvC;;;;;;;OAOG;IACH,YAAY,CACV,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,SAAK,EACV,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,SAAI,GACT,OAAO,EAAE;IAIZ;;;;;;;;;;;OAWG;IACH,2BAA2B,CACzB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,SAAK,EACV,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,SAAI,GACT,YAAY;IAgKf;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAoCxB;;;;;;;;;;OAUG;IAuBH,SAAS,CACP,EAAE,EAAE,MAAM,EAAE,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,EAAE,CAAC,EAAE,MAAM,EAAE,EACb,GAAG,CAAC,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO;IA0DV;;;;;;;;;;;;OAYG;IACH,eAAe,CACb,UAAU,EAAE,oBAAoB,EAAE,EAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,MAAY,GACpB,iBAAiB,EAAE;IAgDtB;;;;;;;;;;OAUG;IACH,WAAW,CACT,EAAE,EAAE,MAAM,EAAE,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,EAAE,CAAC,EAAE,MAAM,EAAE,EACb,GAAG,CAAC,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO;IAwDV;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,UAAQ,EAAE,IAAI,UAAO,GAAG,OAAO;IAqChF;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,UAAO,GAAG,OAAO;IA2C7E;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAY/B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYjC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYhC;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYlC;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAgB/D;;;;;;;;;OASG;IACH,OAAO,CAAC,4BAA4B;IAkBpC;;OAEG;IACH;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,mBAAmB;IAwD3B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAgBhG;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAoGzB;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE;IAI1D;;;;;;OAMG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE;IAsB3F;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE;IAItD;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE;IAIxD;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE;IAIxD;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE;IAI1D;;;;OAIG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,EAAE;IAiEzC;;;;OAIG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAmF7E;;OAEG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;IA8C1C;;OAEG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAgC1D;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAyBtD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IA8BnF;;OAEG;IACH,aAAa,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAyFvC;;OAEG;IACH,YAAY,IAAI,OAAO,EAAE;IAIzB;;;OAGG;IACH,OAAO,CAAC,aAAa;IA2CrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACH,SAAS,IAAI,QAAQ,EAAE;IAiCvB;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO;IA+B3D;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE;IAgExC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,cAAc,CAAK;IAE3B;;OAEG;IACH,aAAa,IAAI,aAAa,EAAE;IAIhC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI7C;;OAEG;IACH,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,EAAE,CAAC,EAAE,MAAM,EAAE,EACb,EAAE,CAAC,EAAE,MAAM,EAAE,EACb,EAAE,CAAC,EAAE,MAAM,GACV,aAAa;IAOhB;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,WAAW,CACT,EAAE,EAAE,MAAM,EACV,SAAS,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5E,OAAO;IAqBV;;OAEG;IACH,WAAW,IAAI,iBAAiB;IA8EhC;;OAEG;IACH,YAAY,IAAI,SAAS;IA4CzB;;;;;;;OAOG;IACH,wBAAwB,IAAI,qBAAqB;IA6DjD;;;;;;;;;OASG;IACH,aAAa,IAAI,UAAU;CAiE5B"}
|
|
@@ -158,6 +158,29 @@ export function isPathWithinAllowedRoots(resolvedPath) {
|
|
|
158
158
|
return resolvedPath === base || resolvedPath.startsWith(base + sep);
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Pattern in a raw AppleScript error that indicates an operation Mail.app's
|
|
163
|
+
* scripting interface simply cannot perform on this target — most often a
|
|
164
|
+
* server-side (IMAP / Gmail / Workspace / iCloud / Exchange) mailbox or a draft.
|
|
165
|
+
* Mail throws `AppleEvent handler failed` (-10000) for these; the GUI can do
|
|
166
|
+
* them, the scripting bridge cannot. See issue #42 and the audit doc.
|
|
167
|
+
*/
|
|
168
|
+
const UNSUPPORTED_APPLESCRIPT_OP = /AppleEvent handler failed|-10000/i;
|
|
169
|
+
/**
|
|
170
|
+
* Turn a raw mailbox delete/rename failure into an actionable, non-retryable
|
|
171
|
+
* message when it's the known server-side-mailbox limitation (#42); otherwise
|
|
172
|
+
* return the raw error unchanged.
|
|
173
|
+
*
|
|
174
|
+
* Exported for unit testing.
|
|
175
|
+
*/
|
|
176
|
+
export function describeMailboxOpError(op, raw) {
|
|
177
|
+
const trimmed = (raw || "").trim();
|
|
178
|
+
if (UNSUPPORTED_APPLESCRIPT_OP.test(trimmed)) {
|
|
179
|
+
const verb = op === "delete" ? "Delete" : "Rename";
|
|
180
|
+
return `Mail.app cannot ${op} server-side (IMAP / Gmail / Workspace / iCloud / Exchange) mailboxes via AppleScript — only local "On My Mac" mailboxes support this. ${verb} it in Mail.app directly. (Mail.app error: ${trimmed})`;
|
|
181
|
+
}
|
|
182
|
+
return trimmed || `Failed to ${op} mailbox`;
|
|
183
|
+
}
|
|
161
184
|
export function escapeForAppleScript(text) {
|
|
162
185
|
if (!text)
|
|
163
186
|
return "";
|
|
@@ -1425,11 +1448,41 @@ export class AppleMailManager {
|
|
|
1425
1448
|
deleteMessage(id) {
|
|
1426
1449
|
const script = this.findMessageScript(id, "delete msg");
|
|
1427
1450
|
const result = executeAppleScript(script, { timeoutMs: 60000 });
|
|
1428
|
-
if (
|
|
1429
|
-
|
|
1430
|
-
return false;
|
|
1451
|
+
if (result.success && !result.output.startsWith("error:")) {
|
|
1452
|
+
return { success: true };
|
|
1431
1453
|
}
|
|
1432
|
-
|
|
1454
|
+
const raw = result.success
|
|
1455
|
+
? result.output.replace(/^error:/, "")
|
|
1456
|
+
: result.error || "Unknown error";
|
|
1457
|
+
const error = this.classifyMessageMutationError(id, raw, "delete");
|
|
1458
|
+
console.error(`Failed to delete message: ${error}`);
|
|
1459
|
+
return { success: false, error };
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Classify a failed message mutation (delete/move) into an actionable error.
|
|
1463
|
+
*
|
|
1464
|
+
* Mail.app's scripting bridge cannot delete or move drafts, and cannot mutate
|
|
1465
|
+
* messages in some server-side special mailboxes — it throws `AppleEvent
|
|
1466
|
+
* handler failed` rather than a useful message (#42). When that pattern is
|
|
1467
|
+
* seen, look up the message's mailbox (cheap, indexed `whose id is`) to give a
|
|
1468
|
+
* draft-specific or server-specific hint. Other errors (e.g. "Message not
|
|
1469
|
+
* found", "ambiguous destination") pass through unchanged.
|
|
1470
|
+
*/
|
|
1471
|
+
classifyMessageMutationError(id, raw, op) {
|
|
1472
|
+
const trimmed = (raw || "").trim();
|
|
1473
|
+
if (!UNSUPPORTED_APPLESCRIPT_OP.test(trimmed))
|
|
1474
|
+
return trimmed || `Failed to ${op} message`;
|
|
1475
|
+
let mailbox = "";
|
|
1476
|
+
try {
|
|
1477
|
+
mailbox = this.getMessageById(id)?.mailbox ?? "";
|
|
1478
|
+
}
|
|
1479
|
+
catch {
|
|
1480
|
+
/* best-effort; fall through to the generic server-side message */
|
|
1481
|
+
}
|
|
1482
|
+
if (/draft/i.test(mailbox)) {
|
|
1483
|
+
return `Mail.app cannot ${op} drafts via AppleScript; ${op} it in Mail.app directly. (Mail.app error: ${trimmed})`;
|
|
1484
|
+
}
|
|
1485
|
+
return `Mail.app cannot ${op} this message via AppleScript (server-side or special mailbox${mailbox ? ` "${mailbox}"` : ""}); ${op} it in Mail.app directly. (Mail.app error: ${trimmed})`;
|
|
1433
1486
|
}
|
|
1434
1487
|
/**
|
|
1435
1488
|
* Move a message to a different mailbox.
|
|
@@ -1501,11 +1554,12 @@ export class AppleMailManager {
|
|
|
1501
1554
|
return { success: true };
|
|
1502
1555
|
}
|
|
1503
1556
|
moveMessage(id, mailbox, account) {
|
|
1504
|
-
const
|
|
1505
|
-
if (
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1557
|
+
const res = this.moveMessageInternal(id, mailbox, account);
|
|
1558
|
+
if (res.success)
|
|
1559
|
+
return { success: true };
|
|
1560
|
+
const error = this.classifyMessageMutationError(id, res.error || "Failed to move message", "move");
|
|
1561
|
+
console.error(`Failed to move message: ${error}`);
|
|
1562
|
+
return { success: false, error };
|
|
1509
1563
|
}
|
|
1510
1564
|
// ===========================================================================
|
|
1511
1565
|
// Batch Operations
|
|
@@ -1938,11 +1992,15 @@ export class AppleMailManager {
|
|
|
1938
1992
|
`);
|
|
1939
1993
|
const result = executeAppleScript(script);
|
|
1940
1994
|
if (!result.success || result.output.startsWith("error:")) {
|
|
1941
|
-
|
|
1942
|
-
|
|
1995
|
+
const raw = result.success
|
|
1996
|
+
? result.output.replace(/^error:/, "")
|
|
1997
|
+
: result.error || "Unknown error";
|
|
1998
|
+
const error = describeMailboxOpError("delete", raw);
|
|
1999
|
+
console.error(`Failed to delete mailbox: ${error}`);
|
|
2000
|
+
return { success: false, error };
|
|
1943
2001
|
}
|
|
1944
2002
|
this.invalidateCache();
|
|
1945
|
-
return true;
|
|
2003
|
+
return { success: true };
|
|
1946
2004
|
}
|
|
1947
2005
|
/**
|
|
1948
2006
|
* Rename a mailbox by creating a new one, moving messages, and deleting the old one.
|
|
@@ -1951,7 +2009,10 @@ export class AppleMailManager {
|
|
|
1951
2009
|
const targetAccount = this.resolveAccount(account);
|
|
1952
2010
|
// Create the new mailbox
|
|
1953
2011
|
if (!this.createMailbox(newName, targetAccount)) {
|
|
1954
|
-
return
|
|
2012
|
+
return {
|
|
2013
|
+
success: false,
|
|
2014
|
+
error: `Could not create the destination mailbox "${newName}" needed for the rename.`,
|
|
2015
|
+
};
|
|
1955
2016
|
}
|
|
1956
2017
|
// Move all messages from old to new
|
|
1957
2018
|
const resolvedOld = this.resolveMailbox(oldName, targetAccount);
|
|
@@ -1997,19 +2058,27 @@ export class AppleMailManager {
|
|
|
1997
2058
|
// check), so a truncated move is recoverable rather than lossy.
|
|
1998
2059
|
const result = executeAppleScript(moveScript, { timeoutMs: 120000 });
|
|
1999
2060
|
if (!result.success || result.output.startsWith("error:")) {
|
|
2000
|
-
|
|
2001
|
-
|
|
2061
|
+
const raw = result.success
|
|
2062
|
+
? result.output.replace(/^error:/, "")
|
|
2063
|
+
: result.error || "Unknown error";
|
|
2064
|
+
// The empty destination mailbox we just created is now an orphan; the
|
|
2065
|
+
// source is untouched (delete only runs after a verified-empty move).
|
|
2066
|
+
const error = describeMailboxOpError("rename", raw);
|
|
2067
|
+
console.error(`Failed to rename mailbox: ${error}`);
|
|
2068
|
+
this.invalidateCache();
|
|
2069
|
+
return { success: false, error };
|
|
2002
2070
|
}
|
|
2003
2071
|
if (result.output.startsWith("partial")) {
|
|
2004
2072
|
const parts = result.output.split(FIELD_SEP);
|
|
2005
2073
|
const remaining = parts[3] ?? "?";
|
|
2006
2074
|
const total = parts[2] ?? "?";
|
|
2007
|
-
|
|
2075
|
+
const error = `Only ${parts[1] ?? "?"} of ${total} messages moved, ${remaining} remain in "${resolvedOld}"; the source was NOT deleted (both mailboxes left intact). Retry to move the rest.`;
|
|
2076
|
+
console.error(`Failed to rename mailbox: ${error}`);
|
|
2008
2077
|
this.invalidateCache(); // the new mailbox now exists and holds the moved messages
|
|
2009
|
-
return false;
|
|
2078
|
+
return { success: false, error };
|
|
2010
2079
|
}
|
|
2011
2080
|
this.invalidateCache();
|
|
2012
|
-
return true;
|
|
2081
|
+
return { success: true };
|
|
2013
2082
|
}
|
|
2014
2083
|
// ===========================================================================
|
|
2015
2084
|
// Account Operations
|