@bobfrankston/rmfmail 1.0.678 → 1.0.679

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.
@@ -1,28 +1,40 @@
1
1
  /**
2
- * Right-click spell-check for the TinyMCE compose editor.
2
+ * Live spell-check for the TinyMCE compose editor.
3
3
  *
4
4
  * Why this exists: WebView2's built-in spell checker isn't reliably
5
5
  * enabled on our msger-hosted compose iframe (see msger main.rs around
6
- * AreDefaultContextMenusEnabled — settings are left at defaults but
7
- * `IsSpellcheckEnabled` is never explicitly set, and the default varies
8
- * by WebView2 runtime). Rather than depend on the host, we ship a JS
9
- * spellchecker (`nspell`) + the standard `dictionary-en` Hunspell files.
6
+ * AreDefaultContextMenusEnabled — the comment claims it leaves
7
+ * defaults for spell-suggest menus, but `IsSpellcheckEnabled` is never
8
+ * explicitly set and the default varies by WebView2 runtime). Rather
9
+ * than depend on the host, we ship a JS spellchecker (`nspell`) + the
10
+ * standard `dictionary-en` Hunspell files.
10
11
  *
11
- * Scope (intentionally minimal — Bob 2026-05-11):
12
- * - On right-click inside the editor body, find the word at the click.
13
- * - If nspell flags it, show a small popup with suggestions plus an
14
- * "Add to mailx dictionary" item.
15
- * - Custom dictionary persists in localStorage under
16
- * `mailx-user-dict`; added words are also fed to nspell.add() so the
17
- * same session stops flagging them immediately.
18
- * - No live red-underline decoration that would mutate DOM the user
19
- * is actively typing into and adds significant complexity. The
20
- * right-click flow gives the suggestions experience without the
21
- * editing-experience tradeoffs.
12
+ * Two layers:
13
+ * 1. Live decoration words that nspell flags get wrapped in a
14
+ * `<span data-mailx-spellerror="1">` while editing. CSS gives them
15
+ * a wavy red underline (text-decoration: underline wavy #d33). The
16
+ * markers are stripped at serialization time so they never reach
17
+ * the sent message or the saved draft.
18
+ * 2. Right-click clicking on a marker shows our own popup with
19
+ * suggestions plus "Add to dictionary" / "Ignore (this session)".
22
20
  *
23
- * Loads nspell + the ~1 MB dictionary lazily on first right-click in
24
- * an editor session, so picking TinyMCE in Settings doesn't pay this
25
- * cost up front.
21
+ * Decoration runs:
22
+ * - Once after the editor inits + dict loads (initial scan of pre-
23
+ * populated quote / signature, though we skip blockquote content).
24
+ * - Debounced after every input (~500 ms idle).
25
+ * - After setContent (paste, reply-quote insertion, …).
26
+ *
27
+ * The decoration walker:
28
+ * - Skips `<blockquote>` (the quoted reply — not the user's words),
29
+ * `<code>`, `<pre>`, `<a>` (URLs aren't natural-language words),
30
+ * and content inside any existing marker (so re-scans don't double-
31
+ * wrap).
32
+ * - Uses TinyMCE's `undoManager.ignore` + selection bookmarks so the
33
+ * decoration mutations don't pollute undo and don't move the caret.
34
+ *
35
+ * Dictionary persistence:
36
+ * - User additions: `localStorage["mailx-user-dict"]` (a JSON array).
37
+ * - "Ignore this session": in-memory only via `nspell.add()`.
26
38
  */
27
39
  // @ts-expect-error — nspell ships no type defs. Treated as `any`; the
28
40
  // surface we use (`new NSpell({aff, dic})`, `.correct`, `.suggest`,
@@ -31,14 +43,15 @@ import NSpell from "nspell";
31
43
  type NSpell = any;
32
44
 
33
45
  const USER_DICT_KEY = "mailx-user-dict";
46
+ const MARKER_ATTR = "data-mailx-spellerror";
47
+ const DECORATE_DEBOUNCE_MS = 500;
48
+ const MIN_WORD_LEN = 3;
49
+ const SKIP_TAGS = new Set(["BLOCKQUOTE", "CODE", "PRE", "A", "SCRIPT", "STYLE", "KBD", "SAMP", "VAR"]);
34
50
 
35
51
  let spellPromise: Promise<NSpell> | null = null;
36
52
  async function getSpell(): Promise<NSpell> {
37
53
  if (spellPromise) return spellPromise;
38
54
  spellPromise = (async () => {
39
- // Paths are relative to compose.html. msger serves files from
40
- // contentDir=client/, so `../lib/dict/...` lands in the right
41
- // place under both msger.localhost and Android file:// schemes.
42
55
  const [affRes, dicRes] = await Promise.all([
43
56
  fetch("../lib/dict/en.aff"),
44
57
  fetch("../lib/dict/en.dic"),
@@ -48,11 +61,10 @@ async function getSpell(): Promise<NSpell> {
48
61
  }
49
62
  const [aff, dic] = await Promise.all([affRes.text(), dicRes.text()]);
50
63
  const sp = new NSpell({ aff, dic });
51
- // Seed with user dictionary.
52
64
  try {
53
65
  const raw = localStorage.getItem(USER_DICT_KEY);
54
66
  if (raw) for (const w of JSON.parse(raw) as string[]) sp.add(w);
55
- } catch { /* corrupt localStorage entry — start clean */ }
67
+ } catch { /* corrupt entry — start clean */ }
56
68
  return sp;
57
69
  })();
58
70
  return spellPromise;
@@ -65,59 +77,153 @@ function addToUserDict(word: string, sp: NSpell): void {
65
77
  if (arr.includes(word)) return;
66
78
  arr.push(word);
67
79
  localStorage.setItem(USER_DICT_KEY, JSON.stringify(arr));
68
- } catch { /* localStorage write failed — at least the in-memory add wins for this session */ }
80
+ } catch { /* */ }
69
81
  sp.add(word);
70
82
  }
71
83
 
72
- /** Find the word at a given (x,y) point inside a document. Uses
73
- * `caretPositionFromPoint` (Firefox) or `caretRangeFromPoint`
74
- * (WebKit/Blink). Returns the word string + a Range covering it,
75
- * or null if the click was on whitespace / punctuation / outside text. */
76
- function wordAtPoint(doc: Document, x: number, y: number): { word: string; range: Range } | null {
77
- const anyDoc = doc as any;
78
- let caretNode: Node | null = null;
79
- let caretOffset = 0;
80
- if (typeof anyDoc.caretRangeFromPoint === "function") {
81
- const r = anyDoc.caretRangeFromPoint(x, y) as Range | null;
82
- if (!r) return null;
83
- caretNode = r.startContainer;
84
- caretOffset = r.startOffset;
85
- } else if (typeof anyDoc.caretPositionFromPoint === "function") {
86
- const p = anyDoc.caretPositionFromPoint(x, y);
87
- if (!p) return null;
88
- caretNode = p.offsetNode;
89
- caretOffset = p.offset;
90
- } else {
91
- return null;
84
+ // ── Live decoration ───────────────────────────────────────────────
85
+
86
+ /** Walk the editor body, wrap newly-misspelled words, unwrap markers
87
+ * that are now correct. Mutations are wrapped in undoManager.ignore so
88
+ * they don't pollute undo history; selection is preserved via a
89
+ * TinyMCE bookmark. */
90
+ function decorate(editor: any, sp: NSpell): void {
91
+ const body: HTMLElement | null = editor.getBody?.();
92
+ const doc: Document | null = editor.getDoc?.();
93
+ if (!body || !doc) return;
94
+
95
+ // Don't fight active typing — if the caret is INSIDE a current
96
+ // misspelling marker, the user is mid-correction. Let them finish.
97
+ // We'll re-scan after the debounce on their next pause.
98
+ const sel = doc.getSelection();
99
+ if (sel && sel.rangeCount > 0) {
100
+ const focus = sel.focusNode as Node | null;
101
+ let p: Node | null = focus;
102
+ while (p && p !== body) {
103
+ if (p.nodeType === Node.ELEMENT_NODE && (p as Element).hasAttribute?.(MARKER_ATTR)) {
104
+ // Cursor inside a marker — skip this pass; re-decorate
105
+ // when they next stop typing.
106
+ return;
107
+ }
108
+ p = p.parentNode;
109
+ }
92
110
  }
93
- if (!caretNode || caretNode.nodeType !== Node.TEXT_NODE) return null;
94
- const text = (caretNode as Text).data;
95
- // Expand left and right from caret to a word boundary. Hunspell-ish
96
- // word characters: letters, digits, apostrophe, hyphen-in-word.
97
- const isWordChar = (ch: string): boolean => /[\p{L}\p{N}'’\-]/u.test(ch);
98
- let start = caretOffset;
99
- let end = caretOffset;
100
- while (start > 0 && isWordChar(text[start - 1])) start--;
101
- while (end < text.length && isWordChar(text[end])) end++;
102
- if (start === end) return null;
103
- // Strip leading/trailing punctuation a word boundary regex might
104
- // have included (apostrophe at the edge: "'hello" → "hello").
105
- let word = text.slice(start, end);
106
- while (word.length && /^['’\-]/.test(word)) { word = word.slice(1); start++; }
107
- while (word.length && /['’\-]$/.test(word)) { word = word.slice(0, -1); end--; }
108
- if (!word) return null;
109
- const range = doc.createRange();
110
- range.setStart(caretNode, start);
111
- range.setEnd(caretNode, end);
112
- return { word, range };
111
+
112
+ const bookmark = editor.selection?.getBookmark?.(2);
113
+ try {
114
+ editor.undoManager?.ignore?.(() => {
115
+ // 1. Unwrap any existing markers we'll re-wrap fresh based
116
+ // on the current content. Cheaper than incremental update
117
+ // and avoids stale markers if the user fixed a word
118
+ // without going through our menu (just retyped it).
119
+ const old = body.querySelectorAll(`span[${MARKER_ATTR}]`);
120
+ for (const m of old) {
121
+ const parent = m.parentNode;
122
+ if (!parent) continue;
123
+ while (m.firstChild) parent.insertBefore(m.firstChild, m);
124
+ parent.removeChild(m);
125
+ }
126
+ // Merge text nodes that were split by the now-removed spans.
127
+ body.normalize();
128
+
129
+ // 2. Walk text nodes and collect words to wrap.
130
+ const walker = doc.createTreeWalker(body, NodeFilter.SHOW_TEXT, {
131
+ acceptNode(node) {
132
+ let p: Node | null = node.parentNode;
133
+ while (p && p !== body) {
134
+ if (p.nodeType === Node.ELEMENT_NODE && SKIP_TAGS.has((p as Element).tagName)) {
135
+ return NodeFilter.FILTER_REJECT;
136
+ }
137
+ p = p.parentNode;
138
+ }
139
+ return NodeFilter.FILTER_ACCEPT;
140
+ },
141
+ });
142
+ type Hit = { node: Text; start: number; end: number };
143
+ const hits: Hit[] = [];
144
+ let n: Node | null = walker.nextNode();
145
+ // Letter / digit / apostrophe / hyphen — tokenize words via
146
+ // Unicode-aware regex so we don't false-flag accented words.
147
+ const WORD_RE = /[\p{L}][\p{L}'’\-]*/gu;
148
+ while (n) {
149
+ const tn = n as Text;
150
+ const text = tn.data;
151
+ let m: RegExpExecArray | null;
152
+ WORD_RE.lastIndex = 0;
153
+ while ((m = WORD_RE.exec(text)) !== null) {
154
+ const word = m[0];
155
+ if (word.length < MIN_WORD_LEN) continue;
156
+ if (sp.correct(word)) continue;
157
+ hits.push({ node: tn, start: m.index, end: m.index + word.length });
158
+ }
159
+ n = walker.nextNode();
160
+ }
161
+
162
+ // 3. Wrap hits in reverse order — wrapping a span splits the
163
+ // text node, which would invalidate earlier offsets. Going
164
+ // right-to-left keeps the not-yet-touched offsets valid.
165
+ hits.reverse();
166
+ for (const h of hits) {
167
+ const range = doc.createRange();
168
+ range.setStart(h.node, h.start);
169
+ range.setEnd(h.node, h.end);
170
+ const span = doc.createElement("span");
171
+ span.setAttribute(MARKER_ATTR, "1");
172
+ try { range.surroundContents(span); }
173
+ catch { /* range spans a node boundary — rare; skip */ }
174
+ }
175
+ });
176
+ } finally {
177
+ if (bookmark) try { editor.selection?.moveToBookmark?.(bookmark); } catch { /* */ }
178
+ }
179
+ }
180
+
181
+ /** Inject the wavy-red CSS into the editor iframe. */
182
+ function installDecorationStyle(editor: any): void {
183
+ const doc: Document | null = editor.getDoc?.();
184
+ if (!doc) return;
185
+ if (doc.getElementById("mailx-spell-style")) return;
186
+ const style = doc.createElement("style");
187
+ style.id = "mailx-spell-style";
188
+ style.textContent = `
189
+ span[${MARKER_ATTR}] {
190
+ text-decoration: underline wavy #d33;
191
+ text-decoration-skip-ink: none;
192
+ text-underline-offset: 2px;
193
+ /* No background — keeps the styling subtle, like a native
194
+ * spell underline, not a Find-highlight. */
195
+ background: transparent;
196
+ }
197
+ `;
198
+ doc.head.appendChild(style);
113
199
  }
114
200
 
115
- /** Show a small floating menu at (x, y) in the parent document
116
- * (NOT inside the editor iframe the iframe clips to its own bounds,
117
- * and a positioned menu can extend past the iframe edge). Returns
118
- * a remove() function. */
119
- function showSuggestionsMenu(parentDoc: Document, x: number, y: number, items: Array<{ label: string; action: () => void; emphasized?: boolean }>): void {
120
- // Close any prior instance.
201
+ /** Strip decoration markers from serialized output. TinyMCE fires
202
+ * attribute filters during getContent / draft-save; this filter
203
+ * unwraps the span so the saved/sent HTML carries only the text. */
204
+ function installSerializerFilter(editor: any): void {
205
+ if ((editor as any).__mailxSpellSerializerWired) return;
206
+ (editor as any).__mailxSpellSerializerWired = true;
207
+ try {
208
+ editor.serializer.addAttributeFilter(MARKER_ATTR, (nodes: any[]) => {
209
+ for (const node of nodes) {
210
+ // TinyMCE's html-node API: `unwrap()` replaces the node
211
+ // with its children. Exactly what we want — keep the
212
+ // text, drop the span.
213
+ if (typeof node.unwrap === "function") node.unwrap();
214
+ }
215
+ });
216
+ } catch (e) {
217
+ console.warn("[spellcheck] serializer filter setup failed:", e);
218
+ }
219
+ }
220
+
221
+ // ── Context menu ──────────────────────────────────────────────────
222
+
223
+ function showSuggestionsMenu(
224
+ parentDoc: Document, x: number, y: number,
225
+ items: Array<{ label: string; action: () => void; emphasized?: boolean; separator?: boolean }>,
226
+ ): void {
121
227
  parentDoc.getElementById("mailx-spell-menu")?.remove();
122
228
  const menu = parentDoc.createElement("div");
123
229
  menu.id = "mailx-spell-menu";
@@ -132,11 +238,11 @@ function showSuggestionsMenu(parentDoc: Document, x: number, y: number, items: A
132
238
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
133
239
  padding: 4px 0;
134
240
  font: 13px system-ui, sans-serif;
135
- min-width: 160px;
241
+ min-width: 180px;
136
242
  max-width: 320px;
137
243
  `;
138
244
  for (const it of items) {
139
- if (it.label === "---") {
245
+ if (it.separator) {
140
246
  const sep = parentDoc.createElement("div");
141
247
  sep.style.cssText = "border-top:1px solid var(--color-border,#ddd); margin: 4px 0;";
142
248
  menu.appendChild(sep);
@@ -159,11 +265,9 @@ function showSuggestionsMenu(parentDoc: Document, x: number, y: number, items: A
159
265
  menu.appendChild(btn);
160
266
  }
161
267
  parentDoc.body.appendChild(menu);
162
- // Clamp into viewport if it would overflow.
163
268
  const r = menu.getBoundingClientRect();
164
269
  if (r.right > window.innerWidth) menu.style.left = `${Math.max(8, window.innerWidth - r.width - 8)}px`;
165
270
  if (r.bottom > window.innerHeight) menu.style.top = `${Math.max(8, window.innerHeight - r.height - 8)}px`;
166
- // Dismiss on next click anywhere or Esc.
167
271
  const dismiss = (e: Event) => {
168
272
  if (e.type === "keydown" && (e as KeyboardEvent).key !== "Escape") return;
169
273
  if (e.type === "mousedown" && menu.contains(e.target as Node)) return;
@@ -177,12 +281,13 @@ function showSuggestionsMenu(parentDoc: Document, x: number, y: number, items: A
177
281
  }, 0);
178
282
  }
179
283
 
180
- /** Replace the text covered by `range` with `replacement` via a normal
181
- * Selection edit TinyMCE observes this through its normal undo /
182
- * dirty-tracking pathway. Document.execCommand("insertText") gives the
183
- * best undo integration; fall back to range mutation if the command
184
- * isn't recognized (older WebViews). */
185
- function replaceRange(doc: Document, range: Range, replacement: string): void {
284
+ /** Replace a misspelling marker span with the correction. Done via
285
+ * range-based selection + insertText so TinyMCE's undo stack and
286
+ * dirty-tracking pick it up properly. */
287
+ function replaceMarker(editor: any, marker: HTMLElement, replacement: string): void {
288
+ const doc: Document = editor.getDoc();
289
+ const range = doc.createRange();
290
+ range.selectNode(marker);
186
291
  const sel = doc.getSelection();
187
292
  if (!sel) return;
188
293
  sel.removeAllRanges();
@@ -198,70 +303,81 @@ function replaceRange(doc: Document, range: Range, replacement: string): void {
198
303
  }
199
304
  }
200
305
 
201
- /** Wire the right-click spell-suggest flow into a TinyMCE editor instance.
202
- * Idempotent (safe to call multiple times — only attaches once). */
306
+ // ── Public entry point ────────────────────────────────────────────
307
+
308
+ /** Wire the spell-check into a TinyMCE editor instance. Idempotent. */
203
309
  export function wireSpellcheck(editor: any): void {
204
310
  if ((editor as any).__mailxSpellWired) return;
205
311
  (editor as any).__mailxSpellWired = true;
206
312
 
207
- const iframeDoc: Document | null = editor.getDoc?.() || null;
208
- if (!iframeDoc) return;
313
+ let sp: NSpell | null = null;
314
+ let decorateTimer: ReturnType<typeof setTimeout> | null = null;
315
+ const scheduleDecorate = (): void => {
316
+ if (!sp) return;
317
+ if (decorateTimer) clearTimeout(decorateTimer);
318
+ decorateTimer = setTimeout(() => {
319
+ decorateTimer = null;
320
+ if (sp) decorate(editor, sp);
321
+ }, DECORATE_DEBOUNCE_MS);
322
+ };
323
+
324
+ // Kick off the dictionary load. First decoration runs as soon as
325
+ // it resolves; subsequent runs are triggered by editor events.
326
+ getSpell().then((loaded) => {
327
+ sp = loaded;
328
+ installDecorationStyle(editor);
329
+ installSerializerFilter(editor);
330
+ decorate(editor, loaded);
331
+ }).catch((err) => {
332
+ console.error("[spellcheck] dict load failed:", err);
333
+ });
334
+
335
+ // Re-decorate on edits / paste / content swap. `nodechange` covers
336
+ // most of these; `input` catches typing in finer-grained events on
337
+ // some TinyMCE versions.
338
+ editor.on("input nodechange setcontent paste keyup", scheduleDecorate);
209
339
 
340
+ // Right-click handler. If the click landed on a marker span, show
341
+ // suggestions; otherwise let the default menu (WebView2's) fire.
342
+ const iframeDoc: Document = editor.getDoc();
210
343
  iframeDoc.addEventListener("contextmenu", (ev: Event) => {
211
344
  const e = ev as MouseEvent;
212
- // Translate the iframe-internal point to the parent's viewport
213
- // for menu positioning. The iframe element's bounding rect plus
214
- // the event's clientX/Y inside the iframe gives parent-relative
215
- // coords.
345
+ const target = e.target as HTMLElement | null;
346
+ if (!target) return;
347
+ const marker = target.closest?.(`span[${MARKER_ATTR}]`) as HTMLElement | null;
348
+ if (!marker) return; // not on a misspelled word — default menu fires
349
+ const word = marker.textContent || "";
350
+ if (!word || !sp) return;
351
+ e.preventDefault();
352
+ e.stopPropagation();
353
+ const sugs: string[] = sp.suggest(word).slice(0, 7);
216
354
  const iframeEl = editor.iframeElement as HTMLIFrameElement | undefined;
217
- if (!iframeEl) return;
218
- const found = wordAtPoint(iframeDoc, e.clientX, e.clientY);
219
- if (!found) return; // not on a word — let WebView2 default fire
220
- // Lazy-load the dictionary. First right-click on a word in any
221
- // editor session triggers the load; subsequent are instant.
222
- getSpell().then(sp => {
223
- if (sp.correct(found.word)) return; // word IS in the dictionary, no menu
224
- // Misspelled — suppress default and show suggestions.
225
- const sugs = sp.suggest(found.word).slice(0, 7);
226
- const iframeRect = iframeEl.getBoundingClientRect();
227
- const menuX = iframeRect.left + e.clientX;
228
- const menuY = iframeRect.top + e.clientY;
229
- const items: Array<{ label: string; action: () => void; emphasized?: boolean }> = [];
230
- if (sugs.length === 0) {
231
- items.push({ label: "(no suggestions)", action: () => { /* */ } });
232
- } else {
233
- for (const s of sugs) {
234
- items.push({
235
- label: s,
236
- emphasized: true,
237
- action: () => replaceRange(iframeDoc, found.range, s),
238
- });
239
- }
355
+ const iframeRect = iframeEl ? iframeEl.getBoundingClientRect() : { left: 0, top: 0 };
356
+ const items: Array<{ label: string; action: () => void; emphasized?: boolean; separator?: boolean }> = [];
357
+ if (sugs.length === 0) {
358
+ items.push({ label: "(no suggestions)", action: () => { /* */ } });
359
+ } else {
360
+ for (const s of sugs) {
361
+ items.push({
362
+ label: s,
363
+ emphasized: true,
364
+ action: () => {
365
+ replaceMarker(editor, marker, s);
366
+ // Re-decorate so the replacement is checked too.
367
+ scheduleDecorate();
368
+ },
369
+ });
240
370
  }
241
- items.push({ label: "---", action: () => { /* */ } });
242
- items.push({
243
- label: `Add "${found.word}" to dictionary`,
244
- action: () => addToUserDict(found.word, sp),
245
- });
246
- items.push({
247
- label: "Ignore (this session)",
248
- action: () => sp.add(found.word),
249
- });
250
- showSuggestionsMenu(document, menuX, menuY, items);
251
- }).catch(err => {
252
- // Dict load failed (network / corrupt files). Don't intercept
253
- // the menu — let WebView2 default fire. Log so it's debuggable.
254
- console.error("[spellcheck] dict load failed:", err);
255
- return;
371
+ }
372
+ items.push({ label: "", action: () => { /* */ }, separator: true });
373
+ items.push({
374
+ label: `Add "${word}" to dictionary`,
375
+ action: () => { if (sp) addToUserDict(word, sp); scheduleDecorate(); },
256
376
  });
257
- // Preempt the browser default ONLY when we're about to show our
258
- // own menu. We don't know synchronously whether the word is
259
- // misspelled (the load is async), so we have to commit to either
260
- // intercepting or not. Compromise: preempt always when on a
261
- // word, then dismiss instantly if the word turned out correct.
262
- // For the user's typical case (right-click on text), this means
263
- // a brief moment where neither menu shows — acceptable.
264
- e.preventDefault();
265
- e.stopPropagation();
377
+ items.push({
378
+ label: "Ignore (this session)",
379
+ action: () => { if (sp) sp.add(word); scheduleDecorate(); },
380
+ });
381
+ showSuggestionsMenu(document, iframeRect.left + e.clientX, iframeRect.top + e.clientY, items);
266
382
  }, true);
267
383
  }
package/docs/accounts.md CHANGED
@@ -19,7 +19,13 @@
19
19
  "imap": { "host": "imap.example.com", "port": 993, "tls": true, "auth": "password" },
20
20
  "smtp": { "host": "smtp.example.com", "port": 465, "tls": true, "auth": "password" },
21
21
  "enabled": true, // false skips this account at startup
22
- "identityDomains": ["alias.com"] // extra domains for Reply-From auto-detect
22
+ "identityDomains": ["alias.com"], // extra domains for Reply-From auto-detect
23
+ "sig": { // signature appended to NEW messages only (not replies/forwards)
24
+ "text": "—\nBob Frankston\nbob@example.com", // \n becomes <br>; HTML-escaped
25
+ "html": false // reserved; leave false (true would trust `text` as raw HTML)
26
+ },
27
+ "signature": "<p>—<br>Bob Frankston</p>" // alternative form: HTML string,
28
+ // applied to new + reply + forward
23
29
  }
24
30
  ],
25
31
  "keys": { // AI provider API keys (optional)
@@ -37,6 +43,8 @@
37
43
  - **auth** — `"password"` for traditional IMAP/SMTP, `"oauth2"` for Gmail/Google Workspace/Outlook.
38
44
  - **enabled** — set `false` to keep the account record but skip sync at startup.
39
45
  - **identityDomains** — addresses you receive at on alternative domains. When you Reply, rmfmail picks the matching identity address as From instead of the account's primary.
46
+ - **sig** — per-account signature for *new* messages (skipped on reply / forward / draft-resume). `text` is the plain-text body, HTML-escaped at insertion with `\n` → `<br>`. The optional `html` flag is reserved for "trust as raw HTML"; leave it `false` (or omit) for now. Specify either `sig` or `signature`, not both — `sig` wins if both are present and the message is new.
47
+ - **signature** — legacy alternative: an HTML string applied to *new + reply + forward* (positioned before the quote on replies, at the end for new messages). Useful when you want the signature on every outgoing message regardless of context.
40
48
  - **keys.anthropic / keys.openai** — API keys for the AI features (translate / proofread / summarize / autocomplete). Lives at the file's top level alongside `accounts:` so you set it once across all your devices. Generated at console.anthropic.com or platform.openai.com. Provider selection is in `preferences.jsonc`; the key here is read based on which provider is active. Empty string means "not configured" — the AI feature silently no-ops. Local Ollama provider needs no key.
41
49
 
42
50
  ## Notes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.0.678",
3
+ "version": "1.0.679",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -42,7 +42,7 @@
42
42
  "@bobfrankston/msger": "^0.1.378",
43
43
  "@bobfrankston/node-tcp-transport": "^0.1.8",
44
44
  "@bobfrankston/oauthsupport": "^1.0.26",
45
- "@bobfrankston/rmf-tiny": "^0.1.8",
45
+ "@bobfrankston/rmf-tiny": "^0.1.9",
46
46
  "@bobfrankston/smtp-direct": "^0.1.8",
47
47
  "@bobfrankston/tcp-transport": "^0.1.6",
48
48
  "@capacitor/android": "^8.3.0",
@@ -122,7 +122,7 @@
122
122
  "@bobfrankston/msger": "^0.1.378",
123
123
  "@bobfrankston/node-tcp-transport": "^0.1.8",
124
124
  "@bobfrankston/oauthsupport": "^1.0.26",
125
- "@bobfrankston/rmf-tiny": "^0.1.8",
125
+ "@bobfrankston/rmf-tiny": "^0.1.9",
126
126
  "@bobfrankston/smtp-direct": "^0.1.8",
127
127
  "@bobfrankston/tcp-transport": "^0.1.6",
128
128
  "@capacitor/android": "^8.3.0",
@@ -33,6 +33,7 @@ export declare class MailxService {
33
33
  private db;
34
34
  private imapManager;
35
35
  private _accountsCache;
36
+ private _contactsCorpusSeeded;
36
37
  private _settingsCache;
37
38
  private popupFn;
38
39
  /** Inject the popup implementation. Called once at startup from
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}