One row of the task list rendered by the TUI: enough to render the
list view without round-tripping for each task. event_count joins
events_index so we don’t need a second query per row.
Append an external reference to tasks.external. The column is
stored as a comma-separated list — small, append-mostly, no
uniqueness constraint. Acceptable shapes (loose, not enforced):
beads:claude-memory-rsw, github:#42, jira:PROJ-1234.
Read only the tail of the JSONL log since the last call. The cheap path
for hot loops (every MCP tool invocation): scan to the marker, ingest
the rest, update the marker.
All tasks for a project, ordered with open ones first (by recency)
then closed ones. The TUI list view binds directly to this — there
is no other consumer, so the shape is tuned for that callsite.
Set or replace tasks.goal for an existing task. Caller is
expected to have validated the task exists (via task_exists); we
don’t error on no-op rows so the upsert pattern is uniform.
Set or replace the closure metadata. Pass None for outcome_tag
to leave it unset; pass Some("done"|"abandoned"|"superseded")
for a structured tag. Free-text outcome is the primary field.
Returns whether a task with this id has been recorded in the derived
state. Cheap O(1) lookup against the tasks primary key. Callers
should run ingest_new_events first if they want to see the latest
JSONL state.
Status string for an existing task (e.g. “open”, “closed”). Returns
None when the task is unknown — caller decides whether that’s a
hard error or a route-to-pending case.