Skip to content

Retire the PWA (ADR-0059), and fix two docs describing a deleted provider layer - #174

Merged
jeffcrouse merged 1 commit into
mainfrom
chore/retire-pwa
Aug 17, 2026
Merged

Retire the PWA (ADR-0059), and fix two docs describing a deleted provider layer#174
jeffcrouse merged 1 commit into
mainfrom
chore/retire-pwa

Conversation

@jeffcrouse

Copy link
Copy Markdown
Member

Proposes ADR-0059: The Web App Is Not an Installable App, and ships it.

The PWA

The web app still shipped as an installable PWA — manifest, apple-mobile-web-app-* meta tags, a Workbox service worker precaching the shell, runtime caches, and a popup encouraging people to install it to their home screen. Every premise of that was reversed one ADR at a time (0001, 0013, 0050, 0057, 0058) and the site was rewritten to stop mentioning it. Nobody removed the PWA itself.

Gone: InstallPrompt, InstallStatus, the manifest, the meta tags, isPWA(), vite-plugin-pwa, and the backend routes for manifest.json / registerSW.js / workbox-*.

/sw.js stays, and serves a tombstone — this is the load-bearing part

Deleting a service worker does not remove it. A browser that registered /sw.js keeps running the installed Workbox worker, which serves the shell cache-first — so it keeps serving the old index.html and the old bundle indefinitely. Unregistration code in main.tsx never runs, because the code that runs is the cached code that predates it. Removing the file cannot fix it; nothing would be left to notice.

What works is the browser's own update check: it re-fetches the worker URL, byte-compares, installs the difference. The tombstone claims its clients, deletes every cache, unregisters itself, and reloads open tabs. It must not 404 — that falls through to the SPA catch-all and hands the browser index.html as its service worker.

Verified, not assumed:

caches before: [ 'workbox-precache-v2-test' ]
registered: true
registrations after tombstone activated: 0
caches after: []

The cost, named rather than argued away

A browser-only listener loses offline access to tracks they already downloaded. The tracks are untouched in IndexedDB; the shell no longer loads without a server. That's correct for a tool whose entire subject is that server, and ADR-0058 point 5 already schedules the offline settings to leave with the player.

MobileAppRedirect and the apple-itunes-app Smart App Banner stay, and are the point: retiring the PWA isn't retiring mobile, it's sending mobile to the real client (ADR-0050).

The two stale docs

  • docs/OTHER_LLMS.md deleted — it planned a Gemini provider "alongside the existing Anthropic and OpenAI-compatible providers", naming providers_openai.py and providers_anthropic.py as templates. ADR-0048 deleted those, plus service.py, providers.py and both SDKs.
  • CLAUDE.md said llm/ holds service.py and providers.py — two of four names gone since ADR-0048.
  • README.md linked the deleted doc and repeated its false claim. Replaced with what's true: no built-in provider, an MCP server, bring your own client.

Also found, deliberately not fixed here

isNativeApp() tests for window.Capacitor, and the Capacitor app was deleted 2026-08-11 — so it is always false. That makes {isNativeApp() && <ServerSettings />} on the Server destination unreachable, along with branches in FullPlayer, colorExtraction, and the "Connect to Server" screen. Same shape as this ADR (a platform layer outliving its platform), recorded as a follow-up because it touches the player.

Verification

  • pnpm test — 63 files / 956 tests passed
  • tsc --noEmit — 14 errors (unchanged baseline)
  • eslint, audio guardrails, dependency boundaries — 0 errors
  • ruff, mypy, both OpenAPI scripts — clean
  • E2E run as CI does (CI=1, --grep-invert=screenshot) against a built frontend and a real backend — 16 passed, 0 failed
  • Built output contains no Workbox chunks, no manifest.json, no registerSW.js; /sw.js serves the tombstone as application/javascript

🤖 Generated with Claude Code

…er (ADR-0059)

The web app still shipped as an installable PWA: a manifest, apple-mobile-web-app meta
tags, a Workbox service worker precaching the shell, runtime caches for artwork and API
responses, and a popup over the interface encouraging people to install it to their home
screen. Every premise of that had been reversed one ADR at a time — 0001, 0013, 0050,
0057, 0058 — and the site was rewritten to stop mentioning it. Nobody removed the PWA
itself, so an administration page for a music server was asking to be installed on a phone
that is already running the native app the same page points at.

Deleted: InstallPrompt and InstallStatus (one call site each), the manifest, the
apple-mobile-web-app meta tags, isPWA(), vite-plugin-pwa, and the backend routes for
manifest.json, registerSW.js and workbox-*.

**/sw.js stays, and now serves a tombstone.** This is the part that cannot be got wrong
quietly. Deleting a service worker does not remove it: a browser that registered one keeps
running the installed Workbox worker, which serves the shell cache-first, so it keeps
serving the old index.html and the old bundle indefinitely. Unregistration code in main.tsx
never executes, because the code that runs is the cached code that predates it. Removing
the file cannot fix that — nothing would be left to notice. What works is the browser's own
update check: it re-fetches the worker URL, byte-compares, and installs the difference. The
tombstone claims its clients, deletes every cache, unregisters itself and reloads open tabs.
It must not 404 — that falls through to the SPA catch-all and answers with index.html.

Verified rather than assumed: seeded a workbox-precache cache, registered /sw.js, and
watched registrations go to 0 and caches to []. main.tsx also unregisters on load, as a
second path for anyone who reaches the new bundle another way.

The cost, named rather than argued away: a browser-only listener loses offline access to
tracks they already downloaded. The tracks are untouched in IndexedDB; the shell no longer
loads without a server. That is correct for a tool whose whole subject is that server, and
ADR-0058 point 5 already schedules the offline settings to leave with the player.

MobileAppRedirect and the apple-itunes-app Smart App Banner stay, and are the point:
retiring the PWA is not retiring mobile, it is sending mobile to the real client (ADR-0050).

Separately, the two stale documents:

  - docs/OTHER_LLMS.md is deleted. It planned a Gemini provider "alongside the existing
    Anthropic and OpenAI-compatible providers" and named providers_openai.py and
    providers_anthropic.py as templates — files ADR-0048 deleted along with service.py,
    providers.py and both SDKs. A plan for a codebase that no longer exists.
  - CLAUDE.md's key-files tree said llm/ holds service.py and providers.py. Two of those
    four names have been gone since ADR-0048.
  - README.md linked the deleted doc and repeated its false claim that Familiar supports
    Anthropic and any OpenAI-compatible endpoint. Replaced with what is actually true: no
    built-in provider, and an MCP server so you bring your own client (ADR-0043).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jeffcrouse
jeffcrouse merged commit 95d5318 into main Aug 17, 2026
13 checks passed
@jeffcrouse
jeffcrouse deleted the chore/retire-pwa branch August 17, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant