Architecture
Rewrite logic (wispr_pro.py)
response body ── contains marker key "total_trial_days"? ──no──→ pass through
│ yes
▼
parses as a JSON object? ──no──→ pass through
│ yes
▼
patch fields: status, plan, credits, is_subscribed, trial days, daysLeft
│
▼
Content-Encoding removed, Content-Length fixed, body replaced
Everything else — other hosts, endpoints, non-JSON payloads — is untouched.
Config merge chain
defaults ──> config.toml [rewrite] ──> CLI flags
- toml
days_leftmaps to the API fielddaysLeft(camelCase). load_patch()is called by the addon at request time (in-process), so config edits apply on the next response without restarting the proxy.
Plan & status enums (from the app's own enums)
- Plans:
FLOW_BASIC,FLOW_PRO_MONTHLY,FLOW_PRO_YEARLY, student/team/business variants. - Statuses:
active,trialing,canceled,none,past_due, …
Runtime model
- Foreground only.
startruns mitmproxy in-process (DumpMaster + asyncio) and blocks — no child processes. This is deliberate: a spawned child of a PyInstaller onefile binary loses its extraction directory when the parent exits (base_library.zipFileNotFoundError crash — the previous design bug). - Background via
nohup … &;stop/statusreadproxy.pid.
Build pipeline
wispr_pro.py
│ PyInstaller --onefile --collect-all mitmproxy
▼
dist/wispr-pro (single Mach-O, arm64 / universal2)
│ build_app.py assembles bundle + codesign
▼
dist/Wispr Proxyflow.app
│ GitHub Action: hdiutil create (UDZO)
▼
dist/Wispr-Pro-<version>.dmg