heph-pwa: mobile app (PWA mirror of heph-tui) + hub static serving #8

Merged
eblume merged 7 commits from feature/heph-pwa-mobile into main 2026-06-04 17:50:48 -07:00
Owner

Summary

A phone-first, installable PWA that mirrors heph-tui: browse the built-in
views + projects, triage tasks, and — the primary use case — capture tasks fast
with the same quick-add syntax as the desktop Cmd-' popover. Context/KB is
read-only. Online-only thin client of a server-mode hephd.

Chosen as a PWA (not native Swift) because a native iOS app can't be signed or
built without an Apple Developer account; the PWA delivers the primary use case
today and is installable to the home screen.

Backend (hephd)

  • Permissive CORS + browser OPTIONS preflight on the hub HTTP routes.
  • Optional --web-root static serving (index.html SPA fallback) so the hub
    can host the app same-origin. No new crate deps; covered by tests/web_serve.rs.
  • The ⌘' popover is now supervised in server mode too (was gated to local),
    so a store-owning hub can both host the app and drive the desktop popover.

App (heph-pwa/)

  • Buildless ES modules. quickadd.js / datespec.js are faithful ports of the
    Rust parsers, verified by test/parsers.test.mjs (parity with the Rust unit
    cases).
  • Sidebar views (tom/tasks/work/chores/ondeck/inbox) + projects; task list with
    attention flags / project bullets / date chips; tap-to-expand triage
    (done/drop/skip/attention/reschedule/move/delete + undo); search; read-only
    context+log preview.
  • Quick-add modal (FAB or Cmd-') with live parse-preview chips and voice
    (iOS keyboard dictation / Web Speech API). Defaults its hub URL to the serving
    origin (zero-config); re-fetches the current view on window focus.
  • Manifest + service worker (offline app shell) + icons.

Docs

  • docs/how-to/heph-pwa.md — the app (features, quick-add, voice, triage).
  • docs/how-to/host-heph-pwa.md — production runbook: host from the indri hub
    with OIDC in the hub/spoke setup.

Testing

  • cargo test -p hephd (incl. new web_serve.rs) — green
  • node --test heph-pwa/test/parsers.test.mjs — 13/13
  • End-to-end against a local server-mode hephd in headless Chrome (renders
    RankedTasks from the live hub); CORS/preflight/static/SPA-fallback via curl
  • Running live on gilbert over the tailnet

Known follow-ups

  • No in-app OIDC device-code login yet (paste a bearer token in Settings).
  • Online-only (no offline/CRDT replica); context read-only; undo covers done/drop.
  • Push-based live updates to the PWA (see the heph.nvim server-push ticket).
## Summary A phone-first, installable **PWA** that mirrors `heph-tui`: browse the built-in views + projects, triage tasks, and — the primary use case — capture tasks fast with the same quick-add syntax as the desktop Cmd-' popover. Context/KB is read-only. Online-only thin client of a server-mode `hephd`. Chosen as a PWA (not native Swift) because a native iOS app can't be signed or built without an Apple Developer account; the PWA delivers the primary use case today and is installable to the home screen. ### Backend (`hephd`) - Permissive **CORS** + browser `OPTIONS` preflight on the hub HTTP routes. - Optional **`--web-root`** static serving (index.html SPA fallback) so the hub can host the app same-origin. No new crate deps; covered by `tests/web_serve.rs`. - The ⌘' popover is now supervised in **server** mode too (was gated to local), so a store-owning hub can both host the app and drive the desktop popover. ### App (`heph-pwa/`) - Buildless ES modules. `quickadd.js` / `datespec.js` are faithful ports of the Rust parsers, verified by `test/parsers.test.mjs` (parity with the Rust unit cases). - Sidebar views (tom/tasks/work/chores/ondeck/inbox) + projects; task list with attention flags / project bullets / date chips; tap-to-expand triage (done/drop/skip/attention/reschedule/move/delete + undo); search; read-only context+log preview. - Quick-add modal (FAB or Cmd-') with live parse-preview chips and voice (iOS keyboard dictation / Web Speech API). Defaults its hub URL to the serving origin (zero-config); re-fetches the current view on window focus. - Manifest + service worker (offline app shell) + icons. ### Docs - `docs/how-to/heph-pwa.md` — the app (features, quick-add, voice, triage). - `docs/how-to/host-heph-pwa.md` — production runbook: host from the indri hub with OIDC in the hub/spoke setup. ## Testing - [x] `cargo test -p hephd` (incl. new `web_serve.rs`) — green - [x] `node --test heph-pwa/test/parsers.test.mjs` — 13/13 - [x] End-to-end against a local server-mode hephd in headless Chrome (renders RankedTasks from the live hub); CORS/preflight/static/SPA-fallback via curl - [x] Running live on gilbert over the tailnet ## Known follow-ups - No in-app OIDC **device-code login** yet (paste a bearer token in Settings). - Online-only (no offline/CRDT replica); context read-only; undo covers done/drop. - Push-based live updates to the PWA (see the heph.nvim server-push ticket).
Add a permissive CORS middleware (answers the browser OPTIONS preflight and
stamps Access-Control-* on every response) and an optional --web-root static
file handler with an index.html SPA fallback. Together these let a browser
surface — the forthcoming heph-pwa mobile app — call /rpc cross-origin or be
hosted same-origin straight from the hub. No new crate dependencies; file
reads run on the blocking pool. Covered by tests/web_serve.rs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Faithful JS ports of hephd's quickadd.rs / datespec.rs so the PWA's quick-add
accepts the identical syntax (p1-4, #Project greedy match, today/+3d/fri/ISO,
'every …' recurrence) and produces the same RRULEs and local-midnight do-dates
as the CLI/TUI. test/parsers.test.mjs replays the Rust unit cases under
`node --test` (13/13 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A buildless, installable PWA that mirrors heph-tui: sidebar of built-in views
(tom/tasks/work/chores/ondeck/inbox) + projects, a task list with attention
flags / project bullets / date chips, tap-to-expand triage (done/drop/skip/
attention/reschedule/move/delete + undo), full-text search, and a read-only
context+log preview. The primary surface is the quick-add modal (FAB or Cmd-'),
which live-parses the TUI syntax into preview chips and supports voice via
on-device dictation / the Web Speech API. rpc.js is the online-only JSON-RPC
client mirroring heph-tui's Backend; settings persist in localStorage. Service
worker caches the app shell for offline launch.

Verified end-to-end against a local server-mode hephd (--web-root): the app
boots, calls the view RPC, and renders RankedTasks in headless Chrome.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document serving the app from the hub (--web-root), connecting (hub URL +
optional token), quick-add syntax, voice, triage, and the deliberate
design choices (PWA over native iOS; online-only; token paste vs device flow)
with their known limitations to revisit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Popover supervision was gated to Mode::Local, so running the store-owning
daemon in server mode (now needed to host heph-pwa) silently dropped the
desktop quick-capture popover. Server mode is local + an HTTP hub and owns the
same store/socket, so it should drive the popover too; broaden the guard to
Local | Server (client, a thin proxy, still opts out).

Also: when the PWA shell is served from the hub, default the hub URL to its own
origin so the app is zero-config on first open (Settings still overrides). Bump
the service-worker cache to v2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The PWA shares the daemon's store with the TUI/desktop popover but only
re-fetched on a view switch or action — so a task marked done elsewhere left a
stale list on screen. Reload the current view on visibilitychange→visible
(switch back to the phone, unlock, tab re-show), skipping it mid-modal/search.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
doc(heph-pwa): production runbook — host the app from the hub (indri) with OIDC
All checks were successful
Build / validate (pull_request) Successful in 6m18s
936c2635ef
Add host-heph-pwa.md: a deployment how-to for serving the PWA from the canonical
hub in the hub/spoke OIDC setup (post-release) — fetch the shell at the hub's
tag, add --web-root, terminate TLS (tailscale serve / reverse proxy), and the
token-paste caveat with the device-code-login follow-up. Cross-linked from
heph-pwa and the how-to index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
eblume merged commit 052f624e6f into main 2026-06-04 17:50:48 -07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
eblume/hephaestus!8
No description provided.