Files
typebasedio 4fd0befee1 docs(v0.5.4): rewrite commands.md as a structured reference
Bring docs/commands.md up to current state. The document was last
substantively updated in v0.5; v0.5.2 (restore/notes/path/list --names/
completion + archived-inclusive lookup), v0.5.3 (attach + --direct +
persistent session mode + doctor tmux check), and v0.5.4 (info Session
block + list SESSION column) were all undocumented.

Format follows the spec section §3: each command has Purpose, Usage,
Scenarios, Examples, Flags, Notes, Related. Sections are kept short
(roughly one screen each) — if a command needed more, the command is
doing too much, not the docs.

New non-command sections: workspace layout (task and project), a
consolidated environment-variables table (previously scattered),
explicit query-resolution rules including archive-inclusive lookup
behavior, session modes (direct vs persistent), and a shell-completion
how-to.

Examples use the canonical "ctask" command name per spec §3 — docs
describe the product, not the user's local binary path.
2026-05-14 19:59:22 -04:00

24 KiB

ctask Commands Reference

This document describes every ctask command, its flags, the workspace layout ctask creates, the environment variables that influence its behavior, how queries resolve to workspaces, the two session modes, and how to install shell completion.

It is a practical reference, not a tutorial. Examples use the canonical ctask command name; the binary may surface as ctask.exe or ./ctask in your shell, depending on how it was invoked.

Table of contents


Workspace layout

A task workspace:

workspace-root/
├── task.yaml                    # workspace metadata (managed by ctask)
├── CLAUDE.md                    # agent instructions (seeded by ctask, edited by agent)
├── notes.md                     # working context (maintained by agent)
├── logs/
│   └── sessions.log             # append-only session history
└── .ctask/                      # ctask internals (do not edit)
    ├── session.json             # active session lease (v0.4+)
    ├── write.lock               # metadata write lock (v0.4+)
    ├── manifest-start.json      # session start snapshot (v0.2+)
    └── last-session-summary.json  # session summary (v0.4+)

A project workspace adds a project subdirectory and (optionally) a git repo:

workspace-root/
├── task.yaml                    # includes launch_dir: "<project-slug>"
├── CLAUDE.md
├── notes.md
├── .git/                        # single git repo at workspace root
├── .gitignore                   # excludes .ctask/ and logs/sessions.log
├── <project-slug>/              # project subdirectory; agent launches here
│   └── ...                      # user's source code
├── logs/
│   └── sessions.log
└── .ctask/
    └── ...

Files inside .ctask/ are ctask state. Editing them by hand can confuse session detection, archive guards, and the stale-workspace detector.


Workspace creation and entry

ctask new

Purpose: Create a new task or project workspace and launch the agent.

Usage:

ctask new [title] [flags]

If title is omitted, ctask generates task-HHMMSS.

Scenarios:

  • Starting a new piece of work from scratch.
  • Standing up a longer-lived project workspace with --project.

Examples:

$ ctask new "fix auth bug"
[ctask] created general/2026-05-14_fix-auth-bug

$ ctask new --project "billing service"
[ctask] created projects/2026-05-14_billing-service

$ ctask new --no-launch "json cleanup"
[ctask] created general/2026-05-14_json-cleanup

Flags:

  • --category, -c — workspace category subdirectory. Default: general for tasks, projects for projects.
  • --project — create a project workspace. Uses CTASK_PROJECT_ROOT if set, runs git init, seeds the project CLAUDE.md template.
  • --shell — open an interactive shell instead of the agent.
  • --agent, -a — override the agent command (default: claude or CTASK_AGENT).
  • --no-launch — create the workspace only; do not launch a session.
  • --direct — bypass persistent session mode for this invocation.
  • --container — deferred to a future release.

Notes:

  • --project runs git init if git is on PATH and seeds a minimal .gitignore (only when no .gitignore was provided by a seed).
  • For project workspaces, the agent launches inside the project subdirectory (controlled by launch_dir in task.yaml).
  • If the session ends without producing any file changes (e.g. the user cancels at the agent prompt), the workspace is removed automatically — the "provisional workspace" cleanup gate. Persistent mode disables this gate.

Related: ctask resume, ctask attach, ctask doctor.


ctask resume

Purpose: Reopen an existing workspace and launch the agent.

Usage:

ctask resume <query> [flags]

Scenarios:

  • Picking up where you left off in a previous session.
  • Re-entering a long-lived project workspace.

Examples:

$ ctask resume auth-bug
[ctask] local :: fix-auth-bug
[ctask] ~/ai-workspaces/general/2026-05-14_fix-auth-bug
[ctask] Last session: 2026-05-13 14:30-15:45 (warren-desktop, claude)

Flags:

  • --shell — open an interactive shell instead of the agent.
  • --agent, -a — override the agent command for this invocation.
  • --force — skip both the active-session and stale-workspace warnings. Use only when the human has already decided to proceed.
  • --direct — bypass persistent session mode for this invocation.
  • --container — deferred.

Notes:

  • Resolves archived workspaces too, but refuses to launch them and prints a restore hint instead.
  • If multiple workspaces match the query, ctask prints all matches and exits with an error. See Query resolution.
  • Updates updated_at in task.yaml so ctask last recognises this workspace as the most recent.

Related: ctask last, ctask attach, ctask restore, ctask info.


ctask last

Purpose: Resume the most recently updated workspace, across both tasks and projects.

Usage:

ctask last [flags]

Scenarios:

  • Returning to whatever you were last working on without typing a name.

Examples:

$ ctask last
[ctask] local :: fix-auth-bug
[ctask] ...

Flags:

  • --shell — open an interactive shell instead of the agent.
  • --agent, -a — override the agent command.
  • --force — skip active-session and stale-workspace warnings.
  • --direct — bypass persistent session mode for this invocation.

Notes:

  • Equivalent to ctask resume on whichever active workspace has the latest updated_at. Archived workspaces are excluded.
  • Exits non-zero with No active workspaces found. when there are no active workspaces.

Related: ctask resume.


ctask open

Purpose: Open a workspace directory in an interactive shell without launching the agent.

Usage:

ctask open <query> [flags]

Scenarios:

  • Browsing the workspace, running git commands, editing files manually.

Examples:

$ ctask open auth-bug
# subshell rooted at the workspace; exit returns to your prior shell.

Flags:

  • --all, -a — include archived workspaces in query resolution.
  • --force — skip active-session and stale-workspace warnings.
  • --direct — bypass persistent session mode for this invocation.

Notes:

  • Spawns a subshell — the parent shell is unaffected.
  • Same lease/manifest/summary lifecycle as resume, just running $SHELL (or PowerShell on Windows) instead of the agent.

Related: ctask resume, ctask path.


ctask attach

Purpose: Attach to a workspace via tmux. Always uses persistent session mode regardless of CTASK_SESSION_MODE.

Usage:

ctask attach <workspace> [flags]

Scenarios:

  • You have not enabled persistent mode globally but want tmux for one workspace.
  • A persistent tmux session already exists; you want to reattach instead of starting a second direct-mode session.
  • Scripts that need unambiguous "tmux always" behavior.

Examples:

$ ctask attach promptvolley-v3
# owner-create OR passive reattach OR adopted reattach,
# depending on the workspace's current lease/tmux state.

Flags:

  • --agent, -a — override the agent command (used only on owner-create, when ctask spawns the agent inside the new tmux session).
  • --force — skip active-session and stale-workspace warnings. Owner-create path only.

Notes:

  • Active-only resolution: archived workspaces are not candidates.
  • See Session modes for the three entry paths (owner-create, passive reattach, adopted reattach).
  • Native Windows is not supported. Run ctask under WSL.

Related: ctask resume --direct, ctask doctor (tmux check).


Inspection

ctask info

Purpose: Display metadata, path, and current session state for a workspace without entering it.

Usage:

ctask info <query>

Scenarios:

  • Diagnosing whether a workspace is currently in use.
  • Checking the launch directory for a project workspace.

Examples:

$ ctask info promptvolley-v3
Task:      promptvolley-v3
Title:     Prompt Volley v3
Category:  projects
Status:    active
Mode:      local
Agent:     claude
Created:   2026-04-24 09:12:03
Updated:   2026-05-14 18:05:21
Path:      /home/warren/ai-workspaces/projects/2026-04-24_promptvolley-v3

Session:      active
  Mode:       persistent
  Owner:      pid 48291
  Attach:     ctask attach promptvolley-v3

Launch dir: promptvolley-v3/
Launch path: /home/warren/.../2026-04-24_promptvolley-v3/promptvolley-v3
Dir exists: yes

Contents:
  .ctask/
  .git/
  CLAUDE.md
  ...

Flags: (none)

Notes:

  • Resolves archived workspaces by default — the Status: line shows whether the workspace is active or archived. No --all flag needed.
  • The Session: block is derived from the lease file (no tmux invocation, no PID liveness checks). Possible states: none, active, stale. Hostname is omitted when it matches the local machine.
  • Attach: hint appears only for active+persistent sessions.
  • For an archived workspace with a stranded lease (rare; theoretically possible after a crash), info will still surface the raw session state because info is the diagnostic command. list collapses archived workspaces to a dash for simplicity.

Related: ctask list, ctask path, ctask notes.


ctask list

Purpose: List workspaces in reverse-chronological order.

Usage:

ctask list [flags]

Scenarios:

  • Surveying active work.
  • Finding the basename to feed into another command.
  • Driving shell scripting via --names.

Examples:

$ ctask list
active  persistent  project  local  projects  2026-04-24  promptvolley-v3
active  direct      task     local  general   2026-05-14  fix-auth-bug
active  —           task     local  general   2026-05-12  json-cleanup

$ ctask list --names
2026-04-24_promptvolley-v3
2026-05-14_fix-auth-bug
2026-05-12_json-cleanup

Flags:

  • --all, -a — include archived workspaces.
  • --task — show task workspaces only.
  • --projects — show project workspaces only. Mutually exclusive with --task.
  • --category, -c — filter by category.
  • --limit, -n — maximum entries to show. Default: 20.
  • --names — emit one workspace directory basename per line, no header. Used by shell completion and scripting.

Notes:

  • Output columns (default mode): status, session, type, mode, category, date, slug. The session column shows direct, persistent, stale, or em dash for no session. Archived workspaces always show em dash in the session column (a display simplification — see info for the raw state).
  • --names output is intentionally minimal: bare basenames, no header, empty stdout when nothing matches. Every emitted line is guaranteed to resolve to exactly one workspace under the same archive policy.
  • Workspaces created before v0.3 (no type field) are treated as tasks.

Related: ctask info, ctask path, ctask completion.


ctask notes

Purpose: Print a workspace's notes.md to stdout.

Usage:

ctask notes <query>

Scenarios:

  • Quick read of working context without cd-ing into the workspace.
  • Piping notes into pagers, search tools, or other agents.

Examples:

$ ctask notes auth-bug | less
$ ctask notes promptvolley-v3 | grep -i "decision"

Flags: (none)

Notes:

  • Resolves archived workspaces too, mirroring info's archive-inclusive lookup.
  • If notes.md is missing, prints [ctask] no notes.md found in workspace "<query>" to stderr and exits non-zero.

Related: ctask info, ctask path.


ctask path

Purpose: Print the absolute filesystem path of a workspace, with a trailing newline. Designed for shell pipelines.

Usage:

ctask path <query>

Scenarios:

  • cd "$(ctask path auth-bug)"
  • Feeding the path to other tools (rg, fd, editors).

Examples:

$ ctask path auth-bug
/home/warren/ai-workspaces/general/2026-05-14_fix-auth-bug

Flags: (none)

Notes:

  • Resolves archived workspaces too.
  • Output uses native path separators (backslashes on Windows).

Related: ctask open, ctask info.


Lifecycle

ctask archive

Purpose: Mark a workspace as archived. The workspace stays on disk but is hidden from default listings and most query resolution.

Usage:

ctask archive <query>

Scenarios:

  • Putting a workspace away when the task is complete.
  • Reducing default-listing noise.

Examples:

$ ctask archive auth-bug
[ctask] archived: general/2026-05-14_fix-auth-bug

Flags: (none)

Notes:

  • Refuses to archive a workspace with an active session (fresh lease) on non-TTY stdin. On a TTY, prompts for confirmation.
  • After archiving, use ctask list --all to see archived workspaces and ctask restore to bring one back.

Related: ctask restore, ctask list --all, ctask delete.


ctask restore

Purpose: Un-archive a workspace (set status back to active).

Usage:

ctask restore <query>

Scenarios:

  • Resuming work on a previously archived task or project.

Examples:

$ ctask restore old-task
[ctask] restored: general/2026-04-22_old-task
[ctask] status: active

Flags: (none)

Notes:

  • Errors if the target workspace is already active.
  • Mirrors archive's active-session lease guard: refuses on non-TTY, prompts on TTY.
  • Tab completion for restore surfaces archived workspaces only.

Related: ctask archive, ctask list --all.


ctask delete

Purpose: Permanently remove a workspace directory.

Usage:

ctask delete <query> [flags]

Scenarios:

  • Reclaiming space from workspaces that are no longer needed.
  • Removing accidentally created or trivial workspaces.

Examples:

$ ctask delete --force throwaway

Flags:

  • --force, -f — skip the confirmation prompt.
  • --all, -a — include archived workspaces in query resolution.

Notes:

  • Confirmation is required by default. --force skips it but does NOT override the active-session guard.
  • Refuses to delete the workspace currently exported via CTASK_WORKSPACE (catches same-session attempts) and refuses any workspace with .ctask/manifest-start.json present (catches cross-terminal attempts). Exit the session first.
  • Prints a note before confirmation when deleting the most recently updated workspace.

Related: ctask archive (the safer alternative for completed work).


Environment

ctask doctor

Purpose: Verify ctask is correctly set up. Read-only.

Usage:

ctask doctor

Scenarios:

  • First-run sanity check after install.
  • Diagnosing a misconfigured agent, missing seed dir, or tmux problems.

Examples:

$ ctask doctor
  [PASS] Workspace root exists: /home/warren/ai-workspaces
  [PASS] Default agent found: claude
  [PASS] Status line helper found: /home/warren/.local/bin/ctask-statusline.sh
  [PASS] Claude Code status line configured
  [PASS] Workspaces found: 7 tasks (2 archived)
  [INFO] General seed directory: not configured (using built-in defaults)
  [INFO] Project seed directory: not configured (using built-in defaults)
  [INFO] CTASK_PROJECT_ROOT: not set (projects discovered under /home/warren/ai-workspaces/projects)
  [INFO] Session mode: persistent
  [INFO] tmux found: tmux 3.4 (/usr/bin/tmux)

  10 checks passed, 0 failed

Flags: (none)

Notes:

  • Exits 0 on all-pass, 1 if any check fails.
  • Each [FAIL] row includes a concrete fix line.
  • Persistent-mode hosts also see two tmux rows; direct-mode hosts see a single [INFO] Session mode: direct (tmux not required) row.

Related: ctask completion, Session modes.


ctask completion

Purpose: Emit shell-completion scripts for bash, zsh, fish, or PowerShell.

Usage:

ctask completion {bash | zsh | fish | powershell}

Scenarios:

  • Setting up tab completion in your shell so workspace names complete automatically.

Examples:

# bash, current shell only
$ source <(ctask completion bash)

# zsh, persistent
$ ctask completion zsh > "${fpath[1]}/_ctask"

# PowerShell, persistent
PS> ctask completion powershell | Out-String | Invoke-Expression

Flags: (none — the shell is a positional argument.)

Notes:

  • See Shell completion for installation patterns per shell.
  • Workspace name completion is provided via Cobra ValidArgsFunction hooks: resume/open/attach complete on active workspaces, restore completes on archived workspaces, info/notes/path complete on any workspace.

Related: ctask list --names.


Environment variables

ctask reads these to configure behavior:

Variable Default Description
CTASK_ROOT ~/ai-workspaces (Unix) / %USERPROFILE%\ai-workspaces (Windows) Workspace root directory.
CTASK_PROJECT_ROOT (none) Workspace root for project workspaces. When set, projects go directly under this path with no projects/ segment unless -c is also passed.
CTASK_AGENT claude Default agent command.
CTASK_SEED_DIR ~/.config/ctask/seed/ (Unix) / %APPDATA%\ctask\seed\ (Windows) General user seed directory copied into every new workspace.
CTASK_SEED_PROJECT_DIR ~/.config/ctask/seed-project/ (Unix) / %APPDATA%\ctask\seed-project\ (Windows) Project seed directory copied only for --project workspaces (overlay on top of the general seed).
CTASK_SESSION_MODE direct direct or persistent. See Session modes.

ctask exports these into every child session:

Variable Description
CTASK_TASK Workspace slug.
CTASK_MODE Execution mode (currently always local).
CTASK_ROOT Resolved workspace root path.
CTASK_WORKSPACE Full workspace path.
CTASK_CATEGORY Category name.
CTASK_TYPE task or project.
CTASK_LAUNCH_DIR Project subdirectory; empty for tasks and pre-v0.5 projects.

Query resolution

Commands that take a <query> argument resolve workspaces in this order:

  1. Exact directory basename match (e.g. 2026-05-14_fix-auth-bug).
  2. Exact slug match (e.g. fix-auth-bug).
  3. Case-insensitive substring match against the slug (e.g. auth).

If multiple workspaces match, ctask prints all matches and exits with an error. If none match, ctask prints No workspace matches "<query>". and exits with an error.

Archive-inclusive lookup: Some commands resolve archived workspaces by default — info, notes, path, restore, and resume. Of those, resume refuses to launch the archived workspace and prints a restore hint. The other archive-inclusive commands operate on the archived workspace as you would expect.

open, delete, and a few others gate archive inclusion behind --all. archive itself is active-only by definition.

Search roots: Queries always search $CTASK_ROOT plus $CTASK_PROJECT_ROOT when set. When CTASK_PROJECT_ROOT is unset, $CTASK_ROOT/projects/ is searched as well, so projects created with the default category are discoverable from any shell without additional configuration.


Session modes

ctask supports two session modes, selected by CTASK_SESSION_MODE:

  • direct (default) — the agent or shell is the foreground process of the ctask invocation. When the terminal closes, the agent exits. This is the v0.4 behavior.
  • persistent — workspace entry runs inside a deterministic per-workspace tmux session named ctask-<category>-<slug>-<hash6>. Multiple terminals (local + SSH) can attach to the same session, and the agent survives terminal disconnection.

Persistent mode requires:

  • tmux 3.0+ on PATH.
  • An interactive terminal (over SSH, use ssh -t).
  • Not running inside an existing tmux session (the $TMUX env var must be unset).
  • A Unix-like host or WSL — native Windows is not supported.

When you run a persistent-mode entry command (new, resume, last, open, or attach), ctask picks one of three paths:

  1. Owner-create — no tmux session exists for this workspace. ctask launches the agent inside a new tmux session and starts a lease and heartbeat. Equivalent to direct-mode entry plus a tmux wrapper.
  2. Passive reattach — a tmux session exists and a fresh local lease is heartbeating. ctask attaches the user's terminal to the existing session and exits when the user detaches. No lease writes, no manifest, no finalize — the original ctask owner is still managing the workspace.
  3. Adopted reattach — a tmux session exists but the lease is missing, stale, or from another host (the original owner died). ctask transfers ownership to itself, captures a fresh start manifest, starts heartbeating, attaches the terminal, and runs finalize when the session ends.

new, resume, last, and open accept --direct to bypass persistent mode for one invocation. When a persistent tmux session exists for the workspace, ctask prompts the user to confirm. --direct is a no-op under direct mode (allows scripts to use it defensively).

ctask attach always uses persistent mode regardless of CTASK_SESSION_MODE.

ctask doctor validates session-mode prerequisites and reports tmux availability.


Shell completion

ctask completion <shell> writes a Cobra-generated completion script to stdout. Install it once per shell:

bash (system-wide):

ctask completion bash > /etc/bash_completion.d/ctask

bash (per-user, current session):

source <(ctask completion bash)

zsh (assuming compinit and an fpath directory):

ctask completion zsh > "${fpath[1]}/_ctask"

fish:

ctask completion fish > ~/.config/fish/completions/ctask.fish

PowerShell (current session):

ctask completion powershell | Out-String | Invoke-Expression

PowerShell (persistent — append to your profile):

ctask completion powershell >> $PROFILE

Once installed, tab completion works on workspace-name arguments. The completion source is ctask list --names, filtered per command: resume/open/attach show active workspaces only, restore shows archived workspaces only, and info/notes/path show all.


Exit codes

Code Meaning
0 Success.
1 General error (multiple matches, not found, invalid args, doctor failure, refusal).
2 Missing required argument (Cobra default).
127 Agent command not found.