@redpop/apple-mail-mcp 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +241 -2
- package/SECURITY.md +102 -0
- package/bin/Mail MCP Helper.app/Contents/CodeResources +0 -0
- package/bin/Mail MCP Helper.app/Contents/Info.plist +26 -0
- package/bin/Mail MCP Helper.app/Contents/MacOS/mail-helper +0 -0
- package/bin/Mail MCP Helper.app/Contents/Resources/AppIcon.icns +0 -0
- package/bin/Mail MCP Helper.app/Contents/_CodeSignature/CodeResources +128 -0
- package/dist/bodyScan.js +259 -0
- package/dist/bodyScan.js.map +1 -0
- package/dist/cli/doctor.js +242 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +59 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/setup.js +107 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +43 -0
- package/dist/context.js.map +1 -0
- package/dist/cursor.js +39 -0
- package/dist/cursor.js.map +1 -0
- package/dist/dates.js +44 -0
- package/dist/dates.js.map +1 -0
- package/dist/errors.js +56 -0
- package/dist/errors.js.map +1 -0
- package/dist/fdaPrompt.js +29 -0
- package/dist/fdaPrompt.js.map +1 -0
- package/dist/fold.js +8 -0
- package/dist/fold.js.map +1 -0
- package/dist/helper.js +45 -0
- package/dist/helper.js.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/links.js +9 -0
- package/dist/links.js.map +1 -0
- package/dist/mailboxes.js +124 -0
- package/dist/mailboxes.js.map +1 -0
- package/dist/mime.js +151 -0
- package/dist/mime.js.map +1 -0
- package/dist/mimeTrim.js +222 -0
- package/dist/mimeTrim.js.map +1 -0
- package/dist/policy.js +84 -0
- package/dist/policy.js.map +1 -0
- package/dist/quickHtml.js +238 -0
- package/dist/quickHtml.js.map +1 -0
- package/dist/quotes.js +72 -0
- package/dist/quotes.js.map +1 -0
- package/dist/schemas.js +57 -0
- package/dist/schemas.js.map +1 -0
- package/dist/securityMail.data.js +34 -0
- package/dist/securityMail.data.js.map +1 -0
- package/dist/securityMail.js +82 -0
- package/dist/securityMail.js.map +1 -0
- package/dist/server.js +19 -0
- package/dist/server.js.map +1 -0
- package/dist/signing.js +64 -0
- package/dist/signing.js.map +1 -0
- package/dist/state.js +46 -0
- package/dist/state.js.map +1 -0
- package/dist/stdioRunner.js +206 -0
- package/dist/stdioRunner.js.map +1 -0
- package/dist/summary.js +57 -0
- package/dist/summary.js.map +1 -0
- package/dist/tools/getMessage.js +112 -0
- package/dist/tools/getMessage.js.map +1 -0
- package/dist/tools/getThread.js +52 -0
- package/dist/tools/getThread.js.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/listMailboxes.js +50 -0
- package/dist/tools/listMailboxes.js.map +1 -0
- package/dist/tools/respond.js +34 -0
- package/dist/tools/respond.js.map +1 -0
- package/dist/tools/searchMessages.js +159 -0
- package/dist/tools/searchMessages.js.map +1 -0
- package/package.json +60 -4
package/dist/bodyScan.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { fold } from './fold.js';
|
|
2
|
+
import { parseForScan } from './mime.js';
|
|
3
|
+
import { termSurvivesUnknownEntities } from './quickHtml.js';
|
|
4
|
+
import { getMessagesResult, searchResult } from './schemas.js';
|
|
5
|
+
import { classify } from './securityMail.js';
|
|
6
|
+
import { HelperError } from './errors.js';
|
|
7
|
+
export const CANDIDATE_CAP = 2000;
|
|
8
|
+
export const TIME_BUDGET_MS = 3000;
|
|
9
|
+
export const CANDIDATE_PAGE = 200;
|
|
10
|
+
export const BATCH = 50;
|
|
11
|
+
export const SCAN_BYTES_PER_MESSAGE = 256 * 1024;
|
|
12
|
+
export const SCAN_BYTES_TOTAL = 16 * 1024 * 1024;
|
|
13
|
+
export const CONTEXT_CHARS = 160;
|
|
14
|
+
const isSpace = (c) => /^\s$/u.test(c);
|
|
15
|
+
/** Zieht jede Leerraumfolge zu einem Leerzeichen zusammen und trimmt. */
|
|
16
|
+
function collapse(s) {
|
|
17
|
+
return s.replace(/\s+/gu, ' ').trim();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Faltet pro Codepoint und merkt sich, aus welcher Position des Originals jedes gefaltete
|
|
21
|
+
* Zeichen stammt. So bleiben Fundstellen auch dort exakt, wo die Faltung die Laenge aendert
|
|
22
|
+
* (scharfes s wird zu ss). Pro Codepoint zu falten weicht bei kontextabhaengigen Faellen (griechisches
|
|
23
|
+
* Schluss-Sigma) von der Faltung des ganzen Strings ab, und NFC kann pro Codepoint nichts
|
|
24
|
+
* zusammensetzen: ein zerlegtes "o" + Trema bleibt zerlegt. Deshalb wird der Suchbegriff vorher
|
|
25
|
+
* als Ganzes nach NFC gebracht (foldTerm); Mailtexte sind praktisch immer schon NFC.
|
|
26
|
+
*/
|
|
27
|
+
function foldWithMap(text) {
|
|
28
|
+
let folded = '';
|
|
29
|
+
const origin = [];
|
|
30
|
+
let i = 0;
|
|
31
|
+
for (const ch of text) {
|
|
32
|
+
const f = fold(ch);
|
|
33
|
+
for (let k = 0; k < f.length; k++)
|
|
34
|
+
origin.push(i);
|
|
35
|
+
folded += f;
|
|
36
|
+
i += ch.length;
|
|
37
|
+
}
|
|
38
|
+
return { folded, origin };
|
|
39
|
+
}
|
|
40
|
+
const foldCache = new Map();
|
|
41
|
+
/** fold fuer einen Lauf ohne ASCII, pro Codepoint wie foldWithMap (mit Zwischenspeicher). */
|
|
42
|
+
function foldRun(run) {
|
|
43
|
+
let out = '';
|
|
44
|
+
for (const ch of run) {
|
|
45
|
+
let f = foldCache.get(ch);
|
|
46
|
+
if (f === undefined) {
|
|
47
|
+
f = fold(ch);
|
|
48
|
+
if (foldCache.size < 4096)
|
|
49
|
+
foldCache.set(ch, f);
|
|
50
|
+
}
|
|
51
|
+
out += f;
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
// Unterhalb von U+0340 gleicht fold(c) fuer jedes Zeichen ausser dem scharfen s (U+00DF) dem
|
|
56
|
+
// einfachen toLowerCase
|
|
57
|
+
// (tests/bodyScan.test.ts prueft das fuer jeden Codepoint); nur der Rest braucht fold pro Zeichen.
|
|
58
|
+
const NEEDS_FOLD = /\u00df|[^\x00-\u033f]+/g;
|
|
59
|
+
/**
|
|
60
|
+
* Liefert genau foldWithMap(text).folded, nur schnell: U+00DF und Laeufe ab U+0340 werden pro
|
|
61
|
+
* Codepoint gefaltet, danach schreibt toLowerCase den Rest klein. Das ist gleichwertig, weil die
|
|
62
|
+
* Ausgabe von fold fuer jeden Codepoint schon klein ist (toLowerCase aendert sie nicht) und kein
|
|
63
|
+
* grosses Sigma enthaelt, die einzige kontextabhaengige Abbildung von toLowerCase. Die
|
|
64
|
+
* Positionstabelle entsteht erst bei einem Treffer (findMatch).
|
|
65
|
+
*/
|
|
66
|
+
export function foldFast(text) {
|
|
67
|
+
return text.replace(NEEDS_FOLD, foldRun).toLowerCase();
|
|
68
|
+
}
|
|
69
|
+
/** Suchbegriff: erst als Ganzes NFC (zerlegte Umlaute aus der Eingabe), dann wie der Text falten. */
|
|
70
|
+
function foldTerm(term) {
|
|
71
|
+
return collapse(foldWithMap(collapse(term.normalize('NFC'))).folded);
|
|
72
|
+
}
|
|
73
|
+
/** Erste Fundstelle des gefalteten Begriffs; Kontext aus dem Original (nur Leerraum zusammengezogen). */
|
|
74
|
+
export function findMatch(rawText, foldedTerm) {
|
|
75
|
+
const text = collapse(rawText);
|
|
76
|
+
if (!foldFast(text).includes(foldedTerm))
|
|
77
|
+
return null;
|
|
78
|
+
const { folded, origin } = foldWithMap(text);
|
|
79
|
+
const at = folded.indexOf(foldedTerm);
|
|
80
|
+
if (at < 0)
|
|
81
|
+
return null;
|
|
82
|
+
const start = origin[at];
|
|
83
|
+
const last = origin[at + foldedTerm.length - 1];
|
|
84
|
+
// Ende des Originalzeichens, das das letzte gefaltete Zeichen erzeugt hat.
|
|
85
|
+
const endCp = text.codePointAt(last);
|
|
86
|
+
const end = last + (endCp > 0xffff ? 2 : 1);
|
|
87
|
+
const len = end - start;
|
|
88
|
+
let from = start;
|
|
89
|
+
let to = end;
|
|
90
|
+
if (len < CONTEXT_CHARS) {
|
|
91
|
+
const pad = Math.floor((CONTEXT_CHARS - len) / 2);
|
|
92
|
+
from = Math.max(0, start - pad);
|
|
93
|
+
to = Math.min(text.length, from + CONTEXT_CHARS);
|
|
94
|
+
from = Math.max(0, to - CONTEXT_CHARS);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
to = from + CONTEXT_CHARS;
|
|
98
|
+
}
|
|
99
|
+
// Keine halben Surrogatpaare an den Raendern.
|
|
100
|
+
if (from > 0 && /[\udc00-\udfff]/.test(text[from]))
|
|
101
|
+
from++;
|
|
102
|
+
if (to < text.length && /[\ud800-\udbff]/.test(text[to - 1]))
|
|
103
|
+
to--;
|
|
104
|
+
return text.slice(from, to).trim();
|
|
105
|
+
}
|
|
106
|
+
/** Holt die Rohtexte eines Blocks (base64, null = nicht verfuegbar). Geparst wird erst im Scan. */
|
|
107
|
+
async function fetchBatch(runner, policy, batch) {
|
|
108
|
+
const out = new Map();
|
|
109
|
+
let pending = batch.filter((r) => r.file !== 'none').map((r) => r.gid);
|
|
110
|
+
for (const r of batch)
|
|
111
|
+
if (r.file === 'none')
|
|
112
|
+
out.set(r.gid, null);
|
|
113
|
+
while (pending.length > 0) {
|
|
114
|
+
const res = getMessagesResult.parse(await runner.run('get-messages', {
|
|
115
|
+
allowedMailboxIds: policy.allowedMailboxIds,
|
|
116
|
+
gids: pending,
|
|
117
|
+
maxBytesPerMessage: SCAN_BYTES_PER_MESSAGE,
|
|
118
|
+
maxBytesTotal: SCAN_BYTES_TOTAL,
|
|
119
|
+
}));
|
|
120
|
+
const retry = [];
|
|
121
|
+
const got = new Set();
|
|
122
|
+
for (const m of res.messages) {
|
|
123
|
+
got.add(m.gid);
|
|
124
|
+
if (m.raw === null) {
|
|
125
|
+
if (res.budgetExhausted && m.file !== 'none')
|
|
126
|
+
retry.push(m.gid);
|
|
127
|
+
else
|
|
128
|
+
out.set(m.gid, null);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
out.set(m.gid, m.raw);
|
|
132
|
+
}
|
|
133
|
+
for (const g of res.missing)
|
|
134
|
+
out.set(g, null);
|
|
135
|
+
// Weder geliefert noch als fehlend gemeldet: bei Budgetende nachfordern, sonst nicht verfuegbar.
|
|
136
|
+
for (const g of pending) {
|
|
137
|
+
if (got.has(g) || res.missing.includes(g))
|
|
138
|
+
continue;
|
|
139
|
+
if (res.budgetExhausted)
|
|
140
|
+
retry.push(g);
|
|
141
|
+
else
|
|
142
|
+
out.set(g, null);
|
|
143
|
+
}
|
|
144
|
+
// Ohne Fortschritt nicht endlos nachfordern; was dann fehlt, zaehlt als nicht verfuegbar.
|
|
145
|
+
pending = retry.length < pending.length ? retry : [];
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
// Leerraum fuer den Vorfilter; U+200B zaehlt dazu, wie bei html-to-text.
|
|
150
|
+
const LOOSE_SPACE = /[\s\u200b]+/g;
|
|
151
|
+
/**
|
|
152
|
+
* Prueft eine Nachricht: Treffer-Kontext, null ohne Treffer, undefined wenn nicht verfuegbar.
|
|
153
|
+
* Erst wird gesucht, dann klassifiziert: die Klassifikation entscheidet nur ueber Treffer.
|
|
154
|
+
* Ist der Scan-Text nur eine Naeherung (reines HTML oder gekuerzte Nachricht, siehe
|
|
155
|
+
* parseForScan), filtert er ohne Leerraum vor; ein moeglicher Treffer wird am Text von
|
|
156
|
+
* parseMessage bestaetigt, und genau dieser Text geht in die Sicherheitspruefung (E2).
|
|
157
|
+
*
|
|
158
|
+
* "Nicht verfuegbar" haengt nur vom Rohtext und vom schnellen Parsen ab, nie vom Suchbegriff.
|
|
159
|
+
* Scheitert der volle Text nach einem Vorfilter-Treffer, zaehlt das wie ein Fehlschlag des
|
|
160
|
+
* Vorfilters. Sonst verriete `unavailable` bei Begriffen wie "4", "48", ... einen Code.
|
|
161
|
+
*/
|
|
162
|
+
export async function examine(raw, row, term, looseTerm, showSecurityMails) {
|
|
163
|
+
const body = await parseForScan(Buffer.from(raw, 'base64'));
|
|
164
|
+
if (!body.ok)
|
|
165
|
+
return undefined;
|
|
166
|
+
let text = body.quick;
|
|
167
|
+
if (!body.exact) {
|
|
168
|
+
const usable = body.sure || termSurvivesUnknownEntities(looseTerm);
|
|
169
|
+
if (usable && !foldFast(body.quick.replace(LOOSE_SPACE, '')).includes(looseTerm))
|
|
170
|
+
return null;
|
|
171
|
+
text = await body.full();
|
|
172
|
+
}
|
|
173
|
+
if (text === null)
|
|
174
|
+
return null;
|
|
175
|
+
const ctx = findMatch(text, term);
|
|
176
|
+
if (ctx === null)
|
|
177
|
+
return null;
|
|
178
|
+
if (showSecurityMails)
|
|
179
|
+
return ctx;
|
|
180
|
+
const verdict = classify({ subject: row.subject, fromAddress: row.sender === null || row.sender.address === '' ? null : row.sender.address, text });
|
|
181
|
+
return verdict.security ? null : ctx;
|
|
182
|
+
}
|
|
183
|
+
export async function scanBodies(a) {
|
|
184
|
+
const now = a.now ?? Date.now;
|
|
185
|
+
const started = now();
|
|
186
|
+
const term = foldTerm(a.term);
|
|
187
|
+
if (term === '')
|
|
188
|
+
throw new HelperError('INVALID_INPUT', 'bodyContains must contain a visible character.');
|
|
189
|
+
const looseTerm = term.replace(LOOSE_SPACE, '');
|
|
190
|
+
const matches = [];
|
|
191
|
+
let scanned = 0;
|
|
192
|
+
let unavailable = 0;
|
|
193
|
+
let stoppedBy = null;
|
|
194
|
+
let resumeAfter = null;
|
|
195
|
+
let cursor = a.after;
|
|
196
|
+
// Zeitbudget vor jedem Helper-Abruf und vor jeder Nachricht pruefen. Mindestens ein Kandidat
|
|
197
|
+
// pro Aufruf, damit Weiterblaettern immer vorankommt.
|
|
198
|
+
const timeUp = () => scanned > 0 && now() - started >= TIME_BUDGET_MS;
|
|
199
|
+
outer: for (;;) {
|
|
200
|
+
if (timeUp()) {
|
|
201
|
+
stoppedBy = 'time';
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
const page = searchResult.parse(await a.runner.run('search', {
|
|
205
|
+
...a.filters,
|
|
206
|
+
// Nach den Filtern, damit sie die Policy nie ueberschreiben.
|
|
207
|
+
allowedMailboxIds: a.policy.allowedMailboxIds,
|
|
208
|
+
...(cursor ? { after: { date: cursor.d, gid: cursor.g } } : {}),
|
|
209
|
+
limit: CANDIDATE_PAGE,
|
|
210
|
+
maxRecipients: 5,
|
|
211
|
+
countTotal: false,
|
|
212
|
+
}));
|
|
213
|
+
const rows = page.messages;
|
|
214
|
+
for (let b = 0; b < rows.length; b += BATCH) {
|
|
215
|
+
if (timeUp()) {
|
|
216
|
+
stoppedBy = 'time';
|
|
217
|
+
break outer;
|
|
218
|
+
}
|
|
219
|
+
const batch = rows.slice(b, b + BATCH);
|
|
220
|
+
const fetched = await fetchBatch(a.runner, a.policy, batch);
|
|
221
|
+
for (let i = 0; i < batch.length; i++) {
|
|
222
|
+
if (timeUp()) {
|
|
223
|
+
stoppedBy = 'time';
|
|
224
|
+
break outer;
|
|
225
|
+
}
|
|
226
|
+
const row = batch[i];
|
|
227
|
+
scanned++;
|
|
228
|
+
resumeAfter = { d: row.dateReceived, g: row.gid };
|
|
229
|
+
cursor = resumeAfter;
|
|
230
|
+
const raw = fetched.get(row.gid) ?? null;
|
|
231
|
+
const ctx = raw === null ? undefined : await examine(raw, row, term, looseTerm, a.config.showSecurityMails);
|
|
232
|
+
if (ctx === undefined)
|
|
233
|
+
unavailable++;
|
|
234
|
+
else if (ctx !== null)
|
|
235
|
+
matches.push({ row, matchContext: ctx });
|
|
236
|
+
const more = i < batch.length - 1 || b + BATCH < rows.length || page.hasMore;
|
|
237
|
+
if (!more)
|
|
238
|
+
break outer;
|
|
239
|
+
if (matches.length >= a.limit) {
|
|
240
|
+
stoppedBy = 'limit';
|
|
241
|
+
break outer;
|
|
242
|
+
}
|
|
243
|
+
if (scanned >= CANDIDATE_CAP) {
|
|
244
|
+
stoppedBy = 'cap';
|
|
245
|
+
break outer;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (!page.hasMore || rows.length === 0)
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
const complete = stoppedBy === null;
|
|
253
|
+
return {
|
|
254
|
+
matches,
|
|
255
|
+
scan: { scanned, unavailable, stoppedBy, complete },
|
|
256
|
+
resumeAfter: complete ? null : resumeAfter,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=bodyScan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bodyScan.js","sourceRoot":"","sources":["../src/bodyScan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { arch as osArch, homedir } from 'node:os';
|
|
4
|
+
import { describeError, HelperError } from '../errors.js';
|
|
5
|
+
import { parseMailbox } from '../mailboxes.js';
|
|
6
|
+
import { computePolicy } from '../policy.js';
|
|
7
|
+
import { helloResult, listMailboxesResult, probeResult, searchResult } from '../schemas.js';
|
|
8
|
+
import { RELEASE_BUNDLE_ID, readBundleId, readBundleName } from '../signing.js';
|
|
9
|
+
import { readState } from '../state.js';
|
|
10
|
+
import { PROTOCOL_VERSION } from '../stdioRunner.js';
|
|
11
|
+
/** Systemtool mit absolutem Pfad, nie ueber eine Shell; wirft nie. */
|
|
12
|
+
export const defaultDoctorExec = (file, args) => {
|
|
13
|
+
const r = spawnSync(file, args, { encoding: 'utf8' });
|
|
14
|
+
return { stdout: r.stdout ?? '', stderr: r.stderr ?? '', status: r.status ?? 1 };
|
|
15
|
+
};
|
|
16
|
+
/** Ersetzt das Home-Verzeichnis durch ~ (Standardausgabe enthaelt keinen Benutzernamen). */
|
|
17
|
+
export function tildePath(path, home = homedir()) {
|
|
18
|
+
return home !== '' && home !== '/' && (path === home || path.startsWith(home + '/')) ? '~' + path.slice(home.length) : path;
|
|
19
|
+
}
|
|
20
|
+
function packageVersion() {
|
|
21
|
+
try {
|
|
22
|
+
const url = new URL('../../package.json', import.meta.url);
|
|
23
|
+
return JSON.parse(readFileSync(url, 'utf8')).version ?? 'unknown';
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return 'unknown';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Helper-Details (Pfade, Datenbanktext) nur mit --verbose; sonst nur der feste Text zum Code.
|
|
30
|
+
function errText(e, verbose = false) {
|
|
31
|
+
return e instanceof HelperError ? describeError(e.code, verbose ? e.message : undefined) : 'The helper could not be started.';
|
|
32
|
+
}
|
|
33
|
+
function parseCodesign(text) {
|
|
34
|
+
const pick = (re) => re.exec(text)?.[1]?.trim() ?? null;
|
|
35
|
+
return {
|
|
36
|
+
identifier: pick(/^Identifier=(.+)$/m),
|
|
37
|
+
authority: pick(/^Authority=(.+)$/m),
|
|
38
|
+
team: pick(/^TeamIdentifier=(.+)$/m),
|
|
39
|
+
runtime: /^CodeDirectory .*flags=0x[0-9a-f]+\([^)]*\bruntime\b/m.test(text),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const VERBOSE_WARNING = 'Warning: verbose output contains mailbox names and account identifiers. Do not paste it publicly.';
|
|
43
|
+
export async function runDoctor(deps) {
|
|
44
|
+
const { out, runner } = deps;
|
|
45
|
+
const checks = [];
|
|
46
|
+
const add = (id, status, message) => void checks.push({ id, status, message });
|
|
47
|
+
const verboseLines = [];
|
|
48
|
+
// --schema ohne --json: eigener, minimaler Pfad.
|
|
49
|
+
if (deps.schema && !deps.json)
|
|
50
|
+
return runSchema(deps);
|
|
51
|
+
const override = deps.override ?? (deps.configResult.ok && deps.configResult.config.helperPath !== null);
|
|
52
|
+
const channel = override ? 'override' : deps.bundlePath.includes('/Claude Extensions/') ? 'mcpb' : 'npm';
|
|
53
|
+
let helperVersion = 'unknown';
|
|
54
|
+
let protocol = 'unknown';
|
|
55
|
+
try {
|
|
56
|
+
const h = helloResult.parse(await runner.run('hello', {}));
|
|
57
|
+
helperVersion = h.helperVersion;
|
|
58
|
+
protocol = String(h.protocolVersion);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Der probe-Schritt meldet das Problem mit Klartext.
|
|
62
|
+
}
|
|
63
|
+
add('versions', protocol === 'unknown' || Number(protocol) === PROTOCOL_VERSION ? 'ok' : 'fail', `Package ${deps.packageVersion ?? packageVersion()}, helper ${helperVersion}, protocol ${protocol}, install channel ${channel}.`);
|
|
64
|
+
let probe = null;
|
|
65
|
+
let probeError = null;
|
|
66
|
+
// Rohantwort bzw. Fehler bleiben fuer --json --schema erhalten: ein zweiter probe-Aufruf waere teuer und koennte abweichen.
|
|
67
|
+
let probeRaw;
|
|
68
|
+
try {
|
|
69
|
+
probeRaw = { raw: await runner.run('probe', {}) };
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
probeRaw = { error: e };
|
|
73
|
+
}
|
|
74
|
+
if ('error' in probeRaw) {
|
|
75
|
+
probeError = errText(probeRaw.error, deps.verbose);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
try {
|
|
79
|
+
probe = probeResult.parse(probeRaw.raw);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
probeError = errText(e, deps.verbose);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
add('system', 'ok', `macOS ${probe?.osVersion ?? 'unknown'}, ${osArch()}, Node ${process.versions.node}.`);
|
|
86
|
+
// Helper-Bundle, Signatur, Stapling
|
|
87
|
+
const shownBundle = deps.verbose ? deps.bundlePath : tildePath(deps.bundlePath, deps.home);
|
|
88
|
+
let bundleId = null;
|
|
89
|
+
const execOne = (f, a) => {
|
|
90
|
+
const r = deps.exec(f, a);
|
|
91
|
+
if (r.status !== 0)
|
|
92
|
+
throw new Error('exec failed');
|
|
93
|
+
return r.stdout;
|
|
94
|
+
};
|
|
95
|
+
const helperName = readBundleName(deps.bundlePath, execOne);
|
|
96
|
+
try {
|
|
97
|
+
bundleId = readBundleId(deps.bundlePath, execOne);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
bundleId = null;
|
|
101
|
+
}
|
|
102
|
+
const isRelease = bundleId === RELEASE_BUNDLE_ID;
|
|
103
|
+
add('helper-bundle', bundleId ? 'ok' : 'fail', bundleId ? `Bundle ${shownBundle}, identifier ${bundleId}.` : `Bundle ${shownBundle} has no readable identifier.`);
|
|
104
|
+
const cs = deps.exec('/usr/bin/codesign', ['-dv', '--verbose=2', deps.bundlePath]);
|
|
105
|
+
if (cs.status !== 0) {
|
|
106
|
+
add('signature', 'fail', 'The helper bundle signature could not be read.');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const sig = parseCodesign(cs.stderr + '\n' + cs.stdout);
|
|
110
|
+
const authority = sig.authority ?? 'none (ad-hoc)';
|
|
111
|
+
const detail = `Authority ${authority}, team ${sig.team ?? 'none'}, hardened runtime ${sig.runtime ? 'on' : 'off'}.`;
|
|
112
|
+
add('signature', isRelease && (!sig.runtime || sig.team === null) ? 'fail' : sig.runtime || isRelease ? 'ok' : 'warn', detail);
|
|
113
|
+
}
|
|
114
|
+
const st = deps.exec('/usr/bin/xcrun', ['stapler', 'validate', deps.bundlePath]);
|
|
115
|
+
add('stapling', st.status === 0 ? 'ok' : isRelease ? 'fail' : 'warn', st.status === 0 ? 'Notarization ticket is stapled.' : 'Not stapled.');
|
|
116
|
+
// probe
|
|
117
|
+
if (probe === null) {
|
|
118
|
+
add('probe', 'fail', probeError ?? 'The helper did not answer.');
|
|
119
|
+
}
|
|
120
|
+
else if (probe.access !== 'granted') {
|
|
121
|
+
const msg = probe.access === 'denied'
|
|
122
|
+
? `Access: denied. Full Disk Access is not granted to ${helperName}. Run \`npx -y @redpop/apple-mail-mcp setup\`.`
|
|
123
|
+
: probe.access === 'no_mail_data'
|
|
124
|
+
? 'Access: no_mail_data. Apple Mail does not appear to be set up on this Mac.'
|
|
125
|
+
: 'Access: untrusted_signature. The helper refused to read mail because its signature is not trusted.';
|
|
126
|
+
add('probe', 'fail', msg);
|
|
127
|
+
}
|
|
128
|
+
else if (!probe.schema) {
|
|
129
|
+
add('probe', 'fail', 'Mail database could not be read (busy or damaged); try again.');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const s = probe.schema;
|
|
133
|
+
const c = probe.counts;
|
|
134
|
+
add('probe', s && !s.compatible ? 'fail' : 'ok', `Access granted, Mail directory ${probe.mailDir ?? 'unknown'}.`);
|
|
135
|
+
if (s) {
|
|
136
|
+
add('schema', s.compatible ? 'ok' : 'fail', s.compatible ? `Schema compatible, fingerprint ${s.fingerprint}.` : `Schema not supported, missing columns: ${s.missing.join(', ')}; fingerprint ${s.fingerprint}.`);
|
|
137
|
+
}
|
|
138
|
+
if (c)
|
|
139
|
+
add('counts', 'ok', `${c.mailboxes} mailboxes, ${c.messages} messages, ${c.uniqueMessages} unique.`);
|
|
140
|
+
}
|
|
141
|
+
if (probe) {
|
|
142
|
+
const an = probe.accountNames;
|
|
143
|
+
add('account-names', an.status === 'available' && an.unmatchedAccounts === 0 ? 'ok' : 'warn', an.status === 'available'
|
|
144
|
+
? `Account names available; ${an.unmatchedAccounts} mail accounts without a match${an.unmatchedAccounts > 0 ? ' (usually removed accounts; they are listed by UUID)' : ''}.`
|
|
145
|
+
: `Account names unavailable${deps.verbose && an.reason ? ` (${an.reason})` : ''}; ${an.unmatchedAccounts} mail accounts without a match.`);
|
|
146
|
+
}
|
|
147
|
+
// Verwaister FDA-Eintrag (Schluss aus der Zustandsdatei, keine Messung; Spec 12.4, E3)
|
|
148
|
+
if (probe?.access === 'denied') {
|
|
149
|
+
const state = readState(deps.stateDir);
|
|
150
|
+
if (state) {
|
|
151
|
+
add('stale-fda', 'fail', `Access worked on ${state.lastAccessOk.slice(0, 10)}. Since then macOS denies it. If ${helperName} is listed and switched on, remove the entry and add it again.`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Mailbox-Rollen, Abdeckung, Konfiguration
|
|
155
|
+
if (probe?.access === 'granted' && probe.schema) {
|
|
156
|
+
try {
|
|
157
|
+
const list = listMailboxesResult.parse(await runner.run('list-mailboxes', {}));
|
|
158
|
+
const parsed = list.mailboxes.map(parseMailbox);
|
|
159
|
+
const roles = new Map();
|
|
160
|
+
for (const m of parsed)
|
|
161
|
+
roles.set(m.role, (roles.get(m.role) ?? 0) + 1);
|
|
162
|
+
const summary = [...roles].map(([r, n]) => `${r} ${n}`).join(', ');
|
|
163
|
+
const missing = ['junk', 'trash'].filter((r) => !roles.has(r));
|
|
164
|
+
add('mailbox-roles', missing.length > 0 && parsed.length > 0 ? 'warn' : 'ok', missing.length > 0 && parsed.length > 0
|
|
165
|
+
? `Roles: ${summary || 'none'}. No ${missing.join(' or ')} mailbox recognised although accounts exist.`
|
|
166
|
+
: `Roles: ${summary}.`);
|
|
167
|
+
if (deps.verbose) {
|
|
168
|
+
for (const m of parsed)
|
|
169
|
+
verboseLines.push(`mailbox ${m.id}: ${m.name} (${m.role})`);
|
|
170
|
+
for (const a of new Set(parsed.map((m) => m.accountId)))
|
|
171
|
+
verboseLines.push(`account ${a}`);
|
|
172
|
+
}
|
|
173
|
+
if (deps.configResult.ok) {
|
|
174
|
+
const policy = computePolicy(deps.configResult.config, list);
|
|
175
|
+
add('config', policy.unmatchedAllowlistEntries > 0 ? 'warn' : 'ok', `Effective policy ${policy.fingerprint}: ${policy.allowedMailboxIds.length} of ${parsed.length} mailboxes visible, ${policy.unmatchedAllowlistEntries} account allowlist entries without a match.`);
|
|
176
|
+
try {
|
|
177
|
+
const res = searchResult.parse(await runner.run('search', { allowedMailboxIds: policy.allowedMailboxIds, limit: 500, countTotal: false, maxRecipients: 0 }));
|
|
178
|
+
const n = { full: 0, partial: 0, none: 0 };
|
|
179
|
+
for (const m of res.messages)
|
|
180
|
+
n[m.file]++;
|
|
181
|
+
add('local-files', 'ok', `Of the ${res.messages.length} newest messages: full ${n.full}, partial ${n.partial}, none ${n.none}.`);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
add('local-files', 'warn', `Local file coverage could not be measured. ${errText(e, deps.verbose)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
add('mailbox-roles', 'fail', `Mailboxes could not be listed. ${errText(e, deps.verbose)}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (!deps.configResult.ok)
|
|
193
|
+
add('config', 'fail', `Configuration error in ${deps.configResult.key}: ${deps.configResult.error}`);
|
|
194
|
+
// --json --schema: ein fehlender Schemateil zaehlt wie in `doctor --schema` als Fehlschlag.
|
|
195
|
+
const schema = deps.json && deps.schema ? schemaLines(probeRaw, deps.verbose) : null;
|
|
196
|
+
const exit = checks.some((c) => c.status === 'fail') || (schema !== null && !schema.ok) ? 1 : 0;
|
|
197
|
+
if (deps.json) {
|
|
198
|
+
const body = { checks, exitCode: exit };
|
|
199
|
+
if (deps.verbose)
|
|
200
|
+
body.verbose = { warning: VERBOSE_WARNING, lines: verboseLines };
|
|
201
|
+
if (schema)
|
|
202
|
+
body.schema = schema.lines;
|
|
203
|
+
out.write(JSON.stringify(body) + '\n');
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
if (deps.verbose)
|
|
207
|
+
out.write(VERBOSE_WARNING + '\n');
|
|
208
|
+
for (const c of checks)
|
|
209
|
+
out.write(`[${c.status}] ${c.id}: ${c.message}\n`);
|
|
210
|
+
for (const l of verboseLines)
|
|
211
|
+
out.write(l + '\n');
|
|
212
|
+
}
|
|
213
|
+
return exit;
|
|
214
|
+
}
|
|
215
|
+
function schemaLines(probe, verbose) {
|
|
216
|
+
if ('error' in probe)
|
|
217
|
+
return { lines: [errText(probe.error, verbose)], ok: false };
|
|
218
|
+
const p = probeResult.safeParse(probe.raw);
|
|
219
|
+
if (!p.success || !p.data.schema)
|
|
220
|
+
return { lines: ['No schema information available.'], ok: false };
|
|
221
|
+
const lines = [p.data.schema.fingerprint, ...p.data.schema.missing];
|
|
222
|
+
// Nur Anweisungen, die mit CREATE beginnen, je eine Zeile (mehrzeiliges DDL zusammengezogen).
|
|
223
|
+
for (const statement of p.data.schema.ddl ?? []) {
|
|
224
|
+
if (statement.startsWith('CREATE '))
|
|
225
|
+
lines.push(statement.replace(/\s+/g, ' ').trim());
|
|
226
|
+
}
|
|
227
|
+
return { lines, ok: true };
|
|
228
|
+
}
|
|
229
|
+
/** `doctor --schema`: nur Fingerabdruck, fehlende Spalten und ggf. CREATE-Zeilen, sonst nichts. */
|
|
230
|
+
async function runSchema(deps) {
|
|
231
|
+
let probe;
|
|
232
|
+
try {
|
|
233
|
+
probe = { raw: await deps.runner.run('probe', {}) };
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
probe = { error: e };
|
|
237
|
+
}
|
|
238
|
+
const r = schemaLines(probe, deps.verbose);
|
|
239
|
+
deps.out.write(r.lines.join('\n') + '\n');
|
|
240
|
+
return r.ok ? 0 : 1;
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { loadConfig } from '../config.js';
|
|
2
|
+
import { defaultOpen } from '../fdaPrompt.js';
|
|
3
|
+
import { createHelperRunner, packagedHelperBundle } from '../helper.js';
|
|
4
|
+
import { defaultDoctorExec, runDoctor } from './doctor.js';
|
|
5
|
+
import { runSetup } from './setup.js';
|
|
6
|
+
const DEFAULT_CONFIG = {
|
|
7
|
+
accounts: [], includeJunk: false, includeTrash: false, excludeMailboxes: [], showSecurityMails: false,
|
|
8
|
+
bodySearch: true, maxResults: 50, maxBodyChars: 20000, helperPath: null, debug: false,
|
|
9
|
+
};
|
|
10
|
+
/** Einstieg fuer `setup` und `doctor`; stoppt den Helper in jedem Fall vor der Rueckkehr. */
|
|
11
|
+
export async function runCli(command, args, deps = {}) {
|
|
12
|
+
const env = deps.env ?? process.env;
|
|
13
|
+
const out = deps.out ?? process.stdout;
|
|
14
|
+
const configResult = loadConfig(env);
|
|
15
|
+
let config;
|
|
16
|
+
if (configResult.ok) {
|
|
17
|
+
config = configResult.config;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
// Auch bei ungueltiger Konfiguration gilt der Helper-Override (leer = nicht gesetzt).
|
|
21
|
+
const h = env.APPLE_MAIL_HELPER_PATH?.trim();
|
|
22
|
+
config = { ...DEFAULT_CONFIG, helperPath: h ? h : null };
|
|
23
|
+
}
|
|
24
|
+
const runner = (deps.makeRunner ?? createHelperRunner)(config);
|
|
25
|
+
const onSignal = deps.onSignal ?? ((sig, h) => void process.on(sig, h));
|
|
26
|
+
const exit = deps.exit ?? ((c) => process.exit(c));
|
|
27
|
+
onSignal('SIGINT', () => { runner.stop(); exit(130); });
|
|
28
|
+
onSignal('SIGTERM', () => { runner.stop(); exit(143); });
|
|
29
|
+
try {
|
|
30
|
+
if (command === 'setup') {
|
|
31
|
+
return await runSetup({
|
|
32
|
+
runner,
|
|
33
|
+
bundlePath: runner.bundlePath || packagedHelperBundle(),
|
|
34
|
+
open: defaultOpen,
|
|
35
|
+
out,
|
|
36
|
+
override: config.helperPath !== null,
|
|
37
|
+
isTTY: deps.isTTY ?? process.stdout.isTTY === true,
|
|
38
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
39
|
+
now: Date.now,
|
|
40
|
+
...(configResult.ok ? {} : { configWarning: `${configResult.key}: ${configResult.error}` }),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return await runDoctor({
|
|
44
|
+
runner,
|
|
45
|
+
bundlePath: runner.bundlePath,
|
|
46
|
+
configResult,
|
|
47
|
+
override: config.helperPath !== null,
|
|
48
|
+
exec: defaultDoctorExec,
|
|
49
|
+
out,
|
|
50
|
+
verbose: args.includes('--verbose'),
|
|
51
|
+
json: args.includes('--json'),
|
|
52
|
+
schema: args.includes('--schema'),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
runner.stop();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|