@bobfrankston/rmfmail 1.0.628 → 1.0.634

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.
@@ -0,0 +1,102 @@
1
+ # prod / dev release workflow — Android (MAUI APK)
2
+
3
+ Status: design only. Mirror of `prod.md` (npm side); same intent, different mechanism because Android isn't on npm.
4
+
5
+ ## Where the desktop pattern doesn't transfer
6
+
7
+ npm has built-in dist-tags: a single package, multiple movable pointers. Android side-loads have nothing equivalent — an APK is a file at a URL, picked up by the in-app updater. To get the same prod-vs-dev shape we have to build it.
8
+
9
+ Today (current state):
10
+
11
+ ```
12
+ https://rmf39.aaz.lt/mailx/mailx-maui.apk ← single APK
13
+ https://rmf39.aaz.lt/mailx/versions.json ← version manifest
14
+ ```
15
+
16
+ `AppUpdater` (in `MailxApp/Services/`) polls `versions.json`, compares to running `ApplicationVersion`, and prompts a download if newer. There's no channel concept — every install gets every build.
17
+
18
+ ## Goal
19
+
20
+ Same as desktop: `rebuild` publishes builds freely; promotion to "users get this" is a separate step. On Android the unit isn't a tag pointer, it's the APK file the updater downloads.
21
+
22
+ ## Mechanism
23
+
24
+ **Two URL prefixes** (or one prefix with channel paths). Manifest carries which build is current per channel. APK files are versioned filenames, never overwritten.
25
+
26
+ ```
27
+ https://rmf39.aaz.lt/mailx/dev/manifest.json
28
+ https://rmf39.aaz.lt/mailx/dev/mailx-maui-1.0.NNN.apk
29
+ https://rmf39.aaz.lt/mailx/prod/manifest.json
30
+ https://rmf39.aaz.lt/mailx/prod/mailx-maui-1.0.MMM.apk
31
+ ```
32
+
33
+ `manifest.json` shape:
34
+
35
+ ```json
36
+ { "version": "1.0.NNN", "apk": "mailx-maui-1.0.NNN.apk", "released": "2026-05-09T17:00:00Z", "minDesktop": "1.0.500" }
37
+ ```
38
+
39
+ The "promotion" step writes a new `prod/manifest.json` pointing at an existing dev APK file. The dev APK doesn't move or recompile — same bytes, just referenced under prod's manifest.
40
+
41
+ ## Required pieces
42
+
43
+ ### 1. `build-apk.cmd` / `build-apk.ts` — build + upload to dev channel
44
+
45
+ Currently builds and copies to `download/apks/mailx-maui.apk` (single name, overwrites every time). Change to:
46
+
47
+ - Read version from `package.json` (already does).
48
+ - Build APK, copy to `download/apks/mailx-maui-<version>.apk` (versioned filename, never overwritten).
49
+ - Update local `download/dev/manifest.json` to point at the new APK.
50
+ - Sync `download/dev/` to the rmf39.aaz.lt webroot.
51
+
52
+ The dev channel always tracks the most recent build.
53
+
54
+ ### 2. `prod-android.cmd` — promote dev → prod
55
+
56
+ Mirror of `prod.cmd`. Reads `download/dev/manifest.json`, copies it to `download/prod/manifest.json`, syncs prod/ to webroot. No new APK file uploaded — the prod-channel manifest now points at the same APK that's already in `dev/` (or copy it under `prod/` for symmetry; cheap).
57
+
58
+ ### 3. AppUpdater — channel awareness
59
+
60
+ `AppUpdater` currently reads `https://rmf39.aaz.lt/mailx/versions.json`. Change to read `<base>/<channel>/manifest.json`. Channel default is `prod`; users on the dev channel set a flag (manual install, or a Settings toggle, or a build-time constant in a separate `MailxAppDev` package).
61
+
62
+ Two ways to put a user on the dev channel:
63
+
64
+ - **Flavor build**: build a separate APK (`MailxApp.Dev`) where `AppUpdater._channel = "dev"`. Different package id (`com.frankston.mailx.dev`), different AUMID, side-by-side install. This is the desktop `RMFMAIL_PROFILE` analog — full coexistence.
65
+ - **Settings toggle**: single APK, channel stored in app settings, defaults to prod. User flips a switch, next updater poll hits the dev manifest. Same APK, just different update source.
66
+
67
+ Settings toggle is simpler for a one-user dev/prod workflow; flavor build is necessary if you want both versions installed at once on the same phone (different package ids).
68
+
69
+ ### 4. APK version semantics
70
+
71
+ Android's `ApplicationVersion` is a monotonically-increasing integer. Promoting a dev APK to prod does NOT bump the integer — it's the same APK. The manifest's "version" field stays in sync with the APK's actual `ApplicationDisplayVersion`. Rolling back is just rewriting the manifest to point at an older APK.
72
+
73
+ ## Workflow once wired
74
+
75
+ 1. `build-apk.cmd` — builds, uploads to `dev/`, updater on dev-channel devices picks it up.
76
+ 2. Daily testing on the dev phone/tablet.
77
+ 3. `prod-android.cmd` — copies the current dev manifest to prod. Devices on prod-channel pick up the new build on next poll.
78
+ 4. Rolling back prod: re-run `prod-android.cmd <specific-version>` (need a version arg to override "current dev").
79
+
80
+ ## Notes / open questions
81
+
82
+ - **Coexistence on a single device** — only possible with flavor build (different package id). Settings toggle is single-install. Pick based on how often you need both at once.
83
+ - **Force-update / minimum-version** — manifest already supports a `minDesktop` field; an Android equivalent (`minSupported`: refuse to run older client) can refuse to run a stale APK after a breaking server change. Not needed today; cheap to add later.
84
+ - **APK signing** — same key for dev and prod, otherwise users can't upgrade between them without uninstall. (Different package id flavor build IS a separate app and can have a separate key — but that's the coexistence model anyway.)
85
+ - **`download/apks/mailx-maui.apk` (current single filename)** — keep as-is for back-compat until devices move off it; or symlink it to the current prod APK.
86
+
87
+ ## Effort estimate
88
+
89
+ - `build-apk.ts` — read version, versioned filename, manifest write, sync. ~30 lines.
90
+ - `prod-android.cmd` — manifest copy + sync. ~10 lines.
91
+ - `AppUpdater.cs` channel awareness + Settings toggle UI — ~50 lines including the storage pref.
92
+ - Webroot layout setup on rmf39.aaz.lt — one-time directory creation.
93
+ - Test cycle: build dev, verify prod APK on phone unchanged. Promote, verify next poll picks up new prod APK.
94
+
95
+ Maybe 2 hours wall-clock total. The hardest part is the Settings toggle, not the channel logic.
96
+
97
+ ## Order
98
+
99
+ 1. `prod.md` (desktop) ships first — proves the dist-tag flow and gives you the workflow you'd want here.
100
+ 2. Android channels: `build-apk.ts` rewrite → AppUpdater channel param → Settings toggle (or flavor build) → `prod-android.cmd`.
101
+
102
+ No urgency until desktop side is settled and you actually want both flavors in use on the phone.
@@ -0,0 +1,215 @@
1
+ # prod / dev release workflow — wrapper-package variant
2
+
3
+ Status: design only. Alternative to `prod.md` (dist-tag approach). Pick one.
4
+
5
+ ## Shape
6
+
7
+ Today: one package `@bobfrankston/rmfmail` ships everything.
8
+
9
+ Proposed: split into two packages, three install names.
10
+
11
+ | Name | Role | Versioning |
12
+ |---|---|---|
13
+ | `@bobfrankston/rmfmailapp` | The actual code (today's rmfmail content). | Bumps freely on every build. |
14
+ | `@bobfrankston/rmfmail` | Thin wrapper. `dependencies: { rmfmailapp: "1.0.NNN" }` pinned. | Bumps only on promotion. |
15
+ | `@bobfrankston/rmfmaildev` | Thin wrapper. `dependencies: { rmfmailapp: "*" }` (or repinned at every publish to current `@latest`). | Tracks rmfmailapp tip. |
16
+
17
+ Casual user: `npm install -g @bobfrankston/rmfmail` — pulls the wrapper, npm resolves the pinned rmfmailapp, installs both. The wrapper's `bin` shim invokes rmfmailapp's actual entry point.
18
+
19
+ Dev user: `npm install -g @bobfrankston/rmfmaildev` — wrapper that pulls `rmfmailapp@latest` (or its current `*`-resolved match).
20
+
21
+ Promotion = single git commit on the wrapper repo bumping its `dependencies.rmfmailapp` from one frozen version to a newer frozen version, plus `npm publish` of the wrapper.
22
+
23
+ ## Why this rather than dist-tags
24
+
25
+ - **Audit trail in git.** The history of "what version was current prod when" is `git log app/wrapper/package.json`, not registry-only state.
26
+ - **Promotion is reversible by `git revert`.** Same as any code change.
27
+ - **Multi-channel scales.** `rmfmail-beta`, `rmfmail-rc`, etc. are just more wrappers, each pinned independently. dist-tags work too but become a bigger pile.
28
+ - **Pre-flight gating possible.** A CI check on the wrapper's package.json (lint, smoke test) can refuse promotions that name a version that hasn't been validated.
29
+
30
+ ## Why NOT, vs dist-tags
31
+
32
+ - **Two packages to maintain** instead of one. Two `package.json`s, two `npm publish` calls per promotion.
33
+ - **One more rename.** Current `@bobfrankston/rmfmail` → `@bobfrankston/rmfmailapp` (every workspace dep that references it has to flip too — not many in mailx, but it's a non-trivial rename).
34
+ - **npm cache pressure.** Each version of rmfmailapp lingers in users' npm caches; the wrapper resolves at install time, so old transitive resolutions can sit around. dist-tags don't multiply package versions.
35
+
36
+ ## Layout
37
+
38
+ ```
39
+ mailx/
40
+ rmfmailapp/ # was app/, the actual code
41
+ package.json → "name": "@bobfrankston/rmfmailapp"
42
+ bin/mailx.ts → unchanged
43
+ packages/ → unchanged
44
+ client/ → unchanged
45
+ ...
46
+
47
+ rmfmail/ # NEW — wrapper for prod
48
+ package.json → see below
49
+ bin/rmfmail.js → 3-line shim
50
+
51
+ rmfmaildev/ # NEW — wrapper for dev
52
+ package.json → see below
53
+ bin/rmfmaildev.js → 3-line shim
54
+ ```
55
+
56
+ ### `rmfmail/package.json` (prod wrapper)
57
+
58
+ ```json
59
+ {
60
+ "name": "@bobfrankston/rmfmail",
61
+ "version": "1.0.0",
62
+ "description": "Local-first email client (current stable)",
63
+ "type": "module",
64
+ "bin": { "rmfmail": "bin/rmfmail.js" },
65
+ "dependencies": {
66
+ "@bobfrankston/rmfmailapp": "1.0.609"
67
+ },
68
+ "license": "MIT"
69
+ }
70
+ ```
71
+
72
+ Wrapper's own version (`1.0.0`) only bumps on shape changes (e.g., bin renamed, scope changed). Day-to-day promotions just re-pin the dependency line.
73
+
74
+ ### `rmfmail/bin/rmfmail.js` (shim)
75
+
76
+ ```js
77
+ #!/usr/bin/env node
78
+ // Wrapper bin — defer to the pinned rmfmailapp entry point. Keeps argv
79
+ // and exit code identical so the wrapper is invisible at the CLI.
80
+ import { fileURLToPath } from "node:url";
81
+ import { createRequire } from "node:module";
82
+ const require = createRequire(import.meta.url);
83
+ const appBin = require.resolve("@bobfrankston/rmfmailapp/bin/mailx.js");
84
+ await import(`file://${appBin}`);
85
+ ```
86
+
87
+ (Or even just `require("@bobfrankston/rmfmailapp/bin/mailx.js")` if the rmfmailapp bin runs on `import`.)
88
+
89
+ ### `rmfmaildev/package.json` (dev wrapper)
90
+
91
+ ```json
92
+ {
93
+ "name": "@bobfrankston/rmfmaildev",
94
+ "version": "1.0.0",
95
+ "description": "Local-first email client (development tip)",
96
+ "type": "module",
97
+ "bin": { "rmfmail": "bin/rmfmaildev.js" },
98
+ "dependencies": {
99
+ "@bobfrankston/rmfmailapp": "*"
100
+ },
101
+ "license": "MIT"
102
+ }
103
+ ```
104
+
105
+ `*` means "any version" — npm picks the latest published. New `npm install -g @bobfrankston/rmfmaildev` always installs whatever rmfmailapp tip is at install time. Existing dev users run `npm update -g @bobfrankston/rmfmaildev` to refresh.
106
+
107
+ Alternative: `rmfmaildev` re-pins on every rmfmailapp publish (`prepublish` hook in rmfmailapp's CI bumps rmfmaildev's pin and publishes). Adds steps but gives dev installs the same lockstep behavior as prod.
108
+
109
+ ### Workflow
110
+
111
+ **rebuild.cmd** (publishes rmfmailapp):
112
+ ```cmd
113
+ cd rmfmailapp
114
+ npmglobalize
115
+ ```
116
+
117
+ No tag flag needed (rmfmailapp's `@latest` is just "newest dev build"; rmfmail prod doesn't read from it directly).
118
+
119
+ **prod.cmd** (promote):
120
+ ```cmd
121
+ @echo off
122
+ setlocal
123
+ set TARGET=%1
124
+ if "%TARGET%"=="" (
125
+ for /f "tokens=2 delims=:," %%v in ('findstr /b " \"version\":" "%~dp0rmfmailapp\package.json"') do set TARGET=%%~v
126
+ set TARGET=%TARGET: =%
127
+ set TARGET=%TARGET:"=%
128
+ )
129
+ echo Promoting rmfmail wrapper to pin rmfmailapp@%TARGET%...
130
+
131
+ rem Edit rmfmail/package.json's dependency line. 5-line node one-liner:
132
+ node -e "const p=require('./rmfmail/package.json'); p.dependencies['@bobfrankston/rmfmailapp']='%TARGET%'; require('fs').writeFileSync('./rmfmail/package.json', JSON.stringify(p,null,2)+'\n');"
133
+
134
+ rem Bump wrapper patch version (so npm sees a new wrapper to install).
135
+ cd rmfmail && npm version patch && cd ..
136
+ git add rmfmail/package.json
137
+ git commit -m "rmfmail: pin rmfmailapp@%TARGET%"
138
+
139
+ cd rmfmail
140
+ npm publish --access public
141
+ cd ..
142
+ echo Done. Casual users running 'npm install -g @bobfrankston/rmfmail' now get rmfmail@x.y.z → rmfmailapp@%TARGET%.
143
+ endlocal
144
+ ```
145
+
146
+ **Casual install** (unchanged from today's user-facing command):
147
+ ```
148
+ npm install -g @bobfrankston/rmfmail
149
+ ```
150
+
151
+ **Dev install**:
152
+ ```
153
+ npm install -g @bobfrankston/rmfmaildev
154
+ ```
155
+
156
+ ## Required code changes
157
+
158
+ ### 1. Rename `@bobfrankston/rmfmail` → `@bobfrankston/rmfmailapp`
159
+
160
+ - `app/package.json` `"name"` field.
161
+ - Every `dependencies` reference in workspace `packages/*/package.json`. Today they use `file:` paths so this might already be transparent — check.
162
+ - `bin/postinstall.js` — any hard-coded package name strings.
163
+ - `npmglobalize` config — no changes if it reads from package.json.
164
+
165
+ The rename is a one-time event. After it lands, no package.json edits in normal day-to-day work.
166
+
167
+ ### 2. Create `rmfmail/` and `rmfmaildev/` directories
168
+
169
+ Top-level (not under `app/`). Each gets a 5-line `package.json` and a 3-line bin shim. ~30 lines total.
170
+
171
+ ### 3. CI / build wiring
172
+
173
+ Today's `rebuild.cmd` builds and publishes app. Add:
174
+ - `prod.cmd` — promotes by bumping rmfmail's pin.
175
+ - Optionally automate rmfmaildev re-pin on every app publish (postpublish hook).
176
+
177
+ ### 4. npmglobalize: no changes needed
178
+
179
+ The wrapper packages publish like any other. dist-tag flag work in `prod.md` is **not required** for this approach.
180
+
181
+ ## What this does NOT do
182
+
183
+ - Does not enable side-by-side coexistence on a single machine — same as dist-tag plan, that's the orthogonal `RMFMAIL_PROFILE` env-var design.
184
+ - Does not eliminate user upgrades — users still need to re-run `npm install -g` (or rely on mailx's in-app updater) to pick up a new prod pin.
185
+ - Does not split testing or CI per channel — same code, same tests; only the promotion step gates the user-facing pin.
186
+
187
+ ## Comparison to `prod.md`
188
+
189
+ | | `prod.md` (dist-tag) | `prod-wrapper.md` (this) |
190
+ |--|--|--|
191
+ | Number of npm packages | 1 (rmfmail) | 3 (rmfmailapp + rmfmail + rmfmaildev) |
192
+ | What "promotion" is | `npm dist-tag add` (registry call) | git commit + `npm publish` of wrapper |
193
+ | Promotion auditable in git | no | yes |
194
+ | Roll-back mechanism | retag earlier version | `git revert` then republish wrapper |
195
+ | Required npmglobalize change | yes (`--tag` flag) | no |
196
+ | Casual install command | `npm install -g @bobfrankston/rmfmail` | (same) |
197
+ | Dev install command | `... rmfmail@dev` | `... rmfmaildev` |
198
+ | One-time rename of code package | no | yes (rmfmail → rmfmailapp) |
199
+ | Multi-channel future (beta, rc, …) | more dist-tags | more wrappers |
200
+
201
+ ## Recommendation
202
+
203
+ If you want:
204
+ - **Minimum mechanical change**: dist-tag (`prod.md`).
205
+ - **Maximum traceability**: wrapper (`prod-wrapper.md`).
206
+ - **Both eventually**: nothing stops doing dist-tag now and migrating to wrapper later. The dist-tag is a cheap throwaway; the wrapper is a structural commitment.
207
+
208
+ ## Effort estimate
209
+
210
+ - One-time rename `rmfmail` → `rmfmailapp`: ~30 minutes (search-replace + verify, plus npm deprecate of old name to point users at new install path).
211
+ - `rmfmail/` + `rmfmaildev/` skeletons: ~15 minutes.
212
+ - `prod.cmd`: ~15 minutes.
213
+ - Test cycle: build app, publish, run prod.cmd, install in clean dir, verify it runs. ~30 minutes.
214
+
215
+ About 1.5 hours wall-clock. Bigger one-time investment than dist-tag (~15 minutes); smaller per-promotion friction (one git commit vs `npm dist-tag add ... prod && add ... latest`).
package/docs/prod.md ADDED
@@ -0,0 +1,224 @@
1
+ # prod / dev release workflow
2
+
3
+ Status: design. Two viable approaches; pick one. Both deliver the same shape:
4
+
5
+ - `rebuild.cmd` publishes builds without affecting what casual users get.
6
+ - A separate `prod.cmd` step promotes a known-good build to be what casual users install.
7
+ - Casual users keep typing `npm install -g @bobfrankston/rmfmail` (no flags).
8
+ - Dev users explicitly opt in.
9
+
10
+ ## Key invariant (answers the obvious confusion)
11
+
12
+ `@latest` is **what casual `npm install` gets**. It only moves when prod.cmd promotes. So between promotions:
13
+
14
+ ```
15
+ @latest = @prod = 1.0.609 ← last promoted, what users get
16
+ @dev = 1.0.620 ← every rebuild bumps this
17
+ ```
18
+
19
+ Casual users keep installing 1.0.609 until you say so. Dev tip never accidentally becomes the casual install.
20
+
21
+ ---
22
+
23
+ ## Approach A — npm dist-tags (one package)
24
+
25
+ ### Mechanics
26
+
27
+ npm's built-in [dist-tag](https://docs.npmjs.com/cli/v10/commands/npm-dist-tag) feature: one package, multiple movable pointers.
28
+
29
+ - `npm publish --tag dev` sets `@dev` to the new version. `@latest` untouched.
30
+ - `npm dist-tag add @bobfrankston/rmfmail@<v> prod` moves the `prod` pointer; `npm dist-tag add ... latest` moves `latest` too. Two HTTP calls, no republish.
31
+
32
+ ### Required changes
33
+
34
+ **1. npmglobalize** — accepts a `--dist-tag` flag and forwards to `npm publish`. ~5 lines. See `docs/npmglobalize-disttag.md` for the patch.
35
+
36
+ **2. rebuild.cmd** — invoke `npmglobalize --dist-tag dev`. One-line edit.
37
+
38
+ **3. prod.cmd** — new file. Explicit arg wins; otherwise query npm for the
39
+ current `@dev` and promote that. (`@dev` is the right default because you've
40
+ just published it via `rebuild.cmd` and want it to become user-facing.)
41
+
42
+ ```cmd
43
+ @echo off
44
+ setlocal
45
+ set V=%1
46
+ if "%V%"=="" (
47
+ for /f "delims=" %%v in ('npm view @bobfrankston/rmfmail dist-tags.dev') do set V=%%v
48
+ )
49
+ if "%V%"=="" (
50
+ echo No version supplied and 'npm view ... dist-tags.dev' returned empty.
51
+ echo Usage: prod.cmd [version] e.g. prod.cmd 1.0.611
52
+ exit /b 1
53
+ )
54
+ echo Promoting @bobfrankston/rmfmail@%V% to prod and latest...
55
+ call npm dist-tag add @bobfrankston/rmfmail@%V% prod
56
+ call npm dist-tag add @bobfrankston/rmfmail@%V% latest
57
+ echo Done.
58
+ endlocal
59
+ ```
60
+
61
+ Roll back to an older known-good: `prod.cmd 1.0.598` — explicit arg path.
62
+
63
+ The "default = local package.json" alternative (if you never want to query
64
+ the registry):
65
+
66
+ ```cmd
67
+ for /f "tokens=2 delims=:," %%v in ('findstr /b " \"version\":" "%~dp0app\package.json"') do set V=%%~v
68
+ set V=%V: =%
69
+ set V=%V:"=%
70
+ ```
71
+
72
+ Use whichever default matches your workflow — the explicit-arg path works
73
+ either way.
74
+
75
+ ### Workflow
76
+
77
+ 1. Edit code, run `rebuild.cmd` — version bumps, publishes as `@dev`. `@latest`/`@prod` unaffected.
78
+ 2. On the dev machine: `npm install -g @bobfrankston/rmfmail@dev` to grab the freshest build.
79
+ 3. When something feels stable: run `prod.cmd`. Promotes the current `package.json` version to `@prod` and `@latest`.
80
+ 4. On the prod machine (and any default install): `npm install -g @bobfrankston/rmfmail` (no tag) gets the newly-promoted version.
81
+
82
+ Roll back: `npm dist-tag add @bobfrankston/rmfmail@<earlier> prod` + `... latest`. No republish, no version bump.
83
+
84
+ ### Effort
85
+
86
+ - npmglobalize change: ~5 lines, ~5 minutes.
87
+ - `rebuild.cmd`: one-line edit.
88
+ - `prod.cmd`: 15 lines, fresh file.
89
+ - Test cycle: ~10 minutes.
90
+
91
+ ---
92
+
93
+ ## Approach B — wrapper packages
94
+
95
+ ### Mechanics
96
+
97
+ Split the current single package into three:
98
+
99
+ | Name | Role | Versioning |
100
+ |---|---|---|
101
+ | `@bobfrankston/rmfmailapp` | Today's actual code. | Bumps freely on every build. |
102
+ | `@bobfrankston/rmfmail` | Wrapper. `dependencies: { rmfmailapp: "1.0.609" }` pinned. | Bumps only on promotion. |
103
+ | `@bobfrankston/rmfmaildev` | Wrapper. `dependencies: { rmfmailapp: "*" }`. | Tracks rmfmailapp tip. |
104
+
105
+ Casual user: `npm install -g @bobfrankston/rmfmail` — installs the wrapper, which pulls in the pinned rmfmailapp via npm's normal dependency resolution. Wrapper's `bin` shim invokes rmfmailapp's actual entry point, so the CLI is identical.
106
+
107
+ Promotion = git commit on the wrapper bumping `dependencies.rmfmailapp` from one frozen version to another, plus `npm publish` of the wrapper.
108
+
109
+ ### Layout
110
+
111
+ ```
112
+ mailx/
113
+ rmfmailapp/ # was app/
114
+ package.json "name": "@bobfrankston/rmfmailapp"
115
+ bin/, packages/, client/ unchanged
116
+ rmfmail/ # NEW
117
+ package.json pins rmfmailapp version
118
+ bin/rmfmail.js shim that imports rmfmailapp's entry
119
+ rmfmaildev/ # NEW
120
+ package.json "*" range or always-repinned
121
+ bin/rmfmaildev.js shim
122
+ ```
123
+
124
+ ### `rmfmail/package.json`
125
+
126
+ ```json
127
+ {
128
+ "name": "@bobfrankston/rmfmail",
129
+ "version": "1.0.0",
130
+ "type": "module",
131
+ "bin": { "rmfmail": "bin/rmfmail.js" },
132
+ "dependencies": { "@bobfrankston/rmfmailapp": "1.0.609" }
133
+ }
134
+ ```
135
+
136
+ ### `rmfmail/bin/rmfmail.js`
137
+
138
+ ```js
139
+ #!/usr/bin/env node
140
+ import { createRequire } from "node:module";
141
+ const require = createRequire(import.meta.url);
142
+ await import(`file://${require.resolve("@bobfrankston/rmfmailapp/bin/mailx.js")}`);
143
+ ```
144
+
145
+ ### `rmfmaildev/package.json`
146
+
147
+ Same shape but `"@bobfrankston/rmfmailapp": "*"` so npm always resolves to the freshest published rmfmailapp.
148
+
149
+ ### Required changes
150
+
151
+ **1. Rename** `@bobfrankston/rmfmail` → `@bobfrankston/rmfmailapp` in `app/package.json` and any workspace deps that reference it. One-time.
152
+
153
+ **2. Create** `rmfmail/` and `rmfmaildev/` directories with the package.json + shim listed above. ~30 lines total.
154
+
155
+ **3. prod.cmd** — bumps the pin and publishes the wrapper:
156
+
157
+ ```cmd
158
+ @echo off
159
+ setlocal
160
+ set TARGET=%1
161
+ if "%TARGET%"=="" (
162
+ for /f "tokens=2 delims=:," %%v in ('findstr /b " \"version\":" "%~dp0rmfmailapp\package.json"') do set TARGET=%%~v
163
+ set TARGET=%TARGET: =%
164
+ set TARGET=%TARGET:"=%
165
+ )
166
+ node -e "const p=require('./rmfmail/package.json'); p.dependencies['@bobfrankston/rmfmailapp']='%TARGET%'; require('fs').writeFileSync('./rmfmail/package.json', JSON.stringify(p,null,2)+'\n');"
167
+ cd rmfmail
168
+ call npm version patch
169
+ call npm publish --access public
170
+ cd ..
171
+ git add rmfmail/package.json
172
+ git commit -m "rmfmail: pin rmfmailapp@%TARGET%"
173
+ endlocal
174
+ ```
175
+
176
+ **4. npmglobalize**: no changes required.
177
+
178
+ ### Workflow
179
+
180
+ 1. Build, run `rebuild.cmd` — publishes rmfmailapp.
181
+ 2. Dev install: `npm install -g @bobfrankston/rmfmaildev`. Pulls latest rmfmailapp through the `*` range.
182
+ 3. Promotion: `prod.cmd 1.0.611`. Edits rmfmail's pin, bumps wrapper patch version, publishes wrapper, commits.
183
+ 4. Casual install: `npm install -g @bobfrankston/rmfmail` resolves the new wrapper, npm fetches the pinned rmfmailapp, both land under the wrapper.
184
+
185
+ Roll back: edit rmfmail/package.json to a prior pin, `git revert`, republish wrapper.
186
+
187
+ ### Effort
188
+
189
+ - One-time rename: ~30 minutes.
190
+ - Wrapper skeletons: ~15 minutes.
191
+ - prod.cmd: ~15 minutes.
192
+ - Test: ~30 minutes.
193
+ - Total: ~1.5 hours up-front, then near-zero per promotion.
194
+
195
+ ---
196
+
197
+ ## Comparison
198
+
199
+ | | A: dist-tags | B: wrappers |
200
+ |--|--|--|
201
+ | Number of npm packages | 1 | 3 (app + 2 wrappers) |
202
+ | What "promotion" is | `npm dist-tag add` (HTTP call) | git commit + `npm publish` of wrapper |
203
+ | Promotion in git history | no (registry-only) | yes |
204
+ | Roll-back | retag prior version | `git revert` then republish wrapper |
205
+ | npmglobalize change needed | yes (`--tag` flag, ~5 lines) | no |
206
+ | Casual install command | `npm install -g @bobfrankston/rmfmail` | (same) |
207
+ | Dev install command | `... rmfmail@dev` | `... rmfmaildev` |
208
+ | One-time setup work | ~15 minutes | ~1.5 hours |
209
+ | Per-promotion work | seconds (registry call) | minutes (commit + publish) |
210
+ | Multi-channel future (beta, rc) | more dist-tags | more wrappers |
211
+
212
+ ## Recommendation
213
+
214
+ If you want it working today with minimum disturbance: **A (dist-tags)**.
215
+
216
+ If auditability of "what version was prod when" matters and you're willing to spend the one-time rename: **B (wrappers)**.
217
+
218
+ A → B migration later is straightforward (the rename and wrapper creation is the same work whenever you do it; dist-tags become a non-issue once wrappers exist).
219
+
220
+ ## What neither approach does
221
+
222
+ - Does not enable side-by-side coexistence on a single machine — that's the orthogonal `RMFMAIL_PROFILE` env-var design (separate config dir, AUMID, mailto handler, etc.).
223
+ - Does not change the in-app updater. mailx's existing version-check flow keeps working with either.
224
+ - Does not affect Android. APKs aren't on npm — `prod-android.md` is the parallel document with the equivalent channel-manifest design.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.0.628",
3
+ "version": "1.0.634",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -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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"}
@@ -421,38 +421,31 @@ export class MailxService {
421
421
  async unsubscribeOneClick(url) {
422
422
  if (!/^https:\/\//i.test(url))
423
423
  throw new Error("one-click unsubscribe requires an https URL");
424
- // RFC 8058 POST with List-Unsubscribe=One-Click body. A User-Agent
425
- // header appeases servers that reject anonymous clients as "malformed".
424
+ // RFC 8058: POST with body `List-Unsubscribe=One-Click`. Strict
425
+ // no GET fallback. The header `List-Unsubscribe-Post: One-Click`
426
+ // is the sender's promise that POST works; if their endpoint then
427
+ // 405s a POST, that's a sender bug, surface it. Pre-fix did a
428
+ // silent GET fallback on 4xx, which (a) doesn't actually
429
+ // unsubscribe per RFC 8058 (servers may treat GET as "view
430
+ // unsubscribe page", not "unsubscribe"), and (b) hides the real
431
+ // problem from the user. Bob 2026-05-09: "we're back to using
432
+ // get rather than post."
426
433
  const headers = {
427
434
  "Content-Type": "application/x-www-form-urlencoded",
428
435
  "User-Agent": "mailx/1.0 (https://github.com/BobFrankston/mailx)",
429
436
  };
430
- let resp = await fetch(url, {
437
+ const resp = await fetch(url, {
431
438
  method: "POST",
432
439
  headers,
433
440
  body: "List-Unsubscribe=One-Click",
434
441
  redirect: "follow",
435
442
  });
436
- // Some mailers advertise List-Unsubscribe-Post but their endpoint
437
- // actually only handles GET (older RFC 2369 style). Fall back once
438
- // on 4xx so the user doesn't have to open the URL manually.
439
- if (!resp.ok && resp.status >= 400 && resp.status < 500) {
440
- const body = await resp.text().catch(() => "");
441
- console.log(` [unsub] POST ${url} ${resp.status} ${resp.statusText}; body: ${body.slice(0, 200)}`);
442
- try {
443
- const fallback = await fetch(url, { method: "GET", headers, redirect: "follow" });
444
- if (fallback.ok) {
445
- return { ok: true, status: fallback.status, statusText: `${fallback.statusText} (via GET)` };
446
- }
447
- const fbody = await fallback.text().catch(() => "");
448
- console.log(` [unsub] GET ${url} → ${fallback.status} ${fallback.statusText}; body: ${fbody.slice(0, 200)}`);
449
- // Surface the server's own error so the UI shows the real reason.
450
- return { ok: false, status: fallback.status, statusText: (fbody.trim().split("\n")[0] || fallback.statusText).slice(0, 200) };
451
- }
452
- catch { /* fall through to POST error */ }
453
- return { ok: false, status: resp.status, statusText: (body.trim().split("\n")[0] || resp.statusText).slice(0, 200) };
454
- }
455
- return { ok: resp.ok, status: resp.status, statusText: resp.statusText };
443
+ const body = resp.ok ? "" : await resp.text().catch(() => "");
444
+ console.log(` [unsub] POST ${url} ${resp.status} ${resp.statusText}${body ? `; body: ${body.slice(0, 200)}` : ""}`);
445
+ const statusText = resp.ok
446
+ ? resp.statusText
447
+ : ((body.trim().split("\n")[0] || resp.statusText).slice(0, 200));
448
+ return { ok: resp.ok, status: resp.status, statusText };
456
449
  }
457
450
  // ── External edit in Microsoft Word ──
458
451
  /** Per-session map: editId → temp file path + watcher cleanup.