ctask agents check [workspace] validates that a workspace's agent
configuration can be launched without launching it: agent type known,
command resolvable on PATH, launch_dir valid, AGENTS.md present,
CLAUDE.md shim present (WARN only, claude type only). agent.env keys
are displayed informationally, with a WARN line when any key shadows a
ctask-exported CTASK_* var. Returns non-zero when any check FAILs.
ctask doctor includes the same sweep when a workspace context is
resolvable — the most-recently-active workspace via
workspace.MostRecentActive. When no active workspace exists, doctor
shows "Agent check: skipped (no workspace context)" without bumping
the failure counter. runAgentsCheckOnWorkspace is shared between the
standalone command and the doctor integration.
TestCompletionSubcommandViaExecute is made order-independent: cobra's
default completion command captures the root output writer on the first
Execute() in the process, and the new agents-check tests now run an
Execute() earlier in the suite.
Replace TaskMeta.Agent (string) with TaskMeta.Agent (AgentSpec) carrying
type/command/args/env. Custom UnmarshalYAML preserves the legacy scalar
form: a built-in name (claude, opencode) maps to that type; any other
scalar maps to type=custom with the scalar as command. A missing agent
field leaves Type empty so the resolver fills in default_agent at launch.
ValidateAgentSpec enforces: known type (claude|opencode|custom),
type=custom requires command, command must be an executable name or
path with no whitespace or shell metacharacters.
Launch-path wiring (Task 3) and the --agent flag rework (Task 4) are
intentionally not part of this commit; cmd/* call sites are patched to
the minimum needed for the build to compile.
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.