# ctask CLI Specification (v0.1) ## Global Options ``` ctask [command] [options] [arguments] ctask -h | --help ctask --version ``` ## Commands --- ### `ctask new [title]` Create a new task workspace and launch the agent. ``` ctask new [title] [options] ``` **Arguments:** - `title` — Human-readable task name (optional). If omitted, generates `task-HHMMSS`. **Options:** | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--category` | `-c` | `general` | Workspace category subdirectory | | `--container` | | off | Launch in container sandbox (v0.2 — prints notice in v0.1) | | `--shell` | | off | Open interactive shell instead of agent | | `--agent` | `-a` | `claude` | Command to exec as the agent | | `--no-launch` | | off | Create workspace only, do not launch | **Behavior:** - `new` always creates a fresh workspace. If a workspace with the same date+slug exists, append `-2`, `-3`, etc. - Slugs are derived from the title: lowercase, non-alphanumeric replaced with hyphens, trimmed - Workspace created at `$CTASK_ROOT//_/` - Seed files written only if they do not already exist **Examples:** ```bash # Basic — creates workspace, launches claude ctask new "arch notes" # With category ctask new -c scripts "backup helper" # Container mode ctask new --container -c risky "unknown installer" # Shell instead of agent ctask new --shell "test env" # Create workspace but don't launch anything ctask new --no-launch "json cleanup" # Use aider instead of claude ctask new --agent aider "refactor api" # Auto-generated name ctask new ``` **Output:** ``` [ctask] created general/2026-04-05_arch-notes [ctask] local :: arch-notes [ctask] ~/ai-workspaces/general/2026-04-05_arch-notes ``` --- ### `ctask list` Show recent workspaces in reverse-chronological order. ``` ctask list [options] ``` **Options:** | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--all` | `-a` | off | Include archived workspaces | | `--category` | `-c` | all | Filter by category | | `--limit` | `-n` | 20 | Maximum entries to show | **Output format:** ``` active local general 2026-04-05 arch-notes active container risky 2026-04-04 unknown-installer active local scripts 2026-04-03 backup-helper ``` Columns: status, mode, category, date, slug. **Examples:** ```bash # Recent workspaces ctask list # Only scripts category ctask list -c scripts # Include archived ctask list --all # Last 5 ctask list -n 5 ``` --- ### `ctask resume ` Reopen an existing workspace and launch the agent. ``` ctask resume [options] ``` **Arguments:** - `query` — Workspace slug, partial name, or full directory name (required) **Options:** | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--container` | | off | Resume in container mode (v0.2 — prints notice in v0.1) | | `--shell` | | off | Open shell instead of agent | | `--agent` | `-a` | from task.yaml | Override agent command | **Resolution:** 1. Exact directory name match under `$CTASK_ROOT/*/*` → use it 2. Exact slug match (portion after date prefix) → use it 3. Case-insensitive substring match against slug → use if unique 4. Multiple matches → print all matches and exit 1 5. No matches → error and exit 1 Archived workspaces are excluded from matching by default. **Behavior:** - Updates `updated_at` in `task.yaml` - Sets environment variables - Prints launch banner - Execs agent or shell **Examples:** ```bash # Resume by slug ctask resume arch-notes # Resume by partial match ctask resume backup # Resume by full directory name ctask resume 2026-04-05_arch-notes # Resume in container mode (even if originally local) ctask resume --container arch-notes # Resume with shell ctask resume --shell arch-notes ``` **On multiple matches:** ``` Multiple workspaces match "notes": general/2026-04-05_arch-notes research/2026-04-03_migration-notes Specify a more precise query. ``` --- ### `ctask open ` Open a workspace directory without launching the agent. ``` ctask open [options] ``` **Options:** | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--all` | `-a` | off | Include archived workspaces in query resolution | **Behavior:** - Resolves workspace (same rules as `resume`) - Updates `updated_at` - Sets environment variables - Spawns a new interactive subshell in the workspace directory with ctask prompt prefix - Does NOT launch the agent - Does NOT mutate the caller's existing shell session — this is a subshell, not a `cd` This is equivalent to `ctask resume --shell ` but reads more naturally for "I just want to look at the files." **Examples:** ```bash # Open workspace in shell ctask open arch-notes ``` --- ### `ctask info ` Display metadata and path for a workspace without entering it. ``` ctask info [options] ``` **Options:** | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--all` | `-a` | off | Include archived workspaces in query resolution | **Output:** ``` Task: arch-notes Title: arch notes Category: general Status: active Mode: local Agent: claude Created: 2026-04-05 14:30:22 Updated: 2026-04-05 15:12:00 Path: ~/ai-workspaces/general/2026-04-05_arch-notes Contents: task.yaml CLAUDE.md notes.md context/ output/ logs/ ``` **Examples:** ```bash ctask info arch-notes ctask info backup ``` --- ### `ctask archive ` Mark a workspace as archived. ``` ctask archive ``` **Behavior:** - Resolves workspace (same rules as `resume`) - Sets `status: archived` and `archived_at` timestamp in `task.yaml` - Workspace stays in place (not moved or deleted) - Archived workspaces are hidden from `ctask list` unless `--all` is passed **Examples:** ```bash ctask archive arch-notes ctask archive 2026-04-03_backup-helper ``` **Output:** ``` [ctask] archived: general/2026-04-05_arch-notes ``` --- ## Environment Variables ### Set by ctask (exported into every child session) | Variable | Example | Description | |----------|---------|-------------| | `CTASK_TASK` | `arch-notes` | Task slug | | `CTASK_MODE` | `local` | Execution mode | | `CTASK_ROOT` | `/home/warren/ai-workspaces` | Resolved workspace root (absolute path) | | `CTASK_WORKSPACE` | `/home/warren/ai-workspaces/general/2026-04-05_arch-notes` | Full workspace path | | `CTASK_CATEGORY` | `general` | Category | ### Read by ctask (user-configurable input) | Variable | Default | Description | |----------|---------|-------------| | `CTASK_ROOT` | `~/ai-workspaces` (Unix) or `%USERPROFILE%\ai-workspaces` (Windows) | Workspace root directory | | `CTASK_AGENT` | `claude` | Default agent command | **Implementation note on `CTASK_ROOT`:** ctask reads the caller's `CTASK_ROOT` as config input (may contain `~` or relative path), resolves it to an absolute path, then exports the resolved value into the child process environment. The child session always sees a fully resolved absolute path. --- ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | General error (multiple matches, not found, invalid args) | | 2 | Missing required argument | | 127 | Agent command not found | --- ## Shell Prompt Behavior ### In `--shell` mode Ephemeral `PS1` prefix, no permanent config changes: ``` (ctask:arch-notes|local) warren@host:~/ai-workspaces/general/2026-04-05_arch-notes$ ``` ### In agent mode Banner printed before exec: ``` [ctask] local :: arch-notes [ctask] ~/ai-workspaces/general/2026-04-05_arch-notes ``` --- ## Container Mode (Deferred to v0.2) The `--container` flag is accepted but prints a notice that container mode is not yet available in v0.1. This keeps the CLI interface stable so users and scripts don't need to change when container support lands. ``` [ctask] container mode is not available in v0.1. Use local mode or see docs for manual container setup. ``` Design intent for v0.2: persistent named container, Podman-first (Docker fallback), Claude Code only inside container. See MVP contract for details. --- ## Status Line Integration ### Claude Code status line ctask ships a small helper script for Claude Code's status line feature. When ctask environment variables are set, it renders session context at the bottom of the Claude Code UI. **Setup** (add to `~/.claude/settings.json`): ```json { "statusLine": { "type": "command", "command": "bash /path/to/ctask-statusline.sh" } } ``` On Windows, use the PowerShell variant: ```json { "statusLine": { "type": "command", "command": "powershell -NoProfile -File C:\\path\\to\\ctask-statusline.ps1" } } ``` **Output when in a ctask session:** ``` (ctask:arch-notes|local) ~/ai-workspaces/general/2026-04-05_arch-notes ``` **Output when NOT in a ctask session:** empty (no output, falls through gracefully). ### Fallback for non-Claude agents The ephemeral shell prompt prefix (`PS1` on Unix, `PROMPT` on Windows) in `--shell` mode provides session context for any tool that doesn't support a dedicated status line.