docs: add v0.2 spec

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 10:05:27 -04:00
parent 69c487cf79
commit f967064331
5 changed files with 3603 additions and 0 deletions
+404
View File
@@ -0,0 +1,404 @@
# 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/<category>/<YYYY-MM-DD>_<slug>/`
- 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 <query>`
Reopen an existing workspace and launch the agent.
```
ctask resume <query> [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 <query>`
Open a workspace directory without launching the agent.
```
ctask open <query> [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 <query>` 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 <query>`
Display metadata and path for a workspace without entering it.
```
ctask info <query> [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 <query>`
Mark a workspace as archived.
```
ctask archive <query>
```
**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.