apple-mail-mcp 1.6.4 → 1.6.5
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.
|
@@ -21,11 +21,12 @@ import type { Message, MessageContent, Mailbox, Account, Attachment, HealthCheck
|
|
|
21
21
|
export declare function mergeSearchDiagnostics(into: SearchDiagnostics, from: SearchDiagnostics): void;
|
|
22
22
|
/**
|
|
23
23
|
* Split a per-account search payload into its message-list portion and parsed
|
|
24
|
-
* diagnostics. The AppleScript appends a trailer of the form
|
|
24
|
+
* diagnostics. The AppleScript appends a trailer of the form (using the
|
|
25
|
+
* control-character separators defined above):
|
|
25
26
|
*
|
|
26
|
-
* <messages
|
|
27
|
+
* <messages>{DIAG_MARKER}timedOut=true{DIAG_FIELD_SEP}skipped=Foo (9000){DIAG_ITEM_SEP}{DIAG_FIELD_SEP}notSearched=Bar{DIAG_ITEM_SEP}
|
|
27
28
|
*
|
|
28
|
-
* `skipped`/`notSearched` are
|
|
29
|
+
* `skipped`/`notSearched` are DIAG_ITEM_SEP-separated mailbox names, each prefixed
|
|
29
30
|
* with the account name on the way out so the aggregate result is unambiguous.
|
|
30
31
|
*
|
|
31
32
|
* Exported (pure, no Mail.app dependency) for unit testing — this is the logic
|
|
@@ -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,EACjB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,8 +50,26 @@ function getMailboxScanThreshold() {
|
|
|
50
50
|
const SEARCH_ACCOUNT_BUDGET_SECONDS = 30;
|
|
51
51
|
/** osascript process timeout for a per-account search (ms). */
|
|
52
52
|
const SEARCH_ACCOUNT_TIMEOUT_MS = 45000;
|
|
53
|
-
/**
|
|
54
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Result serialization separators (issue #30).
|
|
55
|
+
*
|
|
56
|
+
* AppleScript emits structured results as delimited strings that TS then splits.
|
|
57
|
+
* The original delimiters were printable triple-pipe tokens, so any field value
|
|
58
|
+
* that itself contained one — a subject, sender, attachment filename, or mailbox
|
|
59
|
+
* name with a triple-pipe in it — shifted every subsequent field and silently
|
|
60
|
+
* corrupted the parse. These are now ASCII control characters
|
|
61
|
+
* (Unit/Record/Group Separator) which cannot occur in mail field values, so the
|
|
62
|
+
* collision is structurally impossible. The same constant is used by the
|
|
63
|
+
* AppleScript emitter (interpolated into the script string) and the TS parser,
|
|
64
|
+
* so the two can never drift.
|
|
65
|
+
*/
|
|
66
|
+
const FIELD_SEP = "\x1f"; // US — between fields within a record
|
|
67
|
+
const RECORD_SEP = "\x1e"; // RS — between records
|
|
68
|
+
const DIAG_MARKER = "\x1dDIAG\x1d"; // GS-wrapped — payload/diagnostics boundary
|
|
69
|
+
const DIAG_FIELD_SEP = "\x1dF\x1d"; // between diagnostics fields
|
|
70
|
+
const DIAG_ITEM_SEP = "\x1dM\x1d"; // between diagnostics list items
|
|
71
|
+
const CONTENT_MARKER = "\x1dCONTENT\x1d"; // subject/plain-text boundary
|
|
72
|
+
const HTML_MARKER = "\x1dHTML\x1d"; // plain-text/source boundary
|
|
55
73
|
/**
|
|
56
74
|
* Merge a per-account SearchDiagnostics into an aggregate (all-accounts) one.
|
|
57
75
|
*
|
|
@@ -66,11 +84,12 @@ export function mergeSearchDiagnostics(into, from) {
|
|
|
66
84
|
}
|
|
67
85
|
/**
|
|
68
86
|
* Split a per-account search payload into its message-list portion and parsed
|
|
69
|
-
* diagnostics. The AppleScript appends a trailer of the form
|
|
87
|
+
* diagnostics. The AppleScript appends a trailer of the form (using the
|
|
88
|
+
* control-character separators defined above):
|
|
70
89
|
*
|
|
71
|
-
* <messages
|
|
90
|
+
* <messages>{DIAG_MARKER}timedOut=true{DIAG_FIELD_SEP}skipped=Foo (9000){DIAG_ITEM_SEP}{DIAG_FIELD_SEP}notSearched=Bar{DIAG_ITEM_SEP}
|
|
72
91
|
*
|
|
73
|
-
* `skipped`/`notSearched` are
|
|
92
|
+
* `skipped`/`notSearched` are DIAG_ITEM_SEP-separated mailbox names, each prefixed
|
|
74
93
|
* with the account name on the way out so the aggregate result is unambiguous.
|
|
75
94
|
*
|
|
76
95
|
* Exported (pure, no Mail.app dependency) for unit testing — this is the logic
|
|
@@ -87,13 +106,13 @@ export function splitSearchDiagnostics(output, account) {
|
|
|
87
106
|
notSearchedMailboxes: [],
|
|
88
107
|
};
|
|
89
108
|
if (trailer) {
|
|
90
|
-
const fields = trailer.split(
|
|
109
|
+
const fields = trailer.split(DIAG_FIELD_SEP);
|
|
91
110
|
const getField = (key) => {
|
|
92
111
|
const f = fields.find((x) => x.startsWith(`${key}=`));
|
|
93
112
|
return f ? f.slice(key.length + 1) : "";
|
|
94
113
|
};
|
|
95
114
|
const splitList = (raw) => raw
|
|
96
|
-
.split(
|
|
115
|
+
.split(DIAG_ITEM_SEP)
|
|
97
116
|
.map((s) => s.trim())
|
|
98
117
|
.filter((s) => s.length > 0);
|
|
99
118
|
diagnostics.skippedLargeMailboxes = splitList(getField("skipped")).map((mb) => `${account} / ${mb}`);
|
|
@@ -521,17 +540,17 @@ export class AppleMailManager {
|
|
|
521
540
|
set msgDateStr to ${AS_DATE_TO_STRING}
|
|
522
541
|
set msgRead to read status of msg as string
|
|
523
542
|
set msgFlagged to flagged status of msg as string
|
|
524
|
-
if msgCount > 0 then set outputText to outputText & "
|
|
525
|
-
set outputText to outputText & msgId & "
|
|
543
|
+
if msgCount > 0 then set outputText to outputText & "${RECORD_SEP}"
|
|
544
|
+
set outputText to outputText & msgId & "${FIELD_SEP}" & msgSubject & "${FIELD_SEP}" & msgSender & "${FIELD_SEP}" & msgDateStr & "${FIELD_SEP}" & msgRead & "${FIELD_SEP}" & msgFlagged
|
|
526
545
|
set msgCount to msgCount + 1
|
|
527
546
|
${dateFilter ? "end if" : ""}
|
|
528
547
|
end try
|
|
529
548
|
end repeat
|
|
530
549
|
on error _errMsg number _errNum
|
|
531
550
|
set _timedOut to true
|
|
532
|
-
set _notSearched to "${escapeForAppleScript(targetMailbox)}
|
|
551
|
+
set _notSearched to "${escapeForAppleScript(targetMailbox)}${DIAG_ITEM_SEP}"
|
|
533
552
|
end try
|
|
534
|
-
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "
|
|
553
|
+
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "${DIAG_FIELD_SEP}skipped=${DIAG_FIELD_SEP}notSearched=" & _notSearched
|
|
535
554
|
`;
|
|
536
555
|
}
|
|
537
556
|
else {
|
|
@@ -556,7 +575,7 @@ export class AppleMailManager {
|
|
|
556
575
|
end try
|
|
557
576
|
if ((current date) - _startedAt) > ${SEARCH_ACCOUNT_BUDGET_SECONDS} then
|
|
558
577
|
set _timedOut to true
|
|
559
|
-
set _notSearched to _notSearched & mbName & "
|
|
578
|
+
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
|
560
579
|
else
|
|
561
580
|
set mbCount to 0
|
|
562
581
|
try
|
|
@@ -564,7 +583,7 @@ export class AppleMailManager {
|
|
|
564
583
|
end try
|
|
565
584
|
if (${scanGuard}) then
|
|
566
585
|
set _timedOut to true
|
|
567
|
-
set _skipped to _skipped & mbName & " (" & (mbCount as string) & ")
|
|
586
|
+
set _skipped to _skipped & mbName & " (" & (mbCount as string) & ")${DIAG_ITEM_SEP}"
|
|
568
587
|
else
|
|
569
588
|
try
|
|
570
589
|
set allMessages to messages of mb ${searchCondition}
|
|
@@ -581,8 +600,8 @@ export class AppleMailManager {
|
|
|
581
600
|
set msgDateStr to ${AS_DATE_TO_STRING}
|
|
582
601
|
set msgRead to read status of msg as string
|
|
583
602
|
set msgFlagged to flagged status of msg as string
|
|
584
|
-
if msgCount > 0 then set outputText to outputText & "
|
|
585
|
-
set outputText to outputText & msgId & "
|
|
603
|
+
if msgCount > 0 then set outputText to outputText & "${RECORD_SEP}"
|
|
604
|
+
set outputText to outputText & msgId & "${FIELD_SEP}" & msgSubject & "${FIELD_SEP}" & msgSender & "${FIELD_SEP}" & msgDateStr & "${FIELD_SEP}" & msgRead & "${FIELD_SEP}" & msgFlagged & "${FIELD_SEP}" & mbName
|
|
586
605
|
set msgCount to msgCount + 1
|
|
587
606
|
${dateFilter ? "end if" : ""}
|
|
588
607
|
end if
|
|
@@ -590,12 +609,12 @@ export class AppleMailManager {
|
|
|
590
609
|
end repeat
|
|
591
610
|
on error _errMsg number _errNum
|
|
592
611
|
set _timedOut to true
|
|
593
|
-
set _notSearched to _notSearched & mbName & "
|
|
612
|
+
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
|
594
613
|
end try
|
|
595
614
|
end if
|
|
596
615
|
end if
|
|
597
616
|
end repeat
|
|
598
|
-
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "
|
|
617
|
+
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "${DIAG_FIELD_SEP}skipped=" & _skipped & "${DIAG_FIELD_SEP}notSearched=" & _notSearched
|
|
599
618
|
`;
|
|
600
619
|
}
|
|
601
620
|
const script = buildAccountScopedScript(targetAccount, searchCommand);
|
|
@@ -668,7 +687,7 @@ export class AppleMailManager {
|
|
|
668
687
|
if rawSrc contains "Content-Disposition: attachment" then set hasAtt to "true"
|
|
669
688
|
end try
|
|
670
689
|
end if
|
|
671
|
-
return msgSubject & "
|
|
690
|
+
return msgSubject & "${FIELD_SEP}" & msgSender & "${FIELD_SEP}" & msgDate & "${FIELD_SEP}" & msgRead & "${FIELD_SEP}" & msgFlagged & "${FIELD_SEP}" & msgJunk & "${FIELD_SEP}" & msgDeleted & "${FIELD_SEP}" & msgMailbox & "${FIELD_SEP}" & msgAccount & "${FIELD_SEP}" & hasAtt
|
|
672
691
|
end if
|
|
673
692
|
end try
|
|
674
693
|
end repeat
|
|
@@ -683,7 +702,7 @@ export class AppleMailManager {
|
|
|
683
702
|
console.error(`Failed to get message ${id}: ${result.error}`);
|
|
684
703
|
return null;
|
|
685
704
|
}
|
|
686
|
-
const parts = result.output.split(
|
|
705
|
+
const parts = result.output.split(FIELD_SEP);
|
|
687
706
|
if (parts.length < 9)
|
|
688
707
|
return null;
|
|
689
708
|
return {
|
|
@@ -719,7 +738,7 @@ export class AppleMailManager {
|
|
|
719
738
|
try
|
|
720
739
|
set htmlContent to source of msg
|
|
721
740
|
end try
|
|
722
|
-
return msgSubject & "
|
|
741
|
+
return msgSubject & "${CONTENT_MARKER}" & msgContent & "${HTML_MARKER}" & htmlContent
|
|
723
742
|
end if
|
|
724
743
|
end try
|
|
725
744
|
end repeat
|
|
@@ -734,10 +753,10 @@ export class AppleMailManager {
|
|
|
734
753
|
console.error(`Failed to get message content: ${result.error}`);
|
|
735
754
|
return null;
|
|
736
755
|
}
|
|
737
|
-
const htmlSplit = result.output.split(
|
|
756
|
+
const htmlSplit = result.output.split(HTML_MARKER);
|
|
738
757
|
const contentPart = htmlSplit[0];
|
|
739
758
|
const htmlContent = htmlSplit.length > 1 ? htmlSplit[1] : undefined;
|
|
740
|
-
const parts = contentPart.split(
|
|
759
|
+
const parts = contentPart.split(CONTENT_MARKER);
|
|
741
760
|
if (parts.length < 2)
|
|
742
761
|
return null;
|
|
743
762
|
return {
|
|
@@ -859,17 +878,17 @@ export class AppleMailManager {
|
|
|
859
878
|
try
|
|
860
879
|
if (count of mail attachments of msg) > 0 then set msgHasAtt to "true"
|
|
861
880
|
end try
|
|
862
|
-
if msgCount > 0 then set outputText to outputText & "
|
|
863
|
-
set outputText to outputText & msgId & "
|
|
881
|
+
if msgCount > 0 then set outputText to outputText & "${RECORD_SEP}"
|
|
882
|
+
set outputText to outputText & msgId & "${FIELD_SEP}" & msgSubject & "${FIELD_SEP}" & msgSender & "${FIELD_SEP}" & msgDate & "${FIELD_SEP}" & msgRead & "${FIELD_SEP}" & msgFlagged & "${FIELD_SEP}" & msgHasAtt
|
|
864
883
|
set msgCount to msgCount + 1
|
|
865
884
|
end if
|
|
866
885
|
end try
|
|
867
886
|
end repeat
|
|
868
887
|
on error _errMsg number _errNum
|
|
869
888
|
set _timedOut to true
|
|
870
|
-
set _notSearched to "${escapeForAppleScript(targetMailbox)}
|
|
889
|
+
set _notSearched to "${escapeForAppleScript(targetMailbox)}${DIAG_ITEM_SEP}"
|
|
871
890
|
end try
|
|
872
|
-
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "
|
|
891
|
+
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "${DIAG_FIELD_SEP}skipped=${DIAG_FIELD_SEP}notSearched=" & _notSearched
|
|
873
892
|
`;
|
|
874
893
|
}
|
|
875
894
|
else {
|
|
@@ -893,7 +912,7 @@ export class AppleMailManager {
|
|
|
893
912
|
end try
|
|
894
913
|
if ((current date) - _startedAt) > ${SEARCH_ACCOUNT_BUDGET_SECONDS} then
|
|
895
914
|
set _timedOut to true
|
|
896
|
-
set _notSearched to _notSearched & mbName & "
|
|
915
|
+
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
|
897
916
|
else
|
|
898
917
|
set mbCount to 0
|
|
899
918
|
try
|
|
@@ -901,7 +920,7 @@ export class AppleMailManager {
|
|
|
901
920
|
end try
|
|
902
921
|
if (${scanGuard}) then
|
|
903
922
|
set _timedOut to true
|
|
904
|
-
set _skipped to _skipped & mbName & " (" & (mbCount as string) & ")
|
|
923
|
+
set _skipped to _skipped & mbName & " (" & (mbCount as string) & ")${DIAG_ITEM_SEP}"
|
|
905
924
|
else
|
|
906
925
|
try
|
|
907
926
|
repeat with msg in messages of mb ${fromFilter}
|
|
@@ -923,8 +942,8 @@ export class AppleMailManager {
|
|
|
923
942
|
try
|
|
924
943
|
if (count of mail attachments of msg) > 0 then set msgHasAtt to "true"
|
|
925
944
|
end try
|
|
926
|
-
if msgCount > 0 then set outputText to outputText & "
|
|
927
|
-
set outputText to outputText & msgId & "
|
|
945
|
+
if msgCount > 0 then set outputText to outputText & "${RECORD_SEP}"
|
|
946
|
+
set outputText to outputText & msgId & "${FIELD_SEP}" & msgSubject & "${FIELD_SEP}" & msgSender & "${FIELD_SEP}" & msgDate & "${FIELD_SEP}" & msgRead & "${FIELD_SEP}" & msgFlagged & "${FIELD_SEP}" & mbName & "${FIELD_SEP}" & msgHasAtt
|
|
928
947
|
set msgCount to msgCount + 1
|
|
929
948
|
end if
|
|
930
949
|
end if
|
|
@@ -932,12 +951,12 @@ export class AppleMailManager {
|
|
|
932
951
|
end repeat
|
|
933
952
|
on error _errMsg number _errNum
|
|
934
953
|
set _timedOut to true
|
|
935
|
-
set _notSearched to _notSearched & mbName & "
|
|
954
|
+
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
|
936
955
|
end try
|
|
937
956
|
end if
|
|
938
957
|
end if
|
|
939
958
|
end repeat
|
|
940
|
-
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "
|
|
959
|
+
return outputText & "${DIAG_MARKER}timedOut=" & (_timedOut as string) & "${DIAG_FIELD_SEP}skipped=" & _skipped & "${DIAG_FIELD_SEP}notSearched=" & _notSearched
|
|
941
960
|
`;
|
|
942
961
|
}
|
|
943
962
|
const script = buildAccountScopedScript(targetAccount, listCommand);
|
|
@@ -969,10 +988,10 @@ export class AppleMailManager {
|
|
|
969
988
|
* limitation). Use getMessage or list-attachments for authoritative info.
|
|
970
989
|
*/
|
|
971
990
|
parseMessageList(output, mailbox, account) {
|
|
972
|
-
const items = output.split(
|
|
991
|
+
const items = output.split(RECORD_SEP);
|
|
973
992
|
const messages = [];
|
|
974
993
|
for (const item of items) {
|
|
975
|
-
const parts = item.split(
|
|
994
|
+
const parts = item.split(FIELD_SEP);
|
|
976
995
|
if (parts.length < 6)
|
|
977
996
|
continue;
|
|
978
997
|
let msgMailbox = mailbox;
|
|
@@ -1553,8 +1572,8 @@ export class AppleMailManager {
|
|
|
1553
1572
|
set attName to name of att
|
|
1554
1573
|
set attType to MIME type of att
|
|
1555
1574
|
set attSize to file size of att as string
|
|
1556
|
-
if attCount > 0 then set outputText to outputText & "
|
|
1557
|
-
set outputText to outputText & attName & "
|
|
1575
|
+
if attCount > 0 then set outputText to outputText & "${RECORD_SEP}"
|
|
1576
|
+
set outputText to outputText & attName & "${FIELD_SEP}" & attType & "${FIELD_SEP}" & attSize
|
|
1558
1577
|
set attCount to attCount + 1
|
|
1559
1578
|
end repeat
|
|
1560
1579
|
return outputText
|
|
@@ -1569,10 +1588,10 @@ export class AppleMailManager {
|
|
|
1569
1588
|
`);
|
|
1570
1589
|
const result = executeAppleScript(script, { timeoutMs: 60000 });
|
|
1571
1590
|
if (result.success && result.output.trim()) {
|
|
1572
|
-
const items = result.output.split(
|
|
1591
|
+
const items = result.output.split(RECORD_SEP);
|
|
1573
1592
|
const attachments = [];
|
|
1574
1593
|
for (const item of items) {
|
|
1575
|
-
const parts = item.split(
|
|
1594
|
+
const parts = item.split(FIELD_SEP);
|
|
1576
1595
|
if (parts.length < 3)
|
|
1577
1596
|
continue;
|
|
1578
1597
|
attachments.push({
|
|
@@ -1690,9 +1709,9 @@ export class AppleMailManager {
|
|
|
1690
1709
|
set mbName to name of mb
|
|
1691
1710
|
set mbUnread to unread count of mb
|
|
1692
1711
|
set mbCount to count of messages of mb
|
|
1693
|
-
set end of mailboxList to mbName & "
|
|
1712
|
+
set end of mailboxList to mbName & "${FIELD_SEP}" & mbUnread & "${FIELD_SEP}" & mbCount
|
|
1694
1713
|
end repeat
|
|
1695
|
-
set AppleScript's text item delimiters to "
|
|
1714
|
+
set AppleScript's text item delimiters to "${RECORD_SEP}"
|
|
1696
1715
|
return mailboxList as text
|
|
1697
1716
|
`;
|
|
1698
1717
|
const script = buildAccountScopedScript(targetAccount, listCommand);
|
|
@@ -1703,10 +1722,10 @@ export class AppleMailManager {
|
|
|
1703
1722
|
}
|
|
1704
1723
|
if (!result.output.trim())
|
|
1705
1724
|
return [];
|
|
1706
|
-
const items = result.output.split(
|
|
1725
|
+
const items = result.output.split(RECORD_SEP);
|
|
1707
1726
|
const mailboxes = [];
|
|
1708
1727
|
for (const item of items) {
|
|
1709
|
-
const parts = item.split(
|
|
1728
|
+
const parts = item.split(FIELD_SEP);
|
|
1710
1729
|
if (parts.length < 3)
|
|
1711
1730
|
continue;
|
|
1712
1731
|
mailboxes.push({
|
|
@@ -1854,9 +1873,9 @@ export class AppleMailManager {
|
|
|
1854
1873
|
if (count of acctEmail) > 0 then
|
|
1855
1874
|
set emailStr to item 1 of acctEmail
|
|
1856
1875
|
end if
|
|
1857
|
-
set end of accountList to acctName & "
|
|
1876
|
+
set end of accountList to acctName & "${FIELD_SEP}" & emailStr & "${FIELD_SEP}" & acctEnabled
|
|
1858
1877
|
end repeat
|
|
1859
|
-
set AppleScript's text item delimiters to "
|
|
1878
|
+
set AppleScript's text item delimiters to "${RECORD_SEP}"
|
|
1860
1879
|
return accountList as text
|
|
1861
1880
|
`);
|
|
1862
1881
|
const result = executeAppleScript(script);
|
|
@@ -1866,10 +1885,10 @@ export class AppleMailManager {
|
|
|
1866
1885
|
}
|
|
1867
1886
|
if (!result.output.trim())
|
|
1868
1887
|
return [];
|
|
1869
|
-
const items = result.output.split(
|
|
1888
|
+
const items = result.output.split(RECORD_SEP);
|
|
1870
1889
|
const accounts = [];
|
|
1871
1890
|
for (const item of items) {
|
|
1872
|
-
const parts = item.split(
|
|
1891
|
+
const parts = item.split(FIELD_SEP);
|
|
1873
1892
|
if (parts.length < 3)
|
|
1874
1893
|
continue;
|
|
1875
1894
|
accounts.push({
|
|
@@ -1910,19 +1929,19 @@ export class AppleMailManager {
|
|
|
1910
1929
|
repeat with r in rules
|
|
1911
1930
|
set ruleName to name of r
|
|
1912
1931
|
set ruleEnabled to enabled of r
|
|
1913
|
-
set end of ruleList to ruleName & "
|
|
1932
|
+
set end of ruleList to ruleName & "${FIELD_SEP}" & (ruleEnabled as string)
|
|
1914
1933
|
end repeat
|
|
1915
|
-
set AppleScript's text item delimiters to "
|
|
1934
|
+
set AppleScript's text item delimiters to "${RECORD_SEP}"
|
|
1916
1935
|
return ruleList as text
|
|
1917
1936
|
`);
|
|
1918
1937
|
const result = executeAppleScript(script);
|
|
1919
1938
|
if (!result.success || !result.output.trim()) {
|
|
1920
1939
|
return [];
|
|
1921
1940
|
}
|
|
1922
|
-
const items = result.output.split(
|
|
1941
|
+
const items = result.output.split(RECORD_SEP);
|
|
1923
1942
|
const rules = [];
|
|
1924
1943
|
for (const item of items) {
|
|
1925
|
-
const parts = item.split(
|
|
1944
|
+
const parts = item.split(FIELD_SEP);
|
|
1926
1945
|
if (parts.length < 2)
|
|
1927
1946
|
continue;
|
|
1928
1947
|
rules.push({
|
|
@@ -1987,11 +2006,11 @@ export class AppleMailManager {
|
|
|
1987
2006
|
if pPhones is not "" then set pPhones to pPhones & ","
|
|
1988
2007
|
set pPhones to pPhones & (value of ph)
|
|
1989
2008
|
end repeat
|
|
1990
|
-
set end of matchedContacts to pName & "
|
|
2009
|
+
set end of matchedContacts to pName & "${FIELD_SEP}" & pEmails & "${FIELD_SEP}" & pPhones
|
|
1991
2010
|
end if
|
|
1992
2011
|
end repeat
|
|
1993
2012
|
|
|
1994
|
-
set AppleScript's text item delimiters to "
|
|
2013
|
+
set AppleScript's text item delimiters to "${RECORD_SEP}"
|
|
1995
2014
|
return matchedContacts as text
|
|
1996
2015
|
end tell
|
|
1997
2016
|
`;
|
|
@@ -1999,10 +2018,10 @@ export class AppleMailManager {
|
|
|
1999
2018
|
if (!result.success || !result.output.trim()) {
|
|
2000
2019
|
return [];
|
|
2001
2020
|
}
|
|
2002
|
-
const items = result.output.split(
|
|
2021
|
+
const items = result.output.split(RECORD_SEP);
|
|
2003
2022
|
const contacts = [];
|
|
2004
2023
|
for (const item of items) {
|
|
2005
|
-
const parts = item.split(
|
|
2024
|
+
const parts = item.split(FIELD_SEP);
|
|
2006
2025
|
if (parts.length < 3)
|
|
2007
2026
|
continue;
|
|
2008
2027
|
contacts.push({
|
|
@@ -2225,14 +2244,14 @@ export class AppleMailManager {
|
|
|
2225
2244
|
end try
|
|
2226
2245
|
end repeat
|
|
2227
2246
|
|
|
2228
|
-
return (last24h as string) & "
|
|
2247
|
+
return (last24h as string) & "${FIELD_SEP}" & (last7d as string) & "${FIELD_SEP}" & (last30d as string)
|
|
2229
2248
|
`);
|
|
2230
2249
|
const result = executeAppleScript(script, { timeoutMs: 60000 });
|
|
2231
2250
|
if (!result.success || !result.output.trim()) {
|
|
2232
2251
|
console.error(`Failed to get recently received stats: ${result.error}`);
|
|
2233
2252
|
return { last24h: 0, last7d: 0, last30d: 0 };
|
|
2234
2253
|
}
|
|
2235
|
-
const parts = result.output.split(
|
|
2254
|
+
const parts = result.output.split(FIELD_SEP);
|
|
2236
2255
|
if (parts.length < 3) {
|
|
2237
2256
|
return { last24h: 0, last7d: 0, last30d: 0 };
|
|
2238
2257
|
}
|
|
@@ -2276,7 +2295,7 @@ export class AppleMailManager {
|
|
|
2276
2295
|
set totalMailboxes to totalMailboxes + (count of mailboxes of acct)
|
|
2277
2296
|
end repeat
|
|
2278
2297
|
|
|
2279
|
-
return "running
|
|
2298
|
+
return "running${FIELD_SEP}" & accountCount & "${FIELD_SEP}" & totalMailboxes
|
|
2280
2299
|
`);
|
|
2281
2300
|
const result = executeAppleScript(script);
|
|
2282
2301
|
if (!result.success) {
|
|
@@ -2298,7 +2317,7 @@ export class AppleMailManager {
|
|
|
2298
2317
|
};
|
|
2299
2318
|
}
|
|
2300
2319
|
// Parse the response
|
|
2301
|
-
const parts = result.output.split(
|
|
2320
|
+
const parts = result.output.split(FIELD_SEP);
|
|
2302
2321
|
const isRunning = parts[0] === "running";
|
|
2303
2322
|
const accountCount = parseInt(parts[1]) || 0;
|
|
2304
2323
|
// Mail.app is running with accounts configured - assume sync is active
|