generated from eblume/project-template
feat(tui): <Enter> opens the context editor; reorder views (§8.1/§8.2)
All checks were successful
Build / validate (pull_request) Successful in 3m57s
All checks were successful
Build / validate (pull_request) Successful in 3m57s
- `<Enter>` now opens the selected task's context doc in nvim (App::enter: from the sidebar it drills into the task list first); the `o` binding is retired. Hint line updated. - BUILTIN_VIEWS reordered to the owner's preference — Top of Mind, Tasks, Work Tasks, Chores, On Deck — which drives the TUI sidebar and `heph view`. Tests that walked to On Deck by a fixed offset now seek it by title. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2fc48a1aa9
commit
44d6847fae
10 changed files with 97 additions and 54 deletions
|
|
@ -26,6 +26,7 @@ Begin the v1 prototype (Phase 1, tech-spec §11.1), built in TDD slices:
|
|||
- `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`). `a` is a Todoist-style single-line quick-add: `Buy milk tomorrow p2 #Work every week` parses into title + attention (p1–p4) + do-date + recurrence + project (multi-word project names match greedily; an unresolved `#tag` just stays in the title). `/` runs a full-text search whose results overlay the task list; Enter opens a hit (a task at its context doc) in nvim.
|
||||
- Move-to-project (§8.1): a new `task.set_project` RPC re-files a task under another project (or unfiles it) with OR-set link semantics — the old `in-project` link is tombstoned and a new one added, so a task is never filed under two projects at once. In `heph-tui`, **`m`** opens a list-pick overlay ("(Unfile)" then every project) on the highlighted task. `heph edit <task> --project <name>` now routes through the same RPC (fixing a bug where re-filing piled on a duplicate link), and `--project none` unfiles the task. This closes the last Todoist-parity capture gap.
|
||||
- `heph-tui` task-list visuals (§8.1): each row now leads with an attention **flag** (`⚑`, colored red/orange/blue; blank for white) and a **project-colored bullet** — the bullet's color is derived stably from the project id (so it survives projects being added/removed), letting you scan a mixed list by project at a glance. The list also grows a **scrollbar** and keeps the selected task scrolled into view when there are more tasks than fit.
|
||||
- `heph-tui`: **`<Enter>`** opens the selected task's context editor in nvim (from the sidebar it first drills into the task list); the old `o` binding is retired. The view sidebar / `heph view` order is now **Top of Mind, Tasks, Work Tasks, Chores, On Deck**.
|
||||
- `heph-tui` sort toggle (§8.1): **`s`** flips the task list between two orders — **default** (attention → most-overdue → project → creation) and **by-project** (grouped under dimmed `──── Project ────` separators, then the same sub-order). The view's filter still applies first. (To free `s`, **skip** moved to **`S`**.)
|
||||
- `heph.nvim` task-view rows (§8): `:Heph next`/`:Heph list` rows now show a compact **do/late date chip** (and a recurrence `↻`), so you can see scheduling at a glance; `<CR>` still jumps to a task's context doc.
|
||||
- Wiki-links by node id (§8.4): node resolution is now **id-first** (`[[NODEID]]` resolves to its node ahead of any name match, so links can't be shadowed by a like-named node), and heph.nvim grows a **`[[` picker** — type `[[` (or `:Heph link`) to pick a node and insert a canonical `[[NODEID]]` link. With Telescope it's a **live fuzzy filter over your linkable nodes with a preview pane** (the node's body, or a task's context doc) — the list shows first-class targets only (a task appears once; its internal context/log docs and tag nodes are hidden, via the new `node.linkable` query) — type to narrow, Enter to insert, `<C-x>` to create a doc named what you've typed; without Telescope it falls back to a search-then-select prompt. Following such a link (`<CR>`) jumps straight by id. Those id links are kept **readable**: on read a bare `[[NODEID]]` is expanded to `[[NODEID|Current Name]]` (so it follows renames, in both the nvim buffer and the TUI preview), and on save it collapses back to the canonical bare id — a custom `|label` you write is preserved as an override. In the editor the id is **concealed** — a link renders as just its name, styled like a hyperlink, with the raw `[[id|Name]]` revealed on the line your cursor is on. Legacy `[[Name]]` links keep working, and **`heph migrate-links`** rewrites them to the canonical id form in one pass when you're ready (idempotent).
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ Replaces obsidian.nvim. Telescope-backed. **Primarily the context / knowledge-ba
|
|||
|
||||
- **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** (each row: a leading attention **flag** + a **project-colored bullet**, the title, recurrence `↻`, and a compact human do/late chip; a scrollbar appears when the list overflows) · **preview** (canonical-context doc body + `log.tail`).
|
||||
- **Gestures** ✅ — `j/k` move · `Tab`/`h`/`l` focus · `a` **single-line NL quick-add** (Todoist-style: `Buy milk tomorrow p2 #Work every week` → title + attention `p1`..`p4` + do-date + `every …` recurrence + `#project`; no `#project` files it under the selected one) · `x` done · `S` skip · `A` cycle attention · `e` reschedule do-date · `b` push-to-blue · `d` drop · `D` **delete/tombstone** (y/N confirm — true soft-delete, recurring included) · `m` **move-to-project** (a list-pick overlay — "(Unfile)" then every project; backed by `task.set_project`) · `s` **sort toggle** (default ↔ project-grouped) · `o` edit context in nvim · `/` **FTS search** (overlay; Enter opens a hit — a task at its context doc — in nvim) · `r` refresh · `q` quit. The sidebar lists the **§8.2 named filter views** — [[design]] §6.2 "filters = saved views" made interactive. Recurring tasks show a **`↻` marker**, and the **selected row expands inline** with a dimmed detail block (project · recurrence rule · do/late). *(Remaining: humanizing the displayed RRULE is later polish.)*
|
||||
- **Gestures** ✅ — `j/k` move · `Tab`/`h`/`l` focus · `a` **single-line NL quick-add** (Todoist-style: `Buy milk tomorrow p2 #Work every week` → title + attention `p1`..`p4` + do-date + `every …` recurrence + `#project`; no `#project` files it under the selected one) · `x` done · `S` skip · `A` cycle attention · `e` reschedule do-date · `b` push-to-blue · `d` drop · `D` **delete/tombstone** (y/N confirm — true soft-delete, recurring included) · `m` **move-to-project** (a list-pick overlay — "(Unfile)" then every project; backed by `task.set_project`) · `s` **sort toggle** (default ↔ project-grouped) · `⏎` **edit context in nvim** (from a task; from the sidebar it drills into the list) · `/` **FTS search** (overlay; Enter opens a hit — a task at its context doc — in nvim) · `r` refresh · `q` quit. The sidebar lists the **§8.2 named filter views** — [[design]] §6.2 "filters = saved views" made interactive. Recurring tasks show a **`↻` marker**, and the **selected row expands inline** with a dimmed detail block (project · recurrence rule · do/late). *(Remaining: humanizing the displayed RRULE is later polish.)*
|
||||
- **TUI ↔ nvim handoff** ✅ — `o` suspends the alternate screen and launches `nvim +"lua require('heph.node').open('<ctx-id>')"` (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`.
|
||||
|
|
@ -274,10 +274,10 @@ Replaces obsidian.nvim. Telescope-backed. **Primarily the context / knowledge-ba
|
|||
| View | Todoist query (origin) | heph realization |
|
||||
|---|---|---|
|
||||
| **Top of Mind** | `(p1\|p2) & (no date\|today\|overdue)` | `attention ∈ {red,orange}` ∧ actionable |
|
||||
| **On Deck** | `p3 & (no date\|overdue\|today)` | `attention = blue` ∧ actionable |
|
||||
| **Chores** | `(today\|overdue\|no date) & (#Chores\|#Camano Chores)` | scope ∈ {Chores, Camano Chores} ∧ actionable |
|
||||
| **Work Tasks** | `#Work & !p3 & (…) & !subtask` | scope = Work subtree ∧ `attention ≠ blue` ∧ actionable |
|
||||
| **Tasks** | `!p3 & (…) & !(#Daily Routine\|#Work Routine\|#Chores\|#Camano Chores\|#Work\|##Culture\|#Camano Info) & !subtask` | `attention ≠ blue` ∧ actionable ∧ **not in** the routine/work/chore projects |
|
||||
| **Work Tasks** | `#Work & !p3 & (…) & !subtask` | scope = Work subtree ∧ `attention ≠ blue` ∧ actionable |
|
||||
| **Chores** | `(today\|overdue\|no date) & (#Chores\|#Camano Chores)` | scope ∈ {Chores, Camano Chores} ∧ actionable |
|
||||
| **On Deck** | `p3 & (no date\|overdue\|today)` | `attention = blue` ∧ actionable |
|
||||
|
||||
**Engine work — extend `list` (§6) so a view is a *predicate expressed as data*** (mirroring §7's "order as data"):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue