@bobfrankston/rmfmail 1.2.167 → 1.2.169
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 +1 -0
- package/TODO.md +1 -0
- package/client/app.bundle.js +28 -0
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +23 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +18 -0
- package/client/compose/compose.bundle.js +292 -0
- package/client/compose/compose.bundle.js.map +4 -4
- package/client/compose/compose.js +23 -0
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +20 -0
- package/client/compose/harper-lint.js +269 -0
- package/client/compose/harper-lint.js.map +1 -0
- package/client/compose/harper-lint.ts +265 -0
- package/client/index.html +1 -0
- package/client/lib/api-client.js +8 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +8 -0
- package/client/lib/mailxapi.js +6 -0
- package/docs/harper-integration.md +120 -0
- package/package.json +8 -5
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +11 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +60 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +58 -0
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-settings/docs/harper-integration.md +120 -0
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-types/mailx-api.d.ts +12 -0
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +4 -0
- package/packages/mailx-types/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-28172 → node_modules.npmglobalize-stash-69656}/.package-lock.json +0 -0
package/README.md
CHANGED
|
@@ -240,6 +240,7 @@ Under **View** in the toolbar:
|
|
|
240
240
|
|
|
241
241
|
Under **Settings** in the toolbar:
|
|
242
242
|
- **Editor** -- Choose between Quill (default), tiptap, or TinyMCE for compose
|
|
243
|
+
- **Grammar check (Harper)** -- Live grammar, phrasing, capitalization, and repetition squiggles (dotted blue) while composing, in all three editors. Click a squiggle for an explanation and one-click fixes. Powered by [Harper](https://writewithharper.com/), Automattic's open-source grammar checker (Apache-2.0) -- the engine runs entirely on this machine inside the rmfmail service, so draft text never leaves your computer. English only (dialect-aware). Quoted reply text is not checked; spelling stays with the native red-squiggle spellchecker. On by default. More about Harper: <https://writewithharper.com/> and <https://github.com/automattic/harper>.
|
|
243
244
|
- **External editor (Edit in Word)** -- Open the compose body in Microsoft Word or LibreOffice Writer for heavy editing (Auto / Word / LibreOffice)
|
|
244
245
|
- **Auto mark-as-read** -- Mark a viewed message read after a short, configurable delay (delay in seconds; 0 = immediately). Turn off to require an explicit Mark-read.
|
|
245
246
|
- **Check sender reputation (DNSBLs)** -- When opening a message with remote content, look the sender's domain up in three free blocklists in parallel (off by default; each query leaks the bare domain to that DNSBL)
|
package/TODO.md
CHANGED
|
@@ -20,6 +20,7 @@ These items don't need user input — source-only changes, compile-verified befo
|
|
|
20
20
|
| **6** | **C125 — Unify desktop + Android IMAP code paths** | M | Today's split (`mailx-imap` Node-only + `mailx-store-web` browser-only) duplicates orchestration that's protocol-identical. Differences boil down to (a) transport factory choice (b) whether clients are persistent — both parameters, not architectural divides. Plan: extract `mailx-imap-core` with ImapManager + ops queue + fast-lane + sync orchestration over a `Transport` and a `Storage` interface, no Node-specific imports. `mailx-imap` and `mailx-store-web` become thin shims that wire engine-specific Storage + Transport. `{persistent: true\|false}` flag on ImapManager covers the lifetime split (no fast-lane queue when ephemeral). Pre-req for Android non-Gmail IMAP without forking sync code. |
|
|
21
21
|
| **7** | **C156 — Android first-boot/setup progress narration** [M] | M | New-device install looked frozen (Bob 2026-07-22): no indication of "Signing into <gmail>…", "Fetching settings from Google Drive…", "Syncing INBOX (120/2000)…". Surface the android-bootstrap stage breadcrumbs (already vlog'd since v1.2.167) in the startup status area / folder-tree loading slot. |
|
|
22
22
|
| **8** | **C157 — Android fresh install: paint folder list before message sync** [S/M] | S/M | First sync ran minutes with an empty tree. Prioritize per-account folder-LIST fetch + paint ahead of message sync so the skeleton appears in seconds; message counts stream in behind. |
|
|
23
|
+
| **10** | **C159 — Harper local grammar check** [M] | M | **Desktop SHIPPED v1.2.168** (2026-07-22): daemon-side Harper engine + `grammarLint` IPC, generic squiggle overlay + suggestion popup across ALL THREE editors, Settings toggle default ON, quoted chains + spelling lints skipped. **Remaining: Android** (host LocalLinter in android-bootstrap, harper.js dist in APK assets like sql.js, ~+18 MB) + per-rule config + userdict merge. Details: `docs/harper-integration.md`. |
|
|
23
24
|
| **9** | **C158 — Android double-init after fold-triggered reload** [M] | M | 2026-07-22 13:07:49 logit trail: ONE page reload after unfolding produced TWO module loads, duplicate "bridge installed", duplicate GDrive lookups, and THREE "Starting OAuth flow" launches. Activity did NOT recreate (ConfigChanges already declared; no OnCreate in trail) — find what reloads the WebView on fold and make android-bootstrap init idempotent (single-flight guard on the module-level init, dedupe OAuth intent launches). |
|
|
24
25
|
| **5** | **C124 — mailto handler on macOS** (Linux ✅ 2026-07-08 v1.2.115) | S | Linux half shipped: `--register-mailto` on linux writes `~/.local/share/applications/rmfmail.desktop` (`MimeType=x-scheme-handler/mailto;`, quoted node+mailx.js Exec, bare `%u`), runs `xdg-mime default` + `update-desktop-database`; `--unregister-mailto` removes it. **Remaining: macOS** — real `.app` bundle (LaunchServices won't register a bare script) with `Info.plist` `CFBundleURLTypes` declaring `mailto` + a tiny launcher binary; `LSSetDefaultHandlerForURLScheme` programmatically sets the default. Rust `rmfmailto-src/` crate already portable — drop the Win32 imports and `cargo build --target x86_64-apple-darwin` produces the macOS launcher. Needs a Mac to build/verify. |
|
|
25
26
|
| ~~7~~ | ~~**C154 — Audit Android bridge vs MailxApi contract**~~ — **DONE** (2026-07-08, v1.2.115). Bridge now has a generic contract-backstop: every service method not explicitly adapted gets a positional pass-through, so a missing method can never again fail as `parent bridge has no method "X"`. Wire-shape mismatches adapted explicitly (`readJsoncFile`/`writeJsoncFile`/`formatJsonc`/`readConfigHelp` → `{content}`/`{ok}`, `drainStoreSync`/`syncFolderNow` → `{ok}`). Contract gained the missing entries (`getMessageSource`, `copyMessages`, `syncFolderNow`, `cancelServerSearch`, `getReminderSound`, `getCalendars`, optional `popoutWindow`) with web-service stubs per the policy (reads → graceful default, writes/OS → notImpl). Bonus fixes: bridge `getMessages` was dropping sort/sortDir/search and `searchMessages` was dropping scope/accountId/folderId — Android sort toggles and scoped search silently didn't work. | S | |
|
package/client/app.bundle.js
CHANGED
|
@@ -72,6 +72,7 @@ __export(api_client_exports, {
|
|
|
72
72
|
getUnifiedInbox: () => getUnifiedInbox,
|
|
73
73
|
getUserDict: () => getUserDict,
|
|
74
74
|
getVersion: () => getVersion,
|
|
75
|
+
grammarLint: () => grammarLint,
|
|
75
76
|
hasBccHistoryTo: () => hasBccHistoryTo,
|
|
76
77
|
hasCcHistoryTo: () => hasCcHistoryTo,
|
|
77
78
|
installConsoleCapture: () => installConsoleCapture,
|
|
@@ -632,6 +633,12 @@ async function openAttachment(accountId, uid, attachmentId, folderId, filename)
|
|
|
632
633
|
async function getMessageSource(accountId, uid, folderId) {
|
|
633
634
|
return ipc().getMessageSource(accountId, uid, folderId);
|
|
634
635
|
}
|
|
636
|
+
async function grammarLint(blocks) {
|
|
637
|
+
const fn = ipc().grammarLint;
|
|
638
|
+
if (!fn)
|
|
639
|
+
throw new Error("no grammarLint bridge");
|
|
640
|
+
return fn(blocks);
|
|
641
|
+
}
|
|
635
642
|
async function registerMailto() {
|
|
636
643
|
const fn = ipc().registerMailto;
|
|
637
644
|
if (!fn)
|
|
@@ -11873,6 +11880,15 @@ getSettings().then((s) => {
|
|
|
11873
11880
|
const px = Number(s.ui?.composeFontSize);
|
|
11874
11881
|
fontEl.value = String(Number.isFinite(px) && px >= 8 && px <= 32 ? px : 15);
|
|
11875
11882
|
}
|
|
11883
|
+
const gcEl = document.getElementById("opt-grammar-check");
|
|
11884
|
+
if (gcEl) {
|
|
11885
|
+
const on = s.ui?.grammarCheck !== false;
|
|
11886
|
+
gcEl.checked = on;
|
|
11887
|
+
try {
|
|
11888
|
+
localStorage.setItem("mailx-grammar-check", on ? "1" : "0");
|
|
11889
|
+
} catch {
|
|
11890
|
+
}
|
|
11891
|
+
}
|
|
11876
11892
|
}).catch(() => {
|
|
11877
11893
|
});
|
|
11878
11894
|
document.getElementById("opt-compose-window")?.addEventListener("change", (e) => {
|
|
@@ -11887,6 +11903,18 @@ document.getElementById("opt-compose-window")?.addEventListener("change", (e) =>
|
|
|
11887
11903
|
}).catch(() => {
|
|
11888
11904
|
});
|
|
11889
11905
|
});
|
|
11906
|
+
document.getElementById("opt-grammar-check")?.addEventListener("change", (e) => {
|
|
11907
|
+
const on = e.target.checked;
|
|
11908
|
+
try {
|
|
11909
|
+
localStorage.setItem("mailx-grammar-check", on ? "1" : "0");
|
|
11910
|
+
} catch {
|
|
11911
|
+
}
|
|
11912
|
+
getSettings().then((settings) => {
|
|
11913
|
+
settings.ui = { ...settings.ui, grammarCheck: on };
|
|
11914
|
+
saveSettings(settings);
|
|
11915
|
+
}).catch(() => {
|
|
11916
|
+
});
|
|
11917
|
+
});
|
|
11890
11918
|
document.getElementById("opt-compose-font-size")?.addEventListener("change", (e) => {
|
|
11891
11919
|
const el = e.target;
|
|
11892
11920
|
const px = Number(el.value);
|