refactor(completion): use go-lunatask All*() funcs

Amolith created

Add TaskStatuses, Priorities, and Motivations completion functions using
go-lunatask's All*() functions. Update Relationships to use
AllRelationshipStrengths(). Replace completion.Static() calls and
hardcoded 'started' strings with 'in-progress' to match go-lunatask's
normalized enum values.

Assisted-by: Claude Opus 4.5 via Crush <crush@charm.land>

Change summary

README.md                               |  2 
cmd/task/add.go                         | 11 ++---
cmd/task/list.go                        |  3 -
cmd/task/update.go                      | 11 ++---
internal/completion/completion.go       | 53 ++++++++++++++++++++++----
internal/mcp/resources/tasks/filters.go |  4 +-
internal/mcp/resources/tasks/handler.go |  2 
internal/mcp/tools/crud/query.go        |  2 
8 files changed, 58 insertions(+), 30 deletions(-)

Detailed changes

README.md 🔗

@@ -114,7 +114,7 @@ lune goal show KEY [--json]
 
 - `-a, --area` — area key from config
 - `-g, --goal` — goal key (requires area)
-- `-s, --status` — later, next, started, waiting, completed
+- `-s, --status` — later, next, in-progress, waiting, completed
 - `-n, --note` — task note (use `-` for stdin)
 - `-p, --priority` — lowest, low, normal, high, highest
 - `-e, --estimate` — time estimate in minutes (0-720)

cmd/task/add.go 🔗

@@ -42,7 +42,7 @@ Use "-" as NAME to read the task name from stdin.`,
 func init() {
 	AddCmd.Flags().StringP("area", "a", "", "Area key (from config)")
 	AddCmd.Flags().StringP("goal", "g", "", "Goal key (from config)")
-	AddCmd.Flags().StringP("status", "s", "", "Status: later, next, started, waiting")
+	AddCmd.Flags().StringP("status", "s", "", "Status: later, next, in-progress, waiting")
 	AddCmd.Flags().StringP("note", "n", "", "Task note (use - for stdin)")
 	AddCmd.Flags().StringP("priority", "p", "", "Priority: lowest, low, normal, high, highest")
 	AddCmd.Flags().IntP("estimate", "e", 0, "Estimate in minutes (0-720)")
@@ -55,12 +55,9 @@ func init() {
 
 	_ = AddCmd.RegisterFlagCompletionFunc("area", completion.Areas)
 	_ = AddCmd.RegisterFlagCompletionFunc("goal", completion.Goals)
-	_ = AddCmd.RegisterFlagCompletionFunc("status",
-		completion.Static("later", "next", "started", "waiting"))
-	_ = AddCmd.RegisterFlagCompletionFunc("priority",
-		completion.Static("lowest", "low", "normal", "high", "highest"))
-	_ = AddCmd.RegisterFlagCompletionFunc("motivation",
-		completion.Static("must", "should", "want"))
+	_ = AddCmd.RegisterFlagCompletionFunc("status", completion.TaskStatuses)
+	_ = AddCmd.RegisterFlagCompletionFunc("priority", completion.Priorities)
+	_ = AddCmd.RegisterFlagCompletionFunc("motivation", completion.Motivations)
 }
 
 func runAdd(cmd *cobra.Command, args []string) error {

cmd/task/list.go 🔗

@@ -45,8 +45,7 @@ func init() {
 	ListCmd.Flags().Bool("json", false, "Output as JSON")
 
 	_ = ListCmd.RegisterFlagCompletionFunc("area", completion.Areas)
-	_ = ListCmd.RegisterFlagCompletionFunc("status",
-		completion.Static("later", "next", "started", "waiting", "completed"))
+	_ = ListCmd.RegisterFlagCompletionFunc("status", completion.TaskStatuses)
 }
 
 func runList(cmd *cobra.Command, _ []string) error {

cmd/task/update.go 🔗

@@ -33,7 +33,7 @@ func init() {
 	UpdateCmd.Flags().String("name", "", "New task name (use - for stdin)")
 	UpdateCmd.Flags().StringP("area", "a", "", "Move to area key")
 	UpdateCmd.Flags().StringP("goal", "g", "", "Move to goal key")
-	UpdateCmd.Flags().StringP("status", "s", "", "Status: later, next, started, waiting, completed")
+	UpdateCmd.Flags().StringP("status", "s", "", "Status: later, next, in-progress, waiting, completed")
 	UpdateCmd.Flags().StringP("note", "n", "", "Task note (use - for stdin)")
 	UpdateCmd.Flags().StringP("priority", "p", "", "Priority: lowest, low, normal, high, highest")
 	UpdateCmd.Flags().IntP("estimate", "e", 0, "Estimate in minutes (0-720)")
@@ -46,12 +46,9 @@ func init() {
 
 	_ = UpdateCmd.RegisterFlagCompletionFunc("area", completion.Areas)
 	_ = UpdateCmd.RegisterFlagCompletionFunc("goal", completion.Goals)
-	_ = UpdateCmd.RegisterFlagCompletionFunc("status",
-		completion.Static("later", "next", "started", "waiting", "completed"))
-	_ = UpdateCmd.RegisterFlagCompletionFunc("priority",
-		completion.Static("lowest", "low", "normal", "high", "highest"))
-	_ = UpdateCmd.RegisterFlagCompletionFunc("motivation",
-		completion.Static("must", "should", "want"))
+	_ = UpdateCmd.RegisterFlagCompletionFunc("status", completion.TaskStatuses)
+	_ = UpdateCmd.RegisterFlagCompletionFunc("priority", completion.Priorities)
+	_ = UpdateCmd.RegisterFlagCompletionFunc("motivation", completion.Motivations)
 }
 
 func runUpdate(cmd *cobra.Command, args []string) error {

internal/completion/completion.go 🔗

@@ -81,15 +81,14 @@ func Habits(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDi
 
 // Relationships returns relationship strength options for shell completion.
 func Relationships(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
-	return []string{
-		"family",
-		"intimate-friends",
-		"close-friends",
-		"casual-friends",
-		"acquaintances",
-		"business-contacts",
-		"almost-strangers",
-	}, cobra.ShellCompDirectiveNoFileComp
+	rs := lunatask.AllRelationshipStrengths()
+	keys := make([]string, len(rs))
+
+	for i, r := range rs {
+		keys[i] = string(r)
+	}
+
+	return keys, cobra.ShellCompDirectiveNoFileComp
 }
 
 // Workflows returns workflow options for shell completion.
@@ -103,3 +102,39 @@ func Workflows(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCom
 
 	return keys, cobra.ShellCompDirectiveNoFileComp
 }
+
+// TaskStatuses returns task status options for shell completion.
+func TaskStatuses(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
+	statuses := lunatask.AllTaskStatuses()
+	keys := make([]string, len(statuses))
+
+	for i, s := range statuses {
+		keys[i] = string(s)
+	}
+
+	return keys, cobra.ShellCompDirectiveNoFileComp
+}
+
+// Priorities returns priority options for shell completion.
+func Priorities(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
+	priorities := lunatask.AllPriorities()
+	keys := make([]string, len(priorities))
+
+	for i, p := range priorities {
+		keys[i] = p.String()
+	}
+
+	return keys, cobra.ShellCompDirectiveNoFileComp
+}
+
+// Motivations returns motivation options for shell completion.
+func Motivations(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
+	motivations := lunatask.AllMotivations()
+	keys := make([]string, len(motivations))
+
+	for i, m := range motivations {
+		keys[i] = string(m)
+	}
+
+	return keys, cobra.ShellCompDirectiveNoFileComp
+}

internal/mcp/resources/tasks/filters.go 🔗

@@ -83,7 +83,7 @@ func FilterHighPriority(tasks []lunatask.Task) []lunatask.Task {
 
 // FilterNow returns tasks that need attention now.
 // Matches tasks where ANY of:
-// - Status = "started"
+// - Status = in-progress
 // - Priority = highest
 // - Motivation = "must"
 // - Eisenhower = urgent AND important.
@@ -106,7 +106,7 @@ func isNow(task *lunatask.Task) bool {
 		return false
 	}
 
-	// Status = started
+	// Status = in-progress
 	if task.Status != nil && *task.Status == lunatask.StatusInProgress {
 		return true
 	}

internal/mcp/resources/tasks/handler.go 🔗

@@ -55,7 +55,7 @@ const (
 
 	HighPriorityDescription = `Tasks with highest priority.`
 
-	NowDescription = `Tasks needing immediate attention: started, highest priority, must-do, or urgent+important.`
+	NowDescription = `Tasks needing immediate attention: in-progress, highest priority, must-do, or urgent+important.`
 
 	RecentCompletionsDescription = `Tasks completed in the last 72 hours.`
 

internal/mcp/tools/crud/query.go 🔗

@@ -215,7 +215,7 @@ func (h *Handler) listTasks(
 
 	if input.Status != nil {
 		if _, err := lunatask.ParseTaskStatus(*input.Status); err != nil {
-			return shared.ErrorResult("invalid status: must be later, next, started, waiting, or completed"),
+			return shared.ErrorResult("invalid status: must be later, next, in-progress, waiting, or completed"),
 				QueryOutput{Entity: EntityTask}, nil
 		}
 	}