See what's runnable + dispatch by id — cyberine next
cyberine next derives the runnable / blocked / waiting sets from the project task manifest
(.claude/TASKS.md or .local/tasks/ACTIVE.md) — the same deps + blocker logic the global
oc-tasks tool's run action uses, so a T-id picked here is safe to hand to either path.
An empty read has two causes and, since 2026-09-12 (kzkws), two messages: with no manifest file at all it still prints no manifest found. create .claude/TASKS.md (or .local/tasks/ACTIVE.md) ...; with a manifest that exists but holds zero task blocks (exactly what cyberine init seeds) it prints board is empty: <path> exists but holds no task block yet. add tasks (/cyberine:tasks from a conversation, or /cyberine:plan from nothing) .... Both exit 1. The chat /next and /dispatch commands and the planner's list_runnable tool share the same sentence.
Task ids come in two shapes and both are recognised everywhere (cyberine next --dispatch, chat
/dispatch, cyberine loop <id...>): the legacy sequential T<n>/R<n> ids, and nf-tasks'
random k-shape ids (k + 4 lowercase Crockford base32 chars, e.g. k7m2q — alphabet
0-9 a-h j k m n p-t v-z, no i/l/o/u). Don't uppercase a k-id before passing it in: it is
case-sensitive lowercase, unlike T/R ids. The manifest reader also parses (all optional)
effort: S|M|L, priority: p0|p1|p2, created: <text>, and duplicate-of: <id> fields off a
task header; an unrecognised effort/priority value (e.g. a legacy S+M) parses to undefined
rather than erroring. A task carrying duplicate-of: is a tombstone: cyberine next excludes it
from every bucket (like [forbidden]), and a task that depends on a duplicate is satisfied once
the id it points at (the survivor) is done, not the duplicate itself.
cyberine next # show runnable / blocked / waiting sets
cyberine next --all # inside a submodule reading its super's board: every task, not only the submodule's
cyberine next --json # the same sets as one JSON line (schema board-next/1, see "JSON reads of the board" below)
cyberine next --dispatch T05 # dispatch task T05 (its `do:` line is the prompt)
cyberine next --help # one-line usageSubmodule scope (kgvmh, 2026-09-16). A session standing in a git submodule that has no manifest
of its own reads its superproject's board (the resolver anchors up; see docs/tasks-manifest.md
section 2). The listing surfaces then show only the tasks whose path: lands inside that
submodule -- path: sub or path: sub/src/x.ts for a submodule at sub, never path: sub-extra/
-- and print one line to STDERR naming the submodule and how many tasks were hidden:
cyberine: scoped to submodule sub/ -- 3 task(s) elsewhere on this board hidden (--all shows every task)--all restores the whole board. This is the same rule, message shape and flag as nf-tasks'
k1dhx, so both tools answer "what is on my board" the same way from the same directory
(npm run selftest:tasks-interop runs both against one submodule fixture). The chat /next
command takes the same --all. A task with no path: belongs to the superproject and is hidden
inside the submodule. Dep checks still see the whole board, so a scoped task whose dep lives
elsewhere and is done is still runnable.
Known limitations and deferred work: only the LISTING surfaces are scoped (cyberine next, chat
/next). Execution is not: cyberine next --dispatch, cyberine loop, cyberine autopilot and
the planner's backlog tools still see every task, matching nf-tasks, whose run is unscoped too.
The header's done count is still the whole board's, archive included. An NF_TASKS_ROOT pin
turns the scope off, as upstream does.
Sample output for a 7-task project with a mix of done / todo / blocked / waiting:
2 done | 2 runnable | 0 left-for-others | 1 blocked | 1 waiting | 0 in-progress | 0 backlog | 0 forbidden
Runnable (next to dispatch):
T03 next: handlers [deps: T02]
T04 next: routes [deps: T02]
Blocked (deps not done):
T05 blocked: cli -- waiting on: T03, T04
Waiting on external blocker (clear the `blocker:` line to release):
T06 waiting: legal -- blocker: needs legal sign-off--dispatch <T-id> runs the same runnable predicate the chat /dispatch command runs, refuses
with a one-line reason when the id is not runnable (already [done] / already [doing] /
[backlog] -- flip to [todo] first / [forbidden] -- permanent tombstone, never runs /
held by blocker: <text> / blocked -- waiting on: Tnn, Tmm), and exits non-zero so scripts can
gate on it. On success it prints the runId, the log path, the watch command, and the
oc-tasks done Tnn close step.
Batch-integrate finished runs — cyberine land
cyberine land collapses the whole landing leg (wait -> digest -> apply+commit per run -> one final typecheck for the batch) into a single command — the integration step of the two-turn dogfood...
JSON reads of the board — status --json and next --json (ka7fx)
Two read-only views of the board print one JSON object on one stdout line, for a program that narrates the board (the cyberine-taskboard plugin, a script, a status bar) instead of parsing the text...