Split EDITOR env var on whitespace so multi-word values like
"code --wait" work correctly. Add allow-list switch for sort column
and order direction at the query boundary to prevent future callers
from passing unsanitized values into SQL.
Run mode (r key on checklist cards): cursor navigates steps, space
toggles done/undone, r resets all, esc saves changes to DB and exits.
Persists step state — improvement over web which discards on exit.
Fill mode (f key on template cards): tab/shift-tab navigates slots,
type to fill values, enter resolves template and copies to clipboard
with use count increment. Esc cancels without copying.
Both modes are sub-states of detail view, keeping architecture simple.
Search uses existing parse grammar ?prefix — type `?query #tag` in
capture bar to filter entities client-side. Substring match on
body+title+description with AND tag filtering. Esc clears search.
Absorb via m key on fluid entities — opens source picker showing all
other entities, enter merges source into target. Uses existing
store.Absorb() backend.
Stream/cards toggle with 1/2 keys. Cards view with intent filtering
(tab cycles grab/read/fill/all), sort cycling (s key), pinned-first
ordering, and affordance badges. Promote picker (p key) with card type
selection and auto-detection from body content. Detail view renders
card_data per type: checklist steps, template slots, decision fields,
link URLs.
Extracts generateCardData to internal/carddata for reuse across cmd
and tui packages.
Status bar with entity count and context-sensitive key hints. Help
overlay via ? key. Tag filter via # with cursor-navigable tag list.
Todo toggle (x), pin (!), promote (p), demote (D), copy (c), edit (e)
via $EDITOR. Delete confirmation with 3s timeout. Date-grouped list
with completed todo and pinned indicators. Esc clears active tag filter.
Adds CompletedAt/ClearCompleted to EntityUpdate for todo toggling.
Adds `nib tui` command and `make tui` target. Scrollable entity list
with j/k navigation, enter for detail view, `a` to capture new entries
using the existing parse grammar, and `d` to delete.