@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.
- package/TODO.md +3 -0
- package/bin/mailx.js +39 -0
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +31 -0
- package/client/components/alarms.js +0 -3
- package/client/components/alarms.js.map +1 -1
- package/client/components/alarms.ts +0 -3
- package/client/components/message-viewer.js +52 -1
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +54 -1
- package/client/styles/components.css +6 -0
- package/docs/npmglobalize-disttag.md +90 -0
- package/docs/prod-android.md +102 -0
- package/docs/prod-wrapper.md.merged +215 -0
- package/docs/prod.md +224 -0
- package/package.json +1 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +16 -23
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +16 -22
- package/packages/mailx-store-web/android-bootstrap.d.ts.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.js +16 -1
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +15 -1
- package/client/android.html.deleted +0 -226
|
@@ -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 +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
|
|
425
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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.
|