@bobfrankston/rmfmail 1.2.167 → 1.2.168

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.
Files changed (41) hide show
  1. package/TODO.md +1 -0
  2. package/client/app.bundle.js +28 -0
  3. package/client/app.bundle.js.map +2 -2
  4. package/client/app.js +23 -0
  5. package/client/app.js.map +1 -1
  6. package/client/app.ts +18 -0
  7. package/client/compose/compose.bundle.js +292 -0
  8. package/client/compose/compose.bundle.js.map +4 -4
  9. package/client/compose/compose.js +23 -0
  10. package/client/compose/compose.js.map +1 -1
  11. package/client/compose/compose.ts +20 -0
  12. package/client/compose/harper-lint.js +269 -0
  13. package/client/compose/harper-lint.js.map +1 -0
  14. package/client/compose/harper-lint.ts +265 -0
  15. package/client/index.html +1 -0
  16. package/client/lib/api-client.js +8 -0
  17. package/client/lib/api-client.js.map +1 -1
  18. package/client/lib/api-client.ts +8 -0
  19. package/client/lib/mailxapi.js +6 -0
  20. package/docs/harper-integration.md +120 -0
  21. package/package.json +6 -3
  22. package/packages/mailx-imap/package-lock.json +2 -2
  23. package/packages/mailx-imap/package.json +1 -1
  24. package/packages/mailx-service/index.d.ts +11 -0
  25. package/packages/mailx-service/index.d.ts.map +1 -1
  26. package/packages/mailx-service/index.js +56 -0
  27. package/packages/mailx-service/index.js.map +1 -1
  28. package/packages/mailx-service/index.ts +54 -0
  29. package/packages/mailx-service/jsonrpc.js +2 -0
  30. package/packages/mailx-service/jsonrpc.js.map +1 -1
  31. package/packages/mailx-service/jsonrpc.ts +2 -0
  32. package/packages/mailx-service/package.json +1 -1
  33. package/packages/mailx-settings/docs/harper-integration.md +120 -0
  34. package/packages/mailx-settings/package.json +1 -1
  35. package/packages/mailx-store/package.json +1 -1
  36. package/packages/mailx-store-web/package.json +1 -1
  37. package/packages/mailx-types/mailx-api.d.ts +12 -0
  38. package/packages/mailx-types/mailx-api.d.ts.map +1 -1
  39. package/packages/mailx-types/mailx-api.ts +4 -0
  40. package/packages/mailx-types/package.json +1 -1
  41. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-28172 → node_modules.npmglobalize-stash-72420}/.package-lock.json +0 -0
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 | |
@@ -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);