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>
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)
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.
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).
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>