refactor(v0.3): replace ListOpts.Projects bool with tri-state Type filter

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.
This commit is contained in:
2026-04-10 16:49:49 -04:00
parent 4b6c8fad4b
commit bd1cff5b26
5 changed files with 82 additions and 51 deletions
+3 -12
View File
@@ -32,24 +32,15 @@ func runLast(cmd *cobra.Command, args []string) error {
root := config.ResolveRoot()
// Scan all non-archived workspaces (tasks AND projects) and find the most
// recently updated. v0.3: ListWorkspaces filters by type, so we union the
// two type buckets here so `last` keeps working for both.
tasks, err := workspace.ListWorkspaces(root, workspace.ListOpts{
// recently updated.
results, err := workspace.ListWorkspaces(root, workspace.ListOpts{
IncludeArchived: false,
Limit: 0,
Type: workspace.TypeAny,
})
if err != nil {
return err
}
projects, err := workspace.ListWorkspaces(root, workspace.ListOpts{
IncludeArchived: false,
Projects: true,
Limit: 0,
})
if err != nil {
return err
}
results := append(tasks, projects...)
if len(results) == 0 {
fmt.Fprintln(os.Stderr, "No active workspaces found.")