From 2e0e37f76dbafcc84f8bba9832f2e33478c3044b Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 3 Jun 2026 07:23:18 -0700 Subject: [PATCH] =?UTF-8?q?docs(tui):=20mark=20heph-tui=20daily-driver=20c?= =?UTF-8?q?ore=20built=20(=C2=A78.1,=20=C2=A714)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §8.1 status → "core built" with the implemented panes/gestures/handoff; §14 adds the heph-tui Done bullet, retargets the resume list to T3 (NL quick-add + search), and bumps the count to 171 Rust tests. Changelog fragment for the TUI. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/changelog.d/v1-prototype.feature.md | 1 + docs/reference/tech-spec.md | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/changelog.d/v1-prototype.feature.md b/docs/changelog.d/v1-prototype.feature.md index 9ccf385..6771681 100644 --- a/docs/changelog.d/v1-prototype.feature.md +++ b/docs/changelog.d/v1-prototype.feature.md @@ -23,3 +23,4 @@ Begin the v1 prototype (Phase 1, tech-spec §11.1), built in TDD slices: - CLI as a complete task surface (§1, §6.2.1): `heph` now implements the entire daemon API and is the task capture/scripting surface. Structured fields are flags with **human dates** (`--do-date tomorrow|+3d|fri|YYYY-MM-DD`, shown back compactly in `next`/`list`) and **recurrence** (`--recur` presets/natural-language like "every 3 days", or a raw `--rrule`). New verbs: `list`, `done`/`drop`/`skip`, `attention`, `edit` (reschedule do-date/late-on/recurrence, re-attention, re-file — backed by the new `task.set_schedule` RPC), `promote`, `show`, `log` (append or tail), `health`, `node update`/`rm`, `resolve`, `links`/`backlinks`, `link add`, `project add [--parent]`, `sync [--status]`, `conflicts [resolve]`. Projects are referenced by name. Date/recurrence parsing is unit-tested; the new verbs have real-socket process tests. - Daemon lifecycle is now an explicit OS service, and all surfaces are connect-only (no more auto-spawn). `heph daemon start/stop/restart/status/uninstall` idempotently manages a launchd agent (macOS) or systemd user service (Linux) that runs `hephd` on your default store; `heph.nvim` no longer spawns or supervises a daemon — it just connects and points you at `heph daemon start` if none is running. Rationale: once the CLI became a first-class surface, a daemon owned by one surface couldn't be shared (see [[run-the-daemon]], [[design]] §4). - Filter views (§8.2) — saved agenda slices, so the agenda isn't one flat list. `heph view ` runs a built-in view (`tom` Top of Mind, `ondeck` On Deck, `chores`, `work` Work Tasks, `tasks`) seeded from the owner's Todoist filter queries; `heph view` with no name lists them, and `:Heph view ` does the same in Neovim. Under the hood, `list` now takes a `ListFilter` predicate-as-data (attention include/exclude sets, project-subtree scope, project exclusions, an actionable do-date gate), and views resolve project names to ids and expand each to its `parent`-link subtree. The Schedule view is intentionally omitted (time-of-day isn't modeled on date-grained do-dates). +- `heph-tui` (§8.1) — a terminal task agenda/triage UI, the primary surface for working a large task set (the §6.2.1 Todoist study showed triage, not single edits, dominates). A `ratatui` app, thin client of the daemon socket. Three panes: a sidebar of the five filter views + your projects, an attention-colored task list with compact human do/late dates, and a preview of the highlighted task's context doc + recent log. Triage from the keyboard: `a` add (guided title → attention → do-date, filed under the selected project), `x` done, `s` skip, `d` drop, `A` cycle attention, `b` push to On Deck, `e` reschedule the do-date; `o` opens the task's context doc in your nvim (live, via heph.nvim) and returns. `j/k` move, `Tab`/`h`/`l` switch panes, `r` refresh, `q` quit. Run it with `heph-tui` (honors `--socket` / `$HEPH_SOCKET`). Single-line natural-language quick-add and search are still to come. diff --git a/docs/reference/tech-spec.md b/docs/reference/tech-spec.md index 1c3d652..ae596c0 100644 --- a/docs/reference/tech-spec.md +++ b/docs/reference/tech-spec.md @@ -248,16 +248,16 @@ Replaces obsidian.nvim. Telescope-backed. **Primarily the context / knowledge-ba **Known-hard:** reconciling an incoming CRDT body delta into a *dirty* buffer (unsaved local edits, cursor position) — the §9 "update arrives while a buffer is open" case — is genuinely fiddly under Fork A; expect to iterate. -## 8.1 heph-tui surface — task agenda / triage (planned) +## 8.1 heph-tui surface — task agenda / triage (core built) -> **Status: planned, not yet built.** The §6.2.1 Todoist study shows the dominant task activity is *interactive triage of a large set* (387 active tasks; daily orange reconfirm, blue keep/drop review, browse-by-project) — work that is awkward as either CLI flags or nvim buffers. A terminal UI owns it; the CLI (capture/scripting) and nvim (context) flank it. +> **Status: daily-driver core built** (slices T1–T2c; NL quick-add + search are the remaining T3 polish). The §6.2.1 Todoist study shows the dominant task activity is *interactive triage of a large set* (387 active tasks; daily orange reconfirm, blue keep/drop review, browse-by-project) — work that is awkward as either CLI flags or nvim buffers. A terminal UI owns it; the CLI (capture/scripting) and nvim (context) flank it. -- **Crate `crates/heph-tui`** — `ratatui` + `crossterm`, a **thin client of the daemon unix socket** (reuse `hephd::Client`); never touches SQLite, same as nvim. -- **Layout** — three panes: **projects/contexts** (the §6.2.1 hierarchy) · **task list** (`next`/`list` rows with attention + human do/late) · **preview** (canonical-context doc body / `log.tail`). -- **Gestures** — `j/k` move · `a` add · `x` done · `space` skip · `A` cycle attention · `e` reschedule (do/late) · `b` push-to-blue · the left pane lists the **§8.2 named filter views** (Top of Mind, Tasks, Work Tasks, Chores, On Deck) — the [[design]] §6.2 "filters = saved views" made interactive. -- **TUI ↔ nvim handoff** — `o`/`` launches `$EDITOR` (nvim) on the task's canonical-context doc (`nvim` with a `+lua` call opening `heph://node/`, or a temp `.md` round-tripped through `node.update`); a nvim command (e.g. `:Heph agenda`) shells back to the TUI. -- **Testing** — TDD against a real daemon; headless smoke via `ratatui`'s `TestBackend`. -- **Prereqs** (land first): **§8.2 filter views** (the TUI's saved-filter pane is just those views); the CLI-complete task surface and `task.set_schedule` (done). +- **Crate `crates/heph-tui`** ✅ — `ratatui` (which re-exports `crossterm`), a **thin client of the daemon unix socket** (reuse `hephd::Client`); never touches SQLite, same as nvim. `App` is generic over a `Backend` seam so navigation/triage logic is unit-testable without a terminal or daemon; `ui::render` is pure. +- **Layout** ✅ — three panes: **sidebar** (the five §8.2 filter views + projects) · **task list** (attention-colored rows with compact human do/late) · **preview** (canonical-context doc body + `log.tail`). +- **Gestures** ✅ — `j/k` move · `Tab`/`h`/`l` focus · `a` add (guided: title→attention→do-date, filed under the selected project) · `x` done · `s` skip · `A` cycle attention · `e` reschedule do-date · `b` push-to-blue · `d` drop · `o` edit context in nvim · `r` refresh · `q` quit. The sidebar lists the **§8.2 named filter views** — [[design]] §6.2 "filters = saved views" made interactive. *(T3: a single-line NL quick-add à la Todoist, and `/` search.)* +- **TUI ↔ nvim handoff** ✅ — `o` suspends the alternate screen and launches `nvim +"lua require('heph.node').open('')"` (heph.nvim's live buffer surface), passing `$HEPH_SOCKET` so the child points at the same daemon, then restores and reloads. *(A nvim command shelling back to the TUI is later polish.)* +- **Testing** ✅ — TDD against a real daemon; headless render assertions via `ratatui`'s `TestBackend`, plus in-memory navigation/input-flow units against a fake backend. +- **Prereqs** (landed): **§8.2 filter views**; the CLI-complete task surface and `task.set_schedule`. ## 8.2 Filter views (saved agenda slices) — built @@ -380,7 +380,7 @@ See [[design]] §5–§7 for the constraints later phases impose on present choi ## 14. Implementation status (Phase 1 tracker) -> Cross-session resume tracker for the Phase 1 C1 (branch `feature/v1-prototype`, PR #1). Updated 2026-06-03 — **154 Rust tests** (`cargo test --all`) + **18 heph.nvim headless e2e specs** (`mise run test-nvim`; also runs in CI via `dagger call test-nvim`), `clippy -D warnings` + `fmt` + `prek` clean. Workspace: `crates/heph-core`, `crates/hephd`, `crates/heph`, plus `heph.nvim/` (slices 11a–11c **+ a UX iteration + filter views**, below). **The plugin is installed and running on the dev machine** (built from the forge; see [[install-heph]]). +> Cross-session resume tracker for the Phase 1 C1 (branch `feature/v1-prototype`, PR #1). Updated 2026-06-03 — **171 Rust tests** (`cargo test --all`) + **18 heph.nvim headless e2e specs** (`mise run test-nvim`; also runs in CI via `dagger call test-nvim`), `clippy -D warnings` + `fmt` + `prek` clean. Workspace: `crates/heph-core`, `crates/hephd`, `crates/heph`, **`crates/heph-tui`**, plus `heph.nvim/` (slices 11a–11c **+ a UX iteration + filter views + the heph-tui agenda**, below). **The plugin is installed and running on the dev machine** (built from the forge; see [[install-heph]]). **Done** @@ -410,12 +410,13 @@ See [[design]] §5–§7 for the constraints later phases impose on present choi - **Dev/installed isolation:** installed `heph`/`hephd` own the default paths; `mise run dev` runs the working-tree daemon on `.dev/` paths; `$HEPH_SOCKET`/`$HEPH_DB` point a dev Neovim at it. - **CI is now fully Dagger** (`build.yaml`: `dagger call check` + `test-nvim`; **prek dropped from CI** — the Alpine job image has no Rust/nvim/prek, only Dagger + DinD). First-ever green CI. - ✅ **Filter views (§8.2) — saved agenda slices:** the owner's saved filters are first-class so the agenda isn't one flat list. New **`heph-core::filter`**: a `ListFilter` **predicate-as-data** (`attention_in`/`attention_not` sets, project-id `scope`, `exclude_projects`, an `actionable` do-date gate) + the five built-in [`ViewSpec`]s (Top of Mind / On Deck / Chores / Work Tasks / Tasks — **Schedule dropped**, §8.2). `Store::list` now takes a `ListFilter`; new `Store::view(name)` resolves a spec's project **names** → ids and **subtree-expands** them through `parent` links (`links::project_subtree`/`resolve_project_id`), tolerating absent projects (a scoped view whose projects are all missing returns empty, never widens). Surfaces: `heph view ` (no name lists the five), the **`view` RPC** + `RemoteStore` forward, and `:Heph view ` in nvim (`heph://view/` buffers). The `list` RPC/`RemoteStore`/CLI/`heph.nvim` migrated to the filter wire (legacy `--scope`/`--attention`/`--no-blue` map onto it). Tested: `filter` unit predicate, a `views` integration suite (subtree scope+exclude, actionable gate, unknown-view error, absent-project empties), a socket `list`/`view` dispatch test, and two nvim e2e specs. +- ✅ **`heph-tui` (§8.1) — the task agenda/triage surface, daily-driver core (slices T1–T2c):** a `ratatui` terminal UI, thin client of the daemon socket (never touches SQLite). **3-pane layout** — sidebar (the five §8.2 views + projects) · attention-colored task list with compact human do/late · preview (canonical-context body + `log.tail`). `App` is generic over a `Backend` seam (unit-testable without a terminal/daemon); `ui::render` is pure. **Gestures:** `j/k`/`Tab`/`h`/`l` navigate; `a` guided add (title→attention→do-date, filed under the selected project); `x` done, `s` skip, `d` drop, `A` cycle attention, `b` push-to-blue, `e` reschedule do-date; `o` suspends and opens the task's context doc in nvim (`+lua require('heph.node').open`, `$HEPH_SOCKET` shared) then reloads. Shared client date/recurrence parsing (`datespec`) moved from the CLI into `hephd`'s lib so both surfaces use one parser (heph-core stays clock-pure). Tested: `TestBackend` render assertions against a real spawned daemon + in-memory navigation/input-flow units. *(Remaining T3: a single-line NL quick-add like Todoist, `/` search, move-to-project.)* **Not yet done (resume order)** -> The Rust backend is feature-complete; the **CLI is the complete API + task driver**, the **daemon runs as an OS service** (`heph daemon`; all surfaces connect-only), the live store has been seeded from Todoist with reference contexts reclassified to wiki docs ([[design]] §6.2.1), and **filter views (§8.2) are built** (`heph view`). **Surface strategy = three-surface model** ([[design]] §4): **CLI = capture/scripting + complete API** (done), **TUI = primary task agenda/triage** (next big build), **nvim = context/KB**. Remaining work, in order: +> The Rust backend is feature-complete; the **CLI is the complete API + task driver**, the **daemon runs as an OS service** (`heph daemon`; all surfaces connect-only), the live store has been seeded from Todoist ([[design]] §6.2.1), **filter views (§8.2) are built** (`heph view`), and the **`heph-tui` daily-driver core is built** (§8.1, T1–T2c). **Surface strategy = three-surface model** ([[design]] §4): **CLI = capture/scripting + complete API** (done), **TUI = primary task agenda/triage** (core done, T3 polish remains), **nvim = context/KB**. Remaining work, in order: -1. ⏳ **`heph-tui` — the task agenda/triage surface (§8.1) — the next big build:** ratatui terminal UI over the daemon socket; projects/list/preview panes; the §8.2 filter views as the saved-filter pane (the `view` RPC is ready); launches into nvim for context and back. **Filter-views prereq is now done.** +1. ⏳ **`heph-tui` T3 — quick-add + search polish (§8.1):** a single-line **NL quick-add** (`Buy milk tomorrow p2 #Work every week`, reusing `datespec`), `/` **search**, and move-to-project. The daily-driver gestures (T1–T2c) are done; this closes Todoist-parity capture. 2. ⏳ **nvim task-navigation polish (§8) — small:** show do/late in `next`/`list` rows and a clean jump-to-context gesture (read/navigate, not field-edit). 3. ⏳ **Tags + project-hierarchy depth (§4, §6.2.1) — deferred:** tags are barely used (5/387) so low priority; project hierarchy beyond `project add --parent` (and the subtree `scope` the filter-views slice introduced) is a refinement. 4. ⏳ **`heph.nvim` slice 11d (§6/§8) — DEFERRED, post-parity:** daemon **server-push** notification framing (no-`id` lines on the socket; the client read-loop already demuxes them) + the **dirty-buffer reconcile** (the §8 "known-hard" case) + the "update-arrives-while-open" e2e (§9).