Add the v0.5.2 round summary (commits a5e508b..3b6be0d + 5910100):
restore/notes/path commands, direct-lookup archived-inclusive policy,
resume archived hint, list --names, shell completion, cross-workspace
context seed section. Windows + WSL validation passed; Linux binary
statically linked.
Add load-bearing v0.5.2 invariants to the "don't unlearn" section
(archived-inclusive lookup policy, list --names emits basenames not
slugs, completion calls ListWorkspaces directly, etc.). Replace the
"Next: v0.5.2" pointer with a "Next: v0.6 (planning)" stub covering
config/agent profile work, resume-error polish, and flag-aware
completion for open/delete --all.
Drop v0.5.2-spec.md from the untracked-files list (committed in a5e508b).
Adds a concise "## Cross-Workspace Context" section to both the
task and project CLAUDE.md seed templates. Teaches the agent to
inspect related workspaces with the new commands before making
changes:
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
Closes the v0.5.2 design loop: ctask exposes workspace context
through CLI commands and lets agents consume it themselves. The
seed text is read-only by convention — the section explicitly
asks the agent to treat other workspaces as read-only unless the
user grants modification rights.
Applies to newly created workspaces only. Existing workspaces
keep their current CLAUDE.md (per spec: no retroactive overwrite).
Users with custom seed directories see this only if they update
their seeds.
Adds a --names flag to ctask list that emits one workspace
directory basename per line, no header, no decoration. Empty
result is empty stdout with zero exit code (no "No workspaces
found." placeholder).
Used by shell completion scripts and external tooling. Candidates
are directory basenames rather than bare slugs because basenames
are unique under the resolver's exact-match step while slugs can
collide across categories or dates.
Respects existing list filters: --all, --task, --projects,
--category, --limit. So:
ctask list --names active workspaces only
ctask list --names --all active and archived
ctask list --names --projects active project workspaces
The new TestListNamesCandidatesResolveUniquely test enforces the
spec invariant: every line emitted by list --names must resolve
to exactly one workspace via the standard resolver.
Apply the v0.5.2 lookup policy to the existing commands and wire
ValidArgsFunction hooks across the workspace-accepting surface.
info: drop the --all/-a flag entirely. Direct lookup is now
archived-inclusive by default — the user typed a name, so we find
the workspace and surface its status in the output. The Status
line already distinguishes active vs archived clearly.
resume: when targeting an archived workspace, fail with a useful
hint instead of letting the resolver report "not found":
[ctask] error: workspace "X" is archived
To restore it:
ctask restore X
This is implemented by resolving archived-inclusive and rejecting
status==archived before any session-launch logic runs. Genuine
not-found and ambiguous-match behavior are unchanged.
Adds ValidArgsFunction hooks to archive (active), delete (active),
open (active), info (any), resume (active). Restore/notes/path
already have hooks from the previous commit. Shell completion now
covers the full direct-lookup surface.
Three new direct-lookup commands per v0.5.2-spec.md:
- ctask restore <ws> un-archive a workspace (metadata-only flip,
mirrors archive's lease guard, refuses to
restore an already-active workspace)
- ctask notes <ws> stream a workspace's notes.md to stdout (raw,
no framing, [ctask]-prefixed stderr on error)
so AI agents can read prior workspace context
through standard shell pipelines
- ctask path <ws> print the absolute filesystem path of a
workspace, OS-native separators, one line
All three resolve archived-inclusive: the user typed a name, so we
find the workspace whether or not it's archived. Listing stays
filtered (active-only by default) per the v0.5.2 design rule
"listing is filtered, direct lookup is comprehensive".
Adds shared completion infrastructure (cmd/completion.go) used by
these commands and wired into the existing workspace-accepting
commands in a follow-up commit. Candidates are workspace directory
basenames (e.g. 2026-04-22_promptvolley) rather than bare slugs
because basenames are unique under the resolver's exact-match step
while slugs can collide across categories or dates.
Update notes.md with the v0.5.1 Linux portability baseline (commits
7a7b249, 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.
A native Linux build of build-linux defaulted to CGO_ENABLED=1 and
produced a glibc-linked binary, which would not run in minimal
containers (Alpine, distroless, scratch). The Windows cross-compile
was already pure-Go because Go disables cgo when no host C toolchain
is available; making CGO_ENABLED=0 explicit keeps both targets
statically linked regardless of build host.
Verified on WSL: file reports "statically linked", ldd reports
"not a dynamic executable".
- justfile: add build-linux, build-windows, build-all (output to dist/)
- .gitignore: cover ctask, ctask-*, dist/
- scripts/install.sh + scripts/uninstall.sh: POSIX equivalents of .ps1
- remove WorkspacePath metadata field (no production readers; legacy
task.yaml files continue to parse silently)
Linux smoke-test on WSL/container pending.
See audit-report.md and v0.5.1-spec.md.
Workspace directory names (YYYY-MM-DD_slug) and the YYYYMMDD-HHMMSS ID
field now use local time so users see their wall-clock date rather
than UTC — the prior behavior caused evening-EST creations to appear
under tomorrow's date for several hours every day. ctask info's
Created/Updated/Archived lines also convert to local for display.
Stored timestamps in task.yaml, session logs, the lease, the manifest,
and the session summary all continue to use UTC. Only user-facing
surfaces change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the workspace-layout diagram to the --project section, describes
how launch_dir is set and overridden, and documents the v0.5 rules for
fallback (missing/not-a-dir) and error (absolute/escape). Adds
CTASK_LAUNCH_DIR to the env-vars table and CTASK_PROJECT_ROOT INFO line
to the doctor example. Query Resolution note explains that both
CTASK_ROOT and the default projects/ subdirectory are searched so
default-location projects are findable from any shell.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both .sh and .ps1 now build an effective display path by joining
CTASK_WORKSPACE with CTASK_LAUNCH_DIR when that variable is set. When
launch_dir is present and differs from the slug, the project tag also
carries ':<launch_dir>' so the display reflects user-overridden
launches. Tasks and pre-v0.5 projects are unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrites the built-in project CLAUDE.md template with a new Workspace
Structure section that explains the root-vs-subdir split. File
Placement rules refer to the subdirectory. Git section keeps the
single-repo rule and explicitly names the project subdirectory as an
example of where not to init.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three-state check matching the seed-dir pattern: INFO when unset
(points at the default discovery location), INFO with user-scope
advisory when set and present, FAIL when set but the directory
doesn't exist. Advisory wording is recommendatory, not prescriptive
(per spec amendment).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When CTASK_PROJECT_ROOT is unset, SearchRoots now appends
\$CTASK_ROOT/projects/ so that projects created under the default
category are discoverable from any shell without per-session env var
setup. Dedupe in scanAllRoots prevents double-counting workspaces that
are reachable both via the depth-2 scan under CTASK_ROOT and via the
new explicit search root. Adds a named regression test asserting no
duplicates appear in either ResolveQuery or ListWorkspaces results.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
For project workspaces with launch_dir set, info prints three extra
lines after Path: Launch dir, Launch path, and Dir exists (yes/no
from a direct os.Stat of the intended path). Tasks and pre-v0.5
projects still omit these lines.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
LaunchOpts gains LaunchDir. session.Run resolves it via
workspace.ResolveLaunch, prints any fallback warning, and passes the
absolute path as the child process's working directory. Security
violations (absolute paths, .. escape) abort the session. The banner
gains a 'project dir: <name>/' line when launch_dir is set.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
config.EnvVars gains a 7th launchDir argument. cmd/new, cmd/resume, and
cmd/open pass ws.Meta.LaunchDir. Child sessions can read CTASK_LAUNCH_DIR
to know which subdirectory ctask launched them into.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ctask new --project now creates an empty subdirectory named after the
final suffixed slug inside the workspace root, and sets meta.LaunchDir
to that slug. Task workspaces are unchanged. Seeds do not target the
subdirectory — the user populates it with their project code and their
own CLAUDE.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves a relative launch_dir into the absolute directory the child
process should cd into. Returns an error for absolute paths and paths
that escape the workspace via .. traversal. Returns (wsDir, warning, nil)
on os.IsNotExist or target-is-a-file so the caller prints a warning and
falls back. Non-IsNotExist stat errors (permission, invalid name, I/O)
propagate as real errors rather than being masked as warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a child-exit-code guard to handleProvisional so a `ctask new`
workspace is reclaimed only when the agent was actually canceled
before real work (trust prompt rejected, Esc during startup, Ctrl+C
mid-launch — all confirmed empirically as exit code 1). A zero exit
means the user entered the agent and exited cleanly, which is a
legitimate workflow that must preserve the workspace even with an
empty manifest diff — for example when the user wants the workspace
directory established so they can populate context/ before resuming.
The exit code reaches handleProvisional via a new childExitCode
helper that unwraps *exec.ExitError from cmd.Run's return. Non-exit
errors (agent not found, OS-level failure) map to -1 so the
workspace is still cleaned up — the child never actually ran.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Archive now inspects .ctask/session.json before mutating task.yaml. A
fresh lease (heartbeat within 60s) triggers a warning. Interactive
stdin gets a y/N prompt (default N). Non-interactive stdin refuses
with a non-zero exit, which is safer than silently hiding an actively
writing workspace. Stale or missing leases pass through unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the always-informational seed-dir block with three-state checks:
INFO when the env var is unset (defaults will be used), PASS when set and
the path exists, FAIL when set but the directory is missing. Only the
configured-but-missing state counts as a failed check and raises the
doctor exit code.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Project CLAUDE.md template now includes a Git section stating that the
workspace uses a single git repo at the root and subdirectory git init
is not permitted. docs/commands.md picks up the same guidance under the
--project flag section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Every resolver, lister, and most-recent caller now passes
config.SearchRoots() so CTASK_PROJECT_ROOT is searched alongside
CTASK_ROOT. Commands use ws.Root when rendering relative paths or
session env vars so displays and CTASK_ROOT exports are correct for
workspaces living under CTASK_PROJECT_ROOT.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrites scanWorkspaces to handle both category layout
(root/<category>/<workspace>/task.yaml) and flat layout
(root/<workspace>/task.yaml used under CTASK_PROJECT_ROOT).
Adds scanAllRoots to walk multiple roots with absolute-path dedupe.
ResolveQuery, ListWorkspaces, and MostRecentActive now accept []string.
QueryResult gains a Root field so callers can render display paths and
session env vars relative to the originating root.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When `ctask new` launched the agent or shell and the child exited without
touching any files (e.g. the user canceled at Claude Code's trust prompt),
the workspace was left behind as empty clutter. Now, if the invocation
just created the workspace and the manifest diff is empty (zero added,
modified, deleted), the workspace directory is removed and finalize is
skipped. resume/open/last are unaffected (NewlyCreated defaults to false),
and --no-launch is unaffected (session.Run is never called).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reflects the v0.3 polish-pass changes:
- default 'ctask list' shows active tasks AND projects
- --task flag added; --task and --projects are exclusive
- output now includes a "type" column
- 'ctask last' explicitly notes it considers both types
Default behavior is now the broadest useful active view: 'ctask
list' shows all active workspaces, both tasks and projects.
Flag matrix:
ctask list active tasks + projects
ctask list --all all (incl. archived)
ctask list --task active tasks only
ctask list --task --all all tasks (incl. archived)
ctask list --projects active projects only
ctask list --projects --all all projects (incl. archived)
--task and --projects are mutually exclusive; passing both
returns a usage error rather than silently picking one.
Output gains a small "type" column so the mixed default view
is unambiguous: status, type, mode, category, date, slug.
Empty-result message is type-aware ("No tasks found." /
"No projects found." / "No workspaces found.").
Tests cover all six valid flag combinations, the conflict case,
and the three empty-result message variants.
Both commands now call workspace.MostRecentActive(root) directly
instead of inlining a ListWorkspaces scan + max-by-UpdatedAt loop.
The cross-type behavior is identical to before this commit (it
was already correct after the v0.3 union fix), but it is now
locked down by the focused unit tests added in the previous
commit and there is no duplicated selection logic.
The (nil, nil) "no active workspaces" return is mapped to:
- cmd/last: prints "No active workspaces found." and exits 1
- cmd/delete: silently skips the "most recent" note (the user
is deleting some specific workspace by name; the
note was always best-effort)
Extracts the cross-type "most recently updated active workspace"
selector that previously lived inline in cmd/last and cmd/delete.
The helper takes only a root path and returns (nil, nil) when
nothing matches, which keeps the call sites trivial.
Eight focused tests cover:
- tasks-only fixture
- projects-only fixture
- project most-recent vs older task
- task most-recent vs older project
- legacy v0.2 workspace (no Type field) winning, treated as task
- newest workspace archived, older active project wins
- empty root returns (nil, nil)
- all archived returns (nil, nil)
A new createTestWorkspaceFull helper takes an explicit UpdatedAt
timestamp so the "which is newest" assertions don't depend on
wall-clock ordering.
cmd/last and cmd/delete are migrated onto the helper in the next
commit.
ListOpts now exposes a Type string field (TypeAny / TypeTask /
TypeProject). TypeAny is the new way to express "both tasks and
projects" in a single ListWorkspaces call -- which the next two
commits will use to consolidate cmd/last and cmd/delete onto a
single helper, and to make 'ctask list' default to showing both
types.
Invalid Type values now return an explicit error from
ListWorkspaces (defensive against typos in callers).
cmd/list, cmd/last, and cmd/delete are migrated to the new field.
External behavior is unchanged in this commit; the cleanup of
ctask list semantics happens in a follow-up commit so the diff
stays reviewable.
Adds the v0.3 feature spec (source of truth for this release) and
the inline-execution implementation plan that was followed to land
the v0.3 work in the preceding commits.
Scope of v0.3:
- User seed directories (general + project)
- Improved built-in CLAUDE.md defaults (task + project)
- --project mode (type metadata, project root, git init)
- --projects filter for ctask list
- CTASK_TYPE env export
- Status-line and doctor updates
The 2026-04-06-install-workflow plan (also untracked) is left
alone -- it predates this session and is not part of v0.3.
Updates docs/commands.md to cover the v0.3 surface:
- ctask new --project flag, project mode, project root
semantics, seed order, git init behavior
- ctask list --projects flag and --all/--projects matrix
- Seed directory locations (general + project) and skip rules
- CTASK_TYPE child env var, CTASK_PROJECT_ROOT,
CTASK_SEED_DIR, CTASK_SEED_PROJECT_DIR config vars
- Doctor [INFO] seed directory reporting
No remote install or publish commands are added; the project
remains local-only.
Adds two [INFO] lines after the existing pass/fail checks
reporting whether the resolved general and project seed
directories exist. These are read-only and do not contribute to
the pass/fail counters, so users with no seed directories still
see "5 checks passed, 0 failed".
The task case is byte-for-byte identical to v0.2:
(ctask:slug|mode) /workspace/path
Project sessions append a single |project marker:
(ctask:slug|mode|project) /workspace/path
Both helpers (.sh and .ps1) are updated symmetrically. The empty
case (no CTASK_TASK) still outputs nothing.
Smoke verified:
- task default: (ctask:demo|local) /tmp/demo
- explicit CTASK_TYPE=task: (ctask:demo|local) /tmp/demo
- CTASK_TYPE=project: (ctask:demo|local|project) /tmp/demo
- no CTASK_TASK: (silent)
ctask list shows tasks by default and projects with --projects.
--all controls archived visibility (independent of --projects),
so the four combinations work as the spec defines:
- ctask list active tasks
- ctask list --all active + archived tasks
- ctask list --projects active projects
- ctask list --projects --all active + archived projects
Empty-result message reflects the active filter.
ListOpts gains a Projects bool that filters by EffectiveType.
Default behavior (Projects: false) now returns tasks only --
this is a deliberate semantic change that supports the new
'ctask list' (tasks) vs 'ctask list --projects' (projects)
spec.
The change silently regresses two cmd-level callers that scan
for "the most recently updated workspace": cmd/last.go (used by
'ctask last') and cmd/delete.go (used to print the "this was
your most recent workspace" note). Both are fixed by unioning a
tasks-scan with a projects-scan, so 'last' and 'delete' continue
to consider both types.
Test helper createTestWorkspaceTyped allows setting an explicit
type (or "" to simulate a v0.2 workspace with no type field).
After Create() returns, project mode now:
1. Runs git init (or prints "git not found; skipped..." if git
is unavailable)
2. Calls EnsureGitignore, which is a no-op when a seed already
supplied .gitignore (preserving the seed-wins rule end-to-end)
Both git unavailability and git init failure are non-fatal: ctask
warns and continues, so a missing/broken git toolchain never blocks
project creation.
EnsureGitignore writes a minimal .gitignore (.ctask/ +
logs/sessions.log) iff one does not already exist. This is the
file-system half of the v0.3 seed-wins rule for .gitignore: if
either the general or project seed copied a .gitignore into the
workspace, EnsureGitignore must be a no-op.
GitAvailable + RunGitInit wrap exec.LookPath("git") and `git init`
respectively, so the caller in cmd/new.go can decide whether to
print the informational note when git is missing.
Tests cover:
- missing -> created with the minimal body
- present -> preserved verbatim
- integration: general seed .gitignore preserved end-to-end
- integration: project seed .gitignore preserved end-to-end
- integration: no seed -> minimal body created
ctask new gains --project, which:
- records type=project on the workspace
- defaults the category to "projects"
- applies general + project seed overlays
- uses CTASK_PROJECT_ROOT when set, with no doubled "projects/"
path unless the user explicitly passes -c
- exports CTASK_TYPE=project into the child session
EnvVars now takes a taskType arg and exports CTASK_TYPE. Empty
type defaults to "task" for safety. resume/open also pass
EffectiveType so the env var is correct on resume of a v0.2
workspace.
Git init for project mode is wired in the next commit.
When SkipCategoryDir is true, Create places the workspace directly
under Root and does not append a Category subdirectory. This is the
mechanism that prevents doubled paths like
~/projects/projects/<slug> when the user sets CTASK_PROJECT_ROOT
without an explicit -c flag. The Category value is still recorded
on TaskMeta so list/info/filter still work.
CreateOpts gains IsProject, SeedDir, and ProjectSeedDir. The new
seeding flow is:
1. write built-in defaults (task or project CLAUDE.md + notes.md)
2. apply general seed if SeedDir != "" (overlay)
3. apply project seed if IsProject && ProjectSeedDir != "" (overlay)
4. write task.yaml (last, so seeds can never inject metadata)
The obsolete TestCreateDoesNotOverwriteSeedFiles test is removed:
its v0.2 invariant ("don't overwrite existing files") no longer
holds because v0.3 always lays defaults onto a fresh dir and seeds
are expected to overwrite.
TaskMeta now records type: task or type: project. EffectiveType
returns 'task' for missing/empty/unknown values and for nil meta,
so v0.2 workspaces continue to read as tasks without any
migration. The field is placed between Category and Mode in the
YAML output. Tests cover the round-trip and the legacy
no-type-field case.
CopySeedDir is the v0.3 user seed overlay primitive: recursive copy
from a seed directory to a workspace, overwriting destination
files. task.yaml and the .ctask metadata directory at the seed root
are intentionally skipped so a stale or hostile seed cannot
overwrite ctask-owned state. Missing src is a no-op (the seed
directory is optional).
ResolveSeedDir, ResolveProjectSeedDir, and ResolveProjectRoot read
the v0.3 environment variables (CTASK_SEED_DIR,
CTASK_SEED_PROJECT_DIR, CTASK_PROJECT_ROOT) and fall back to
platform defaults under %APPDATA%\ctask or ~/.config/ctask. The
expandPath helper handles tilde expansion + abs-path resolution
once for all resolvers.
ClaudeMDProject returns the project-oriented default used when
--project is passed (and no project seed overrides it). Adds tests
asserting required v0.3 spec sections and ASCII-only content.
Replaces the v0.2 task-scoped template with the v0.3 workspace
guidelines (file placement conventions + session handoff).
ClaudeMD signature is preserved for API compatibility; the
parameters are no longer interpolated.
When the status-line helper is found but Claude settings are misconfigured,
the fix suggestion now shows the real path (e.g. /c/Users/Warren/...) instead
of a <you> placeholder. Always suggests the .sh variant even if only .ps1
was found, since Claude Code runs statusLine through bash.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
justfile with build/install/uninstall/test targets. CLAUDE.md updated with
new install path and commands. status-line-setup.md updated for
%LOCALAPPDATA%\ctask\bin location.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds the canonical install location as the primary search path on Windows,
before falling back to GOPATH/bin. Updates the Claude config guidance message
to reference the new path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removes only ctask-owned files from %LOCALAPPDATA%\ctask\bin. Removes PATH
entry only if .ctask-path-added marker exists (ownership tracking). Cleans
empty install directory. Never touches workspace data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Builds from local repo, installs to %LOCALAPPDATA%\ctask\bin, adds to user
PATH with ownership marker (.ctask-path-added) for safe uninstall. Finds Go
in standard install location if not on PowerShell PATH.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add "Repository and Package Identity" rule to both the project-level CLAUDE.md
and the seeded CLAUDE.md template (internal/seed/templates.go). Every new ctask
workspace now inherits guidance against fabricating repo URLs, module paths,
GitHub identities, or remote install commands.
Also adds local-only build/install instructions and data safety invariant
documentation to the project-level CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: CTASK_WORKSPACE env var only exists inside the child session spawned
by ctask resume. A separate terminal window does not inherit it, so the env-var
check was bypassed entirely. os.RemoveAll then deleted all accessible files while
the root dir was locked by the active cmd.exe process.
Fix: Add a second protection check for .ctask/manifest-start.json, which is only
present during a live session. Both checks run before any mutation (summary scan,
confirmation, or deletion). Either check triggers immediate refusal.
Tests: 4 new tests covering manifest-based protection, no-file-mutation on refusal,
env-var protection, and normal deletion of inactive workspaces.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace box-drawing characters (U+2500) in session log with ASCII dashes.
Replace em dashes (U+2014) in CLAUDE.md template with double hyphens.
Remove em dash from comment in run.go.
Add ASCII-guard tests for session log output and seed templates.
Prevents mojibake on Windows terminals that misinterpret UTF-8 as CP1252.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contents summary, confirmation prompt, --force flag, --all for archived, refuses deletion of active session workspace.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scans non-archived workspaces, finds highest updated_at, delegates to resume flow with session hooks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Checks: workspace root, agent on PATH, status line helper, Claude settings, existing workspaces. Actionable fix guidance for each failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Advisory instructions to append a brief summary to notes.md before ending a session. Also update logs/ description from "reserved" to "automatic session snapshots".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refactor new/resume/open to use session.Run() which wraps child process launch with pre/post manifest capture and append-only session logging to logs/sessions.log. Bump version to 0.2.0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Exit 2 for missing required arguments, exit 127 for agent not found. SilenceUsage on all commands to avoid dumping usage on runtime errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bash and PowerShell helpers for Claude Code statusLine. Setup docs with fallback note for non-Claude agents.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete command implementations with all flags per spec. Shared query resolution helper.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DefaultShell, ExecAgent, ExecShell with prompt prefix. Banner, container notice. Tests for all helpers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create function produces full workspace layout (task.yaml, CLAUDE.md, notes.md, context/, output/, logs/). Seed files only written if missing. Collision suffixing tested.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Slugify, AutoTitle, DirName, ResolveDir with -2, -3 suffixing. Full test coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TaskMeta struct matching task.yaml schema exactly. Tests for roundtrip, field presence, and archive state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Go module, cobra root command, config resolution (CTASK_ROOT, CTASK_AGENT, EnvVars) with tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>