docs(v0.5.1): record v0.5.1 completion; check in v0.5.2 spec
Update notes.md with the v0.5.1 Linux portability baseline (commits7a7b249,1033072): WSL-native validation passed, install.sh works, ctask doctor recognizes the Linux statusline helper, the cross-built Linux binary is statically linked, and WorkspacePath was removed from new task.yaml metadata. Add load-bearing notes for the new invariants (CGO_ENABLED=0, install script does not modify shell config) and a "Next: v0.5.2" pointer. Also check in v0.5.2-spec.md so the workspace-retrieval round has the same on-disk durability as the prior specs.
This commit is contained in:
+390
@@ -0,0 +1,390 @@
|
||||
# ctask v0.5.2 Spec — Workspace Retrieval and Cross-Workspace Context
|
||||
|
||||
## Theme
|
||||
|
||||
v0.1 = create and resume workspaces
|
||||
v0.2 = understand and continue workspaces later
|
||||
v0.3 = personalize workspaces and support longer-lived project work
|
||||
v0.4 = protect workspaces from concurrent session conflicts
|
||||
v0.5 = separate workspace management from project code
|
||||
v0.5.1 = ctask runs correctly on Linux (WSL and Docker)
|
||||
v0.5.2 = workspaces are discoverable, retrievable, and inspectable across sessions
|
||||
|
||||
## Problem
|
||||
|
||||
Four usability gaps discovered through real usage:
|
||||
|
||||
1. **Archived workspaces are a dead end.** `ctask archive` sets metadata and hides the workspace from default listing, but there is no `ctask restore` to bring it back. Users who archive prematurely must recreate the workspace and manually copy notes.md.
|
||||
|
||||
2. **Archived workspaces are invisible to direct lookup.** `ctask info <workspace>` does not find archived workspaces unless the user passes `-a`. Archived workspaces are still workspaces — users expect to look them up by name.
|
||||
|
||||
3. **No cross-workspace context access.** When an AI agent works in one workspace, it has no way to read the notes or location of another workspace. Prior work is invisible unless the user manually copies content. ctask should expose workspace context through CLI commands that agents can call.
|
||||
|
||||
4. **No shell autocompletion.** Workspace names can be long and detailed. Users must type them in full or rely on shell history. Since ctask knows what workspaces exist and uses Cobra, autocompletion should be available.
|
||||
|
||||
## Design Principles
|
||||
|
||||
Two rules govern this spec:
|
||||
|
||||
**Listing is filtered. Direct lookup is comprehensive.** `ctask list` shows active workspaces by default to keep output clean. Commands that accept a workspace name — `info`, `notes`, `path`, `restore` — search active and archived workspaces because the user asked for a specific workspace by name.
|
||||
|
||||
**ctask exposes workspace context through CLI commands. Agents consume it themselves.** ctask does not inject context into agent sessions, manage agent memory, or maintain a central knowledge base. It provides commands that print useful text to stdout. Agents (Claude Code or otherwise) can call these commands and read the output. This keeps ctask agent-agnostic and in its lane as a workspace manager.
|
||||
|
||||
## Scope
|
||||
|
||||
1. `ctask restore <workspace>` — un-archive a workspace
|
||||
2. `ctask notes <workspace>` — print another workspace's notes.md
|
||||
3. `ctask path <workspace>` — print the absolute path of a workspace
|
||||
4. Archived-inclusive direct lookup for `info` (and other direct-lookup commands)
|
||||
5. `ctask list --names` — machine-readable workspace enumeration
|
||||
6. `ctask completion <shell>` — shell autocompletion
|
||||
7. Updated CLAUDE.md seed text for cross-workspace awareness
|
||||
|
||||
---
|
||||
|
||||
## Workspace Lookup Policy
|
||||
|
||||
The resolver (`resolveOne` → `ResolveQuery`) already supports an `includeArchived` boolean. This spec standardizes how each command sets it.
|
||||
|
||||
### Active-only lookup
|
||||
|
||||
These commands operate on active workspaces. Looking up an archived workspace would be an error.
|
||||
|
||||
```
|
||||
ctask resume <workspace> active only (archived → error with restore hint)
|
||||
ctask archive <workspace> active only
|
||||
```
|
||||
|
||||
### Archived-inclusive lookup
|
||||
|
||||
These commands read or inspect workspaces. The user asked for a specific workspace by name — don't pretend it doesn't exist because it's archived.
|
||||
|
||||
```
|
||||
ctask info <workspace> active + archived
|
||||
ctask notes <workspace> active + archived
|
||||
ctask path <workspace> active + archived
|
||||
ctask restore <workspace> active + archived (then require status == archived)
|
||||
```
|
||||
|
||||
### Active-only by default, with `--all` opt-in
|
||||
|
||||
These commands are destructive or start sessions. Defaulting to active-only is safer; `--all` allows explicit archived access.
|
||||
|
||||
```
|
||||
ctask delete <workspace> active only by default; archived allowed with --all/-a
|
||||
ctask open <workspace> active only by default; archived allowed with --all/-a
|
||||
```
|
||||
|
||||
### Implementation
|
||||
|
||||
For commands currently hardcoding `includeArchived=false` (`archive` at `cmd/archive.go:29`, `resume` at `cmd/resume.go:50`): no change needed, these are correct.
|
||||
|
||||
For `info` (`cmd/info.go:23`): remove the `--all/-a` flag and always resolve with `includeArchived=true`. The flag is not needed — `info` is a read-only lookup and should always find the workspace the user asked for.
|
||||
|
||||
For `delete` and `open`: keep their existing `--all/-a` flags with current defaults (active-only). No change needed.
|
||||
|
||||
### Resume behavior for archived workspaces
|
||||
|
||||
When a user runs `ctask resume <archived-workspace>`, the command should fail with a helpful message:
|
||||
|
||||
```
|
||||
[ctask] error: workspace "promptvolley-v2" is archived
|
||||
|
||||
To restore it:
|
||||
ctask restore promptvolley-v2
|
||||
```
|
||||
|
||||
This keeps archive and restore as intentional lifecycle actions, not something that happens silently through resume.
|
||||
|
||||
**Implementation note:** `resume` currently resolves with `includeArchived=false`, so it won't find archived workspaces at all — it just reports "not found." To provide the restore hint, change `resume` to resolve with `includeArchived=true`, then check the result's status. If the workspace is active, proceed normally. If archived, print the hint and exit. This way the user gets a specific, actionable message instead of a generic "not found" error.
|
||||
|
||||
---
|
||||
|
||||
## 1. `ctask restore <workspace>`
|
||||
|
||||
### Behavior
|
||||
|
||||
```bash
|
||||
ctask restore promptvolley-v2
|
||||
```
|
||||
|
||||
Resolves the workspace using archived-inclusive lookup, then:
|
||||
|
||||
- Verify the workspace status is `archived`. If it's already active, print an error: `workspace "promptvolley-v2" is already active`
|
||||
- Check for an active session lease (mirror the guard in `ctask archive`). If a lease is held, refuse with an appropriate message
|
||||
- Set `status: active` in task.yaml. Write the value explicitly — do not omit the field or set it to empty string, even if older code treats empty status as active
|
||||
- Clear `archived_at` (set to zero value / omit from YAML)
|
||||
- Update `updated_at` to current time
|
||||
- Write task.yaml
|
||||
- Print confirmation:
|
||||
|
||||
```
|
||||
[ctask] restored: projects/2026-04-24_promptvolley-v2
|
||||
[ctask] status: active
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
- Restore is metadata-only. No directory moves, no file changes beyond task.yaml
|
||||
- Restoring does not start a session. The user runs `ctask resume` afterward if they want to work in it
|
||||
- If a workspace with the same slug exists in active status (edge case: user archived one, created a new one with the same name), the resolver will find both. The resolver's existing ambiguity handling applies — it should report the conflict and ask the user to use the full name
|
||||
|
||||
### What restore does NOT do
|
||||
|
||||
- Does not launch an agent
|
||||
- Does not regenerate CLAUDE.md or any seed files
|
||||
- Does not modify notes.md, context/, or any workspace content
|
||||
- Does not create a session log entry (no session is started)
|
||||
|
||||
---
|
||||
|
||||
## 2. `ctask notes <workspace>`
|
||||
|
||||
### Behavior
|
||||
|
||||
```bash
|
||||
ctask notes promptvolley-v2
|
||||
```
|
||||
|
||||
Resolves the workspace using archived-inclusive lookup, then prints the contents of `notes.md` to stdout.
|
||||
|
||||
```bash
|
||||
# Equivalent to:
|
||||
cat "$(ctask path promptvolley-v2)/notes.md"
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
- Output is the raw contents of notes.md, no framing or decoration. This makes it directly consumable by agents reading stdout
|
||||
- If notes.md does not exist in the workspace, print a clear message to stderr and exit with a non-zero code: `[ctask] no notes.md found in workspace "promptvolley-v2"`
|
||||
- If the workspace is not found, the resolver's existing error handling applies
|
||||
- Works on both active and archived workspaces
|
||||
|
||||
### Why stdout matters
|
||||
|
||||
The primary consumer of this command is an AI coding agent running `ctask notes <workspace>` via shell. The agent reads stdout to get context from prior work. Keeping the output clean (no banners, no status lines) means the agent gets exactly the document content with no parsing needed. Informational messages go to stderr.
|
||||
|
||||
---
|
||||
|
||||
## 3. `ctask path <workspace>`
|
||||
|
||||
### Behavior
|
||||
|
||||
```bash
|
||||
ctask path promptvolley-v2
|
||||
```
|
||||
|
||||
Resolves the workspace using archived-inclusive lookup, then prints the absolute filesystem path to stdout.
|
||||
|
||||
```
|
||||
C:\Users\Warren\ai-workspaces\projects\2026-04-24_promptvolley-v2
|
||||
```
|
||||
|
||||
or on Linux:
|
||||
|
||||
```
|
||||
/home/warren/ai-workspaces/projects/2026-04-24_promptvolley-v2
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
- Output is a single line: the absolute, OS-native filesystem path. No trailing newline decoration, no framing
|
||||
- The path uses native separators (backslashes on Windows, forward slashes on Linux). This is the real filesystem path, not a display identifier
|
||||
- Works on both active and archived workspaces
|
||||
- This is `QueryResult.Path` — already available from the resolver, no new logic needed
|
||||
|
||||
### Use case
|
||||
|
||||
An agent that needs to inspect files in another workspace can run `ctask path <workspace>` and then read files at that location. Combined with `ctask notes`, this gives agents full read access to prior workspace context through standard shell commands.
|
||||
|
||||
---
|
||||
|
||||
## 4. `ctask info` — Archived-Inclusive by Default
|
||||
|
||||
### Current behavior
|
||||
|
||||
`ctask info <workspace>` requires `--all` or `-a` to find archived workspaces. Without the flag, an archived workspace is reported as not found.
|
||||
|
||||
### New behavior
|
||||
|
||||
`ctask info <workspace>` finds the workspace whether it is active or archived. If the workspace is archived, the info output should include the status clearly:
|
||||
|
||||
```
|
||||
Task: promptvolley-v2
|
||||
Title: promptvolley-v2
|
||||
Category: projects
|
||||
Status: archived
|
||||
...
|
||||
Archived: 2026-05-01 14:30:00
|
||||
```
|
||||
|
||||
### Implementation
|
||||
|
||||
Change `cmd/info.go` so that the resolver call uses `includeArchived=true` unconditionally. Remove the `--all/-a` flag from `info` — it is no longer needed since `info` always searches comprehensively.
|
||||
|
||||
### Why this is correct
|
||||
|
||||
The user typed a specific workspace name. They know it exists. Telling them "not found" because it happens to be archived is unhelpful and forces them to guess at the flag. The principle: listing is filtered, direct lookup is comprehensive.
|
||||
|
||||
---
|
||||
|
||||
## 5. `ctask list --names`
|
||||
|
||||
### Behavior
|
||||
|
||||
```bash
|
||||
ctask list --names
|
||||
```
|
||||
|
||||
Outputs one workspace directory basename per line, no headers, no table formatting:
|
||||
|
||||
```
|
||||
2026-04-24_promptvolley-v2
|
||||
2026-04-22_litlink-v2
|
||||
2026-05-07_linux-test
|
||||
```
|
||||
|
||||
```bash
|
||||
ctask list --names --all
|
||||
```
|
||||
|
||||
Includes archived workspaces in the output.
|
||||
|
||||
### Rules
|
||||
|
||||
- One directory basename per line (e.g., `2026-04-24_promptvolley-v2`, not the bare slug `promptvolley-v2`). Basenames are unambiguous — bare slugs can collide across categories or dates
|
||||
- What `list --names` outputs, other commands accept as input. The resolver already accepts exact directory basenames
|
||||
- Respects existing filters: `--all`, `--archived`, `--projects`, or whatever category/status filters `list` currently supports
|
||||
- No additional decoration: no dates, no status, no categories. This is for machine consumption
|
||||
- If no workspaces match, output nothing (empty stdout, zero exit code)
|
||||
|
||||
### Why this exists
|
||||
|
||||
Shell completion scripts and external tooling need a stable, parseable enumeration of workspace names. While Cobra's `ValidArgsFunction` can enumerate internally, `list --names` serves agents, shell scripts, and any future integration that needs to discover workspaces without importing ctask's Go code.
|
||||
|
||||
---
|
||||
|
||||
## 6. `ctask completion <shell>`
|
||||
|
||||
### Behavior
|
||||
|
||||
```bash
|
||||
ctask completion powershell
|
||||
ctask completion bash
|
||||
ctask completion zsh
|
||||
ctask completion fish
|
||||
```
|
||||
|
||||
Outputs the completion script for the specified shell. The user sources it in their shell profile.
|
||||
|
||||
### Implementation
|
||||
|
||||
Cobra provides built-in completion generation. The implementation is:
|
||||
|
||||
- Enable Cobra's completion command (or add a thin wrapper if customization is needed)
|
||||
- Add `ValidArgsFunction` hooks to every command that accepts a workspace name argument
|
||||
|
||||
### `ValidArgsFunction` hooks
|
||||
|
||||
Each command gets a completion function that enumerates workspace candidates appropriate to that command's lookup policy:
|
||||
|
||||
```
|
||||
resume: active workspaces only
|
||||
archive: active workspaces only
|
||||
restore: archived workspaces only
|
||||
info: active + archived
|
||||
notes: active + archived
|
||||
path: active + archived
|
||||
delete: active workspaces only (flag-aware completion for --all can come later)
|
||||
open: active workspaces only (flag-aware completion for --all can come later)
|
||||
```
|
||||
|
||||
The completion function calls the workspace listing logic internally (no shell-out to `ctask list`). A shared helper should enumerate slugs with a configurable status filter to avoid duplicating logic across commands.
|
||||
|
||||
### PowerShell completion
|
||||
|
||||
PowerShell is the primary shell on Windows. The user adds the output of `ctask completion powershell` to their `$PROFILE`. Tab-cycling through candidates works natively with PowerShell's completion system.
|
||||
|
||||
### Bash/Zsh completion
|
||||
|
||||
For WSL and Linux environments. The user sources the script in `.bashrc` or `.zshrc`. This also benefits the workflow where the developer SSHs into a container and uses ctask there.
|
||||
|
||||
### Rules
|
||||
|
||||
- Completion scripts are generated, not maintained by hand. Cobra handles the shell-specific syntax
|
||||
- The `completion` command itself does not require workspace resolution — it is a utility command
|
||||
- Fish completion is included for free via Cobra. No extra work, but no need to test extensively unless a real user needs it
|
||||
|
||||
---
|
||||
|
||||
## 7. CLAUDE.md Seed Text Update
|
||||
|
||||
### Current state
|
||||
|
||||
ctask seeds a CLAUDE.md into each workspace with workspace management instructions. This text does not mention cross-workspace context access.
|
||||
|
||||
### Addition
|
||||
|
||||
Add the following section to the built-in CLAUDE.md template used during workspace creation:
|
||||
|
||||
```markdown
|
||||
## Cross-Workspace Context
|
||||
|
||||
Related work may exist in other ctask workspaces. For project continuation,
|
||||
migration, debugging, or building on prior work, inspect related workspaces
|
||||
before making changes.
|
||||
|
||||
Available commands:
|
||||
|
||||
ctask list --all discover all workspaces (including archived)
|
||||
ctask info <workspace> view metadata and status of any workspace
|
||||
ctask notes <workspace> read another workspace's notes.md
|
||||
ctask path <workspace> get the filesystem path to inspect files directly
|
||||
|
||||
Treat other workspaces as read-only unless the user explicitly asks you to
|
||||
modify them.
|
||||
```
|
||||
|
||||
### Rules
|
||||
|
||||
- This text is added to the seed template, not retroactively injected into existing workspaces
|
||||
- Users who have customized their seed directory will not see this text unless they add it themselves. This is expected — seeds are user-controlled
|
||||
- The text is concise. CLAUDE.md is loaded into the agent's context window at session start; long instructions waste context budget
|
||||
- The text is agent-agnostic. It references CLI commands, not Claude-specific features. If AGENTS.md is in use (v0.6), this section belongs there instead, with the CLAUDE.md shim pointing to it
|
||||
|
||||
---
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
- Existing workspaces are unaffected. No metadata changes, no layout changes
|
||||
- `ctask info` becomes more permissive (finds archived workspaces), which is strictly a UX improvement — no existing workflow breaks
|
||||
- `ctask list` default behavior is unchanged (active only). `--names` is additive
|
||||
- Existing CLAUDE.md files in workspaces are not modified. The new seed text only applies to newly created workspaces
|
||||
|
||||
## Non-Goals for v0.5.2
|
||||
|
||||
- `ctask find <query>` — full-text search across workspaces. Defer until list + notes proves insufficient
|
||||
- Claude-specific slash commands or skills files. Defer until the manual workflow proves itself
|
||||
- `list --json` — defer unless a real consumer needs structured output. `--names` covers the completion and scripting use case
|
||||
- Fuzzy or partial-match workspace resolution. The current resolver accepts exact slug, exact basename, and case-insensitive substring. That's sufficient
|
||||
- Modifying other workspaces via ctask commands. Cross-workspace access is read-only by design
|
||||
|
||||
## Build Order
|
||||
|
||||
1. Settle the lookup policy: update `info` to use `includeArchived=true` by default. Verify no tests assume the old default
|
||||
2. Implement `ctask restore` with archived-inclusive lookup and active-lease guard
|
||||
3. Implement `ctask notes` with archived-inclusive lookup and clean stdout output
|
||||
4. Implement `ctask path` with archived-inclusive lookup
|
||||
5. Update `ctask resume` to print a helpful restore hint when targeting an archived workspace
|
||||
6. Add `ctask list --names` with filter support
|
||||
7. Add `ctask completion` command and `ValidArgsFunction` hooks for all workspace-accepting commands
|
||||
8. Update CLAUDE.md seed template with cross-workspace context section
|
||||
9. Tests:
|
||||
- restore: archived workspace restored to active with explicit `status: active`, already-active workspace refused, lease guard respected, metadata updated correctly
|
||||
- notes: prints notes.md content, handles missing notes.md, works on archived workspace
|
||||
- path: prints absolute path, correct separators per OS, works on archived workspace
|
||||
- info: finds archived workspace without `-a` flag, flag removed
|
||||
- resume: archived workspace refused with restore hint (not generic "not found")
|
||||
- list --names: outputs directory basenames one per line, respects --all filter, empty output on no matches, no slug collisions
|
||||
- completion: generates valid shell scripts (smoke test — no need to test shell integration)
|
||||
10. Full test suite pass on both Windows and Linux
|
||||
Reference in New Issue
Block a user