# 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](#workspace-layout) - [Workspace creation and entry](#workspace-creation-and-entry) - [`ctask new`](#ctask-new) - [`ctask resume`](#ctask-resume) - [`ctask last`](#ctask-last) - [`ctask open`](#ctask-open) - [`ctask attach`](#ctask-attach) - [Inspection](#inspection) - [`ctask info`](#ctask-info) - [`ctask list`](#ctask-list) - [`ctask notes`](#ctask-notes) - [`ctask path`](#ctask-path) - [Lifecycle](#lifecycle) - [`ctask archive`](#ctask-archive) - [`ctask restore`](#ctask-restore) - [`ctask delete`](#ctask-delete) - [Environment](#environment) - [`ctask doctor`](#ctask-doctor) - [`ctask completion`](#ctask-completion) - [Environment variables](#environment-variables) - [Query resolution](#query-resolution) - [Session modes](#session-modes) - [Shell completion](#shell-completion) - [Exit codes](#exit-codes) --- ## 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: "" ├── CLAUDE.md ├── notes.md ├── .git/ # single git repo at workspace root ├── .gitignore # excludes .ctask/ and logs/sessions.log ├── / # 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 [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](#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 [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 [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](#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 **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 **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 ""` 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 **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 **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 **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 [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`](#ctask-completion), [Session modes](#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](#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`](#ctask-list). --- ## 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](#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 `` 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 "".` 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---`. 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 ` 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. |