First direct-manipulation edit (v0.4): clicking a headline's keyword pill
cycles its TODO state, each change a single 9P write. Left-click / wheel-up
advance (TODO -> NEXT -> ... -> DONE -> none -> TODO); right-click / wheel-down
step back.
Per-document keyword set (server):
- keywords() previously advertised a hardcoded "TODO NEXT WAITING | DONE
CANCELLED", but the parser only recognizes NEXT/WAITING/CANCELLED when the
document declares them via #+TODO:. Writing an unrecognized keyword merged it
into the title and changed the section's slug id.
- keywords() now returns the parser default "TODO | DONE"; new keywords_for(doc)
returns a document's declared #+TODO: sequence or that default. Exposed as a
per-document /<doc>/keywords file.
GUI:
- DocumentModel::setKeyword writes /<doc>/<id>/keyword and refreshes the row;
cycleKeyword reads the per-document /<doc>/keywords so it only cycles to
keywords the parser recognizes (keeping the section id stable), with a
trailing empty state to clear the keyword.
- The keyword pill gains a hover highlight and a MouseArea for click/wheel
cycling.
Verified: server tests (66 passed, +3: default keyword set, declared sequence,
id stable across set+clear). Live 9P run cycling both a plain document
(TODO|DONE) and one with a #+TODO: sequence confirms the section id stays
stable through a full cycle and every transition writes correctly; empty-write
clearing is covered by a unit test (the ork CLI can't pass an empty arg, but
the GUI's p9 client sends a real empty write). GUI builds clean.
Also refresh VISION.md milestones: v0.3 done; checkbox toggling, code
execution, and keyword cycling ticked under v0.4.