generated from eblume/project-template
All checks were successful
Build / validate (pull_request) Successful in 6m18s
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>
119 lines
5.1 KiB
Markdown
119 lines
5.1 KiB
Markdown
---
|
||
title: heph-pwa (mobile app)
|
||
modified: 2026-06-04
|
||
tags:
|
||
- how-to
|
||
---
|
||
|
||
# heph-pwa — the mobile app
|
||
|
||
`heph-pwa` is a phone-first, installable web app that mirrors [[v1-prototype-tech-spec|heph-tui]]:
|
||
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:
|
||
|
||
```bash
|
||
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-root` is optional. Unset, the hub serves only its API routes (unchanged
|
||
behavior). Set, it serves the static shell for any non-API path, with an
|
||
`index.html` SPA 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
|
||
`OPTIONS` preflight, 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 `hephd` base 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 the `version` RPC).
|
||
|
||
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|tech-spec §8.1]] 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 `hephd` as a managed service
|
||
- [[v1-prototype-tech-spec]] — data model, RPC API, quick-add spec
|
||
- [[design]] — vision and rationale
|