- spa_server.py: strip /magpie prefix before API check and file lookup;
all HTTP methods call _normalise_path() first so /magpie/api/v1/* proxies
correctly and /magpie/assets/* resolve against the dist root
- manage.sh: pass --base /magpie to spa_server.py so the handler knows
the deployment prefix
- main.ts: pass import.meta.env.BASE_URL to createWebHistory so Vue Router
strips the /magpie prefix before matching routes
Without these fixes, assets returned index.html (MIME type error), API
calls returned HTML instead of JSON (stats.posts undefined), and router
routes never matched (matched: []).
Closes: #12
- Add SessionWidget.vue: sidebar widget showing Reddit session status
(dot color: green/yellow/red by age), age in hours, and a refresh
button that triggers the Playwright re-login (~30s, blocking POST)
- Add SessionStatus + RefreshResult types and api.reddit.* methods to
api.ts (sessionStatus, refreshSession)
- Mount widget at bottom of sidebar in App.vue via margin-top:auto
- Fix spa_server.py: add reverse proxy for /api/* → FastAPI :8532
(without this, all API calls returned index.html in production mode)
- Guard ageText/dotClass computeds against undefined age_hours with
typeof check + == null (catches both null and undefined from stale
browser-cached HTML responses)
Closes: #12
Python's http.server returns 404 for any path that isn't a real file,
breaking Vue Router history-mode navigation (/campaigns, /queue, etc.).
scripts/spa_server.py: minimal static server that falls back to index.html
for any path that doesn't resolve to a real file in the dist directory.
Both _start_web and the `serve` subcommand now use it.