@bobfrankston/rmfmail 1.2.179 → 1.2.181
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/TODO.md +1 -0
- package/bin/mailx.js +43 -0
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +36 -0
- package/client/android-bootstrap.bundle.js +2 -0
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +4 -0
- package/client/app.bundle.js.map +2 -2
- package/client/compose/compose.bundle.js +74 -0
- package/client/compose/compose.bundle.js.map +3 -3
- package/client/compose/compose.js +93 -0
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +89 -0
- package/client/lib/api-client.js +6 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +7 -0
- package/client/lib/mailxapi.js +5 -0
- package/package.json +5 -5
- package/packages/mailx-imap/index.d.ts +10 -0
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +18 -0
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +17 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +9 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +19 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +17 -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-store-web/android-bootstrap.js +2 -0
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +2 -0
- package/packages/mailx-store-web/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-48352 → node_modules.npmglobalize-stash-51732}/.package-lock.json +0 -0
package/TODO.md
CHANGED
|
@@ -23,6 +23,7 @@ These items don't need user input — source-only changes, compile-verified befo
|
|
|
23
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`. |
|
|
24
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). |
|
|
25
25
|
| **11** | **C160 — Attachment delete: Gmail + Android halves** [M] | M | Desktop IMAP shipped v1.2.173 (right-click chip → Delete one/all: verified local strip + append-confirm-then-delete server replace, .pre-strip.bak backup, UID rebind). Remaining: Gmail REST path (messages.insert + trash of original — changes message id, provider_id rebind) and Android (bridge method + web-service strip using its own parser). Strip helper lives in mailx-service (enumerateMimeLeafParts) — move to mailx-types when Android needs it. |
|
|
26
|
+
| **12** | **C161 — `_rmfmail` IMAP folder for cross-machine state sync** [M] | M | Bob 2026-07-27: use a hidden `_rmfmail` folder on the mail server itself as a per-account sync channel for state that today rides on Google Drive or nowhere — reminder dismissals, per-machine prefs, read-position, contact edits for non-Google accounts. Advantages over Drive files: works for every IMAP account (no Google dependency), naturally per-account, versioned by APPEND, and reuses the existing connection/sync machinery. Shape: one message per state document with a stable `X-Rmfmail-State: <name>` header, save = delete-and-reappend (the draft-dedup pattern), merge semantics per document type (reminders already have per-key max merge in mailx-types). Design Qs: folder visibility (subscribe or not, hide from folder tree), conflict handling when two machines append concurrently, and whether reminders.jsonc migrates or dual-writes. First shipped consumer of the pattern: draft freshness probe (v1.2.180) already proves the search-by-header primitive. |
|
|
26
27
|
| **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. |
|
|
27
28
|
| ~~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 | |
|
|
28
29
|
~~done — C120 read transport diagnostics~~ shipped v1.0.583 (per-folder timeout error now includes `[conn#X r=YB w=ZB writes=N sinceLastRead=Tms]` snapshot for the doomed socket).
|
package/bin/mailx.js
CHANGED
|
@@ -328,6 +328,26 @@ function registerMailtoWindows(unregister) {
|
|
|
328
328
|
lines.push("app on this PC\" to reach rmfmail.");
|
|
329
329
|
return { ok: failed === 0, message: lines.join("\n") };
|
|
330
330
|
}
|
|
331
|
+
/** Cheap probe: is the mailto registration already in place AND pointing at
|
|
332
|
+
* an up-to-date per-app launcher? Lets daemon startup skip the full
|
|
333
|
+
* ~15-reg.exe-spawn registration pass on every boot. Stale cases that
|
|
334
|
+
* return false: never registered, launcher missing, or the npm package
|
|
335
|
+
* ships a newer rmfmailto.exe than the per-app copy (post-update). */
|
|
336
|
+
function mailtoRegistrationCurrent() {
|
|
337
|
+
try {
|
|
338
|
+
const perApp = path.join(process.env.LOCALAPPDATA || "", "rmfmail", "bin", "rmfmailto.exe");
|
|
339
|
+
if (!fs.existsSync(perApp))
|
|
340
|
+
return false;
|
|
341
|
+
const pkgExe = path.join(import.meta.dirname, "rmfmailto.exe");
|
|
342
|
+
if (fs.existsSync(pkgExe) && fs.statSync(pkgExe).mtimeMs > fs.statSync(perApp).mtimeMs)
|
|
343
|
+
return false;
|
|
344
|
+
const out = execSync(`reg query "HKCU\\Software\\Classes\\rmfmail\\shell\\open\\command" /ve`, { stdio: ["pipe", "pipe", "pipe"] }).toString();
|
|
345
|
+
return out.toLowerCase().includes(perApp.toLowerCase());
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
331
351
|
if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
|
|
332
352
|
const unregister = hasFlag("unregister-mailto");
|
|
333
353
|
// C124: Linux registration — a .desktop entry claiming the mailto:
|
|
@@ -2149,6 +2169,29 @@ RFC 5322 with CRLF line endings. Bodies are quoted-printable encoded (readable i
|
|
|
2149
2169
|
// Linux/mac users still go through the CLI (xdg / TODO C124).
|
|
2150
2170
|
if (process.platform === "win32") {
|
|
2151
2171
|
svc.setMailtoRegisterFn(async () => registerMailtoWindows(false));
|
|
2172
|
+
// Auto-register at daemon startup (Bob 2026-07-27: "that should be
|
|
2173
|
+
// automatic"). Install-time is NOT a reliable hook — npm's
|
|
2174
|
+
// allowScripts policy skips this package's install scripts, so a
|
|
2175
|
+
// postinstall registration would silently never run. Startup runs on
|
|
2176
|
+
// every machine that actually launches the app, self-heals after
|
|
2177
|
+
// updates (probe notices a newer packaged rmfmailto.exe), and the
|
|
2178
|
+
// probe keeps already-registered boots to one reg.exe query.
|
|
2179
|
+
// Deferred 5s so the registration pass never sits in the boot path.
|
|
2180
|
+
// Registers rmfmail as an AVAILABLE mailto handler; Windows 11 still
|
|
2181
|
+
// requires the one-time Default-apps pick (UserChoice hash — C46).
|
|
2182
|
+
setTimeout(() => {
|
|
2183
|
+
try {
|
|
2184
|
+
if (mailtoRegistrationCurrent())
|
|
2185
|
+
return;
|
|
2186
|
+
const r = registerMailtoWindows(false);
|
|
2187
|
+
console.log(` [mailto] startup auto-registration ${r.ok ? "completed" : "FAILED"}`);
|
|
2188
|
+
if (!r.ok)
|
|
2189
|
+
console.log(r.message);
|
|
2190
|
+
}
|
|
2191
|
+
catch (e) {
|
|
2192
|
+
console.error(` [mailto] startup auto-registration failed: ${e?.message || e}`);
|
|
2193
|
+
}
|
|
2194
|
+
}, 5000);
|
|
2152
2195
|
}
|
|
2153
2196
|
svc.setPopupFn(async (opts) => {
|
|
2154
2197
|
// Own WebView2 profile so a reminder popup can never share (and
|