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>
5.1 KiB
| title | modified | tags | |
|---|---|---|---|
| heph-pwa (mobile app) | 2026-06-04 |
|
heph-pwa — the mobile app
heph-pwa is a phone-first, installable web app that mirrors v1-prototype-tech-spec:
browse the built-in views and projects, triage tasks, and — the primary use
case — capture tasks fast with the same quick-add syntax as the TUI's a /
Cmd-' popover. Context/KB is read-only here (no Neovim editing surface).
It is a thin, online-only client: every read and write is a JSON-RPC call to a
server-mode hephd (the sync hub, see set-up-sync-hub). There is no
local replica or background sync — when the hub is unreachable, the app shows an
error rather than queueing offline.
Why a PWA and not native iOS? A native Swift app cannot be signed, built, or installed without an Apple Developer account. A PWA delivers the primary use case today — installable to the home screen, full-screen, with home-screen launch and offline app-shell — and keeps the door open to a native wrapper later. This was a deliberate first-cut choice; revisit if a native app becomes worthwhile.
Serve it from the hub
The hub can serve the app shell same-origin (no CORS or separate static host
needed). Point hephd at the heph-pwa/ directory:
hephd --mode server \
--http-addr 0.0.0.0:8787 \
--web-root /path/to/hephaestus/heph-pwa \
--oidc-issuer https://auth.example.com/... \
--oidc-audience heph-mobile
--web-rootis optional. Unset, the hub serves only its API routes (unchanged behavior). Set, it serves the static shell for any non-API path, with anindex.htmlSPA fallback. The shell is unauthenticated (it's just HTML/JS); all data still flows through the auth-gated/rpc.- Every hub response now carries permissive CORS headers and answers the browser
OPTIONSpreflight, so you can alternatively host the shell anywhere (any static server, GitHub Pages, etc.) and still call the hub cross-origin.
Then open https://<hub-host>:8787/ on your phone and Add to Home Screen.
Connect
On first launch the app opens Settings:
- Hub URL — the server-mode
hephdbase URL (e.g.https://hub.example.com:8787). When served from the hub, use that same origin. - Token — a bearer token, if the hub requires OIDC (
--oidc-issuer/-audience). Leave blank for an unauthenticated hub (local network / dev). Tap Test to verify the connection (it calls theversionRPC).
Settings persist in the browser's local storage.
The device-code OIDC login flow (RFC 8628) the CLI/daemon use is not yet wired into the PWA — for now paste a bearer token obtained out-of-band. Wiring the in-app device flow is the obvious next step.
Quick-add
Tap + (or press Cmd-' / Ctrl-' on a keyboard) to capture. The single input accepts the exact v1-prototype-tech-spec syntax, parsed live into preview chips before you submit:
| Token | Example | Effect |
|---|---|---|
p1–p4 |
p1 |
attention: red / orange / blue / white |
#Project |
#Camano Chores |
file under a project (greedy multi-word match) |
| date | today tomorrow +3d fri 2026-07-01 |
do-date |
every … |
every 3 days every other wed every workday |
recurrence (RRULE) |
Unmatched #tags stay in the title verbatim. With no #Project token, the task
files into the currently selected project (or Inbox). The parser is a faithful
JS port of the Rust quickadd/datespec modules, covered by parity tests
(heph-pwa/test/parsers.test.mjs, run with node --test).
Voice
The quick-add field supports voice two ways:
- iOS / iPadOS: use the microphone key on the on-screen keyboard — Apple dictation works in the text field for free, no app permission needed.
- Chrome / Android / desktop: a 🎤 button appears when the Web Speech API is available and dictates straight into the field.
(Anthropic has no speech-to-text endpoint, so transcription leans on the platform. A server-side transcription proxy could be added later if needed.)
Triage
Tap a task to expand its actions, mirroring the TUI keys: Done (x),
Drop (d), Skip (S, recurring only), Attn (cycle attention, A),
Date (reschedule, e), Move (project picker, m), Delete
(tombstone, D). Done/Drop show an Undo. The expanded view also shows the
task's canonical-context body + recent log tail (read-only).
Search (🔍 or /) runs full-text search across tasks and docs.
Known limitations (first cut)
- Online-only; no offline write queue or CRDT replica.
- No in-app OIDC device-code login yet (paste a token).
- Context/KB is read-only (no wiki-link navigation or editing).
- Undo covers Done/Drop only.
Related
- host-heph-pwa — serve this app from the hub (indri) with OIDC, in the hub/spoke deployment
- set-up-sync-hub — stand up the server-mode hub the app talks to
- run-the-daemon — run
hephdas a managed service - v1-prototype-tech-spec — data model, RPC API, quick-add spec
- design — vision and rationale