feat(nvim): frontmatter edit surface — diff block into RPCs on save (§8.3)
Some checks failed
Build / validate (pull_request) Failing after 5m1s

Node buffers now open with the editable YAML frontmatter block on top
(node.get {frontmatter: true}); on :w, `frontmatter.lua` parses the
block, diffs it against what was rendered, and routes each changed field
to the right RPC:
- title → node.update rename
- attention → task.set_attention
- do_date/late_on/recurrence → task.set_schedule (YYYY-MM-DD → local-ms;
  a removed line clears via null)
- project → task.set_project (resolved by name)
- tags → tag.add / tag.remove
A mistyped state surfaces the daemon's validation error; a buffer with no
block edits no metadata (deleting the block can't wipe tags). Body rides
node.update as before (the store strips any echoed frontmatter).

Body-position features are content-relative, so the prepended block
doesn't disturb them; e2e specs that targeted absolute line 1 now locate
body lines by content via a new `h.find` helper. New frontmatter_spec
covers render + the full diff→RPC round-trip. 21 nvim e2e specs green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-06-03 11:44:39 -07:00
commit 0e9cfc1fd7
9 changed files with 328 additions and 23 deletions

View file

@ -79,6 +79,14 @@ edits, else adding the `wiki` link directly).
| `:Heph promote [attention]` | Promote the `- [ ]` line under the cursor to a committed task |
| `:Heph log <text>` | Append a breadcrumb to the current task's log |
A node buffer opens with an editable **YAML frontmatter** block on top (`id`,
`kind`, `title`, `tags`, and — for a task or its context doc — the task's
`state`/`attention`/`do_date`/`late_on`/`recurrence`/`project` plus a `task:`
ref). On `:w`, `frontmatter.lua` diffs the block against what was rendered and
issues the right RPC per changed field (rename, `set_attention`, `set_schedule`,
`set_project`, `tag.add`/`tag.remove`); the store strips the block so it never
enters the body (tech-spec §8.3). A buffer with no block edits no metadata.
"Current task" is resolved from the buffer: a `task` node, or a canonical-context
doc whose owning task is followed via its `canonical-context` backlink. The
`next`/`list` views render the titled rows the daemon returns (`list` enriched to