- scripts/smoke/helpers.mjs — spawn-pi (via python3 pty.spawn), wait-for-port,
fetch, WebSocket helpers; createSmokeHome/removeSmokeHome for isolated HOME
- scripts/smoke/smoke.mjs — 6 node:test assertions:
GET /manifest.json → 200 + JSON shape
GET /icon.svg → 200 + <svg body
GET / (with token) → 302→200 + HTML marker
GET / (no token) → 403
WS /ws (with token) → 101 upgrade
pi process alive check
- scripts/smoke/README.md — usage, design notes, extension guide
- package.json: add 'smoke' script
- docs/SYNC.md: add scripts/smoke/** ownership row + History entry
All 6 tests pass in ~1.4 s locally.
Key finding: pi requires a PTY to enter interactive mode and fire
session_start. Spawning without a TTY causes immediate exit. Workaround:
python3 pty.spawn() — allocates a PTY with no additional deps.