shelbi task

View as markdown
shelbi task <SUBCOMMAND> [OPTIONS]

shelbi task is the CLI face of the Kanban board. Each card is a file under ~/.shelbi/projects/<project>/tasks/; each column transition appends a line to ~/.shelbi/events.log. The TUI's tasks pane and this command are two views on the same files. The orchestrator drives the board through it, and it's where scripting, automation, and one-off fixes live.

A board mid-flight, with one task promoted to TO DO, one dispatched to a workspace, and one already DONE:

jlong@hub — my-project
Tasks · shelbi 5 total Workflow: All ▾ Workspace: All ▾ BACKLOG (2) TO DO (1) IN PROGRESS (1) REVIEW (0) DONE (1) Audit third-party Write CLI reference Write changelog page Getting-started licenses pages app ⎇ shelbi/write-… section app app app Draft Q3 roadmap app
h/l col j/k row open n new f filter r refresh

Every subcommand accepts the global -p / --project <PROJECT> flag: it targets the named project, otherwise $SHELBI_PROJECT or the registered project whose work_dir contains the current directory. It's omitted from the per-subcommand tables below.

add

shelbi task add [OPTIONS] <TITLE>

Create a new task. Lands in backlog by default, your inbox for triage. Pass --status todo to skip triage when you're already sure.

FlagTypeDefaultDescription
<TITLE>stringHuman-readable title (positional, required).
--id <ID>stringslug of titleOverride the auto-generated id.
--status <STATUS>stringbacklogInitial status.
-d, --description <DESCRIPTION>stringemptyTask body. Use shelbi task edit later if omitted.
--depends-on <ID>string (repeatable)Block this task on another. Repeat for multiple deps.
--prefers-machine <NAME>stringHint for the orchestrator to route this task to a workspace on a specific machine.
--workflow <NAME>stringproject defaultWorkflow this task runs under. Names a file in workflows/<NAME>.yaml. Omit to inherit the project's default workflow.
--branch <BRANCH>stringgenerated at dispatchPre-fill the task's branch: frontmatter field. Omit to let the orchestrator generate <prefix>/<task-id> from workflow config, project config, or your GitHub username; supply a value to point the task at an existing branch (the release task pattern).

list

shelbi task list [OPTIONS]

Print every task grouped by column, in priority order within each column. Use --status <NAME> to scope to one status, or --ready to see only unblocked todo items in dispatch order. That's the orchestrator's view of "what should I assign next." --workflow <NAME> narrows either view to a single workflow.

FlagTypeDefaultDescription
--status <STATUS>stringRestrict to a single status.
--readyflagoffShow only unblocked todo items, in priority order. Mutually exclusive with --status.
--workflow <NAME>stringRestrict to tasks resolved to the named workflow. Tasks with no explicit workflow: field inherit the project's default_workflow, or default when unset. Composes with --status and --ready.

show

shelbi task show <ID>

Print a task's frontmatter and body, plus the resolved status of each depends_on entry. The same view the orchestrator reads before deciding whether a task is ready to dispatch.

depends

shelbi task depends [OPTIONS] <ID>

Edit a task's dependency list without opening the file.

FlagTypeDefaultDescription
--add <DEP>string (repeatable)Dependency id to add.
--remove <DEP>string (repeatable)Dependency id to remove.

move

shelbi task move --to <STATUS> [OPTIONS] <ID>

Move a task between statuses. Promoting to todo is the orchestrator's start signal. It picks a free workspace and runs task start itself.

The destination is validated against the task's workflow. A status the workflow doesn't declare (or a custom status with no backing column) errors with the list of reachable statuses, and the task stays put. Matching is case- and punctuation-insensitive (InProgress matches in_progress); a task pinned to a workflow with no YAML on disk falls back to the built-in default, so projects keep moving while the workflows directory is empty.

FlagTypeDefaultDescription
--to <STATUS>stringDestination status (required). Must be a status declared by the task's workflow.
--reason <REASON>stringuser:cliReason tag recorded in ~/.shelbi/events.log. The orchestrator parses this to tell auto-dispatches apart from user actions.

assign

shelbi task assign --to <WORKSPACE> <ID>

Set the task's assigned_to field without launching the workspace. Use this when you want to pre-allocate before promoting to todo. The workspace must be declared in the project YAML.

FlagTypeDefaultDescription
--to <WORKSPACE>stringWorkspace name (required).

unassign

shelbi task unassign <ID>

Clear a task's assigned_to field. The task stays in its current column.

start

shelbi task start [OPTIONS] <ID>

Launch the assigned workspace on this task. Three things happen in one shot:

  1. The workspace's worktree is checked out to the task's branch (generated from workflow config, project config, or your GitHub username when unset).
  2. Any existing pane for that workspace is killed. Context is wiped clean.
  3. The runner relaunches with the task prompt and the column transitions into in_progress.

Pass --workspace to assign and launch in one call. This is the command the orchestrator runs when a task hits todo.

FlagTypeDefaultDescription
--workspace <WORKSPACE>stringtask's assigned_toAssign and launch in one call.
--branch <BRANCH>stringgeneratedOverride the default branch name.
--reason <REASON>stringuser:cli:startReason tag recorded in ~/.shelbi/events.log when the column transitions to in_progress.

resume

shelbi task resume [OPTIONS] <ID>

Relaunch the assigned workspace on the task it is already working, without throwing away progress. Use it when a worker stalls or its session dies (a killed tmux session, a wedged pane, an agent that stopped mid-task) and you want it going again on the same task with its work intact.

resume is the recovery counterpart to start. start wipes the agent's context (kills the pane and re-checks-out a clean branch): right for a fresh dispatch, wrong for recovery. resume instead preserves the in-flight state:

  1. The workspace's worktree is left as-is: its branch, commits, and uncommitted changes stay exactly where the worker left them. The branch is never reset or re-checked-out. (If the worktree was torn down entirely, it's recreated on the task's existing branch.)
  2. The runner pane is recreated or reclaimed: a killed session is stood back up, and a stale or wedged one (the duplicate-session case) is torn down before the fresh pane comes up.
  3. For a claude runner the pane relaunches with --continue, so the worker reloads its prior conversation and picks up mid-thought with full context. Other runners fall back to re-injecting the task prompt. The agent continues by reading its own prior work in the worktree. Either way the prompt is auto-submitted.

If the card has drifted out of in_progress (a killed worker whose task someone moved back), resume restores it.

FlagTypeDefaultDescription
--workspace <WORKSPACE>stringtask's assigned_toWorkspace whose worktree holds the in-flight work.
--reason <REASON>stringuser:cli:resumeReason tag recorded in ~/.shelbi/events.log if the resume has to move the card back into in_progress.

prio

shelbi task prio [OPTIONS] <ID>

Re-order a task within its column. The orchestrator picks the top-most ready task when dispatching, so prio is how you steer "what's next" without opening the TUI.

FlagTypeDefaultDescription
--upflagMove up one slot.
--downflagMove down one slot.
--topflagMove to the top of the column.
--bottomflagMove to the bottom of the column.
--set <N>integerMove to a specific 0-based slot.

edit

shelbi task edit <ID> [OPTIONS]

With no flags, opens the task's markdown file in $EDITOR for free-form edits. Any field flag switches to non-interactive mode, the path for the orchestrator, CI, or a script to revise a task after creation. A non-interactive edit bumps updated_at, validates the touched fields before writing, and emits an edited event so the change is visible to the board and the activity feed. Fields that already have a dedicated command (move, prio, assign, depends) are out of scope; use those.

FlagTypeDescription
--title <TITLE>stringChange the display title. The task's id stays stable (never re-slugged).
--body <TEXT>stringReplace the body with this text.
--body-file <PATH>pathReplace the body with a file's contents.
(stdin)pipePipe the body: shelbi task edit <id> <<EOF … EOF.
--appendflagAppend the body source to the existing body instead of replacing it.
--workflow <NAME>stringSet the workflow. Must name an existing workflows/<NAME>.yaml.
--branch <BRANCH>stringSet the branch: override.
--prefers-machine <NAME>stringSet the machine-affinity hint.
--no-prefers-machineflagClear the machine-affinity hint.
--sub <OLD> <NEW>2× stringLiteral in-place body substitution. Repeatable.
--sub-regex <PATTERN> <REPLACEMENT>2× stringRegex body substitution; REPLACEMENT may reference capture groups ($1). Repeatable.
--allow-no-matchflagPermit a substitution that matches zero occurrences (default: error, writing nothing).
--reason <REASON>stringAnnotation recorded in the emitted edited event. Defaults to user:cli.

The body sources (--body, --body-file, stdin) are mutually exclusive with each other and with the substitution flags. Substitutions replace all occurrences of each match and report a per-substitution count; multiple --sub/--sub-regex apply in command-line order, each operating on the previous one's output. Editing a task whose column is an active status (e.g. in_progress) prints a warning: the running worker won't see the change until the task is re-dispatched with shelbi task start.

# Fix a stale path and swap a value in place, before dispatch.
shelbi task edit fix-login-flow \
    --sub "src/old_auth.rs" "src/auth.rs" \
    --sub-regex "timeout=([0-9]+)" "timeout=30"
 
# Append a late acceptance criterion without rewriting the body.
shelbi task edit fix-login-flow --append <<'EOF'
- [ ] Session cookies are cleared on logout.
EOF

rm

shelbi task rm <ID>

Delete a task file.

Irreversible

shelbi task rm deletes the task's markdown file outright. There's no trash and no undo. To take a card off the board without destroying its history, move it back to backlog instead.

Examples

Triage a new request into the backlog with a dependency on existing work:

shelbi task add "Wire up changelog page" \
    --depends-on docs-write-getting-started-section

Promote a triaged task to todo, and the orchestrator picks it up:

shelbi task move docs-write-cli-reference-pages --to todo

Reorder ready work so a specific task is dispatched first:

shelbi task prio fix-sidebar-clamp --top

Manually dispatch an explicit workspace (overrides the orchestrator's routing):

shelbi task start docs-write-changelog-page --workspace delta

Recover a stalled worker without losing its in-flight work, relaunching the pane and resuming the conversation on the same task:

shelbi task resume docs-write-changelog-page

See also

  • Workflows — the schema behind --workflow, what --to is validated against on task move, and the default workflow's lifecycle (who moves a task between which statuses).
  • shelbi workflow — list, show, scaffold, and edit the workflow YAMLs tasks run under.
  • Workspaces — the pool model that assign / start route into.
  • Orchestrator — how --reason tags get parsed by the scheduler.