summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Omni/Task.hs25
-rw-r--r--Omni/Task/Core.hs37
2 files changed, 62 insertions, 0 deletions
diff --git a/Omni/Task.hs b/Omni/Task.hs
index e3f89dc..656c972 100644
--- a/Omni/Task.hs
+++ b/Omni/Task.hs
@@ -41,6 +41,7 @@ Usage:
task create <title> [--type=<type>] [--parent=<id>] [--priority=<p>] [--deps=<ids>] [--dep-type=<type>] [--discovered-from=<id>] [--namespace=<ns>] [--json]
task list [--type=<type>] [--parent=<id>] [--status=<status>] [--namespace=<ns>] [--json]
task ready [--json]
+ task show <id> [--json]
task update <id> <status> [--json]
task deps <id> [--json]
task tree [<id>] [--json]
@@ -55,6 +56,7 @@ Commands:
create Create a new task or epic
list List all tasks
ready Show ready tasks (not blocked)
+ show Show detailed task information
update Update task status
deps Show dependency tree
tree Show task tree (epics with children, or all epics if no ID given)
@@ -186,6 +188,15 @@ move args
else do
putText "Ready tasks:"
traverse_ printTask tasks
+ | args `Cli.has` Cli.command "show" = do
+ tid <- getArgText args "id"
+ tasks <- loadTasks
+ case filter (\t -> taskId t == tid) tasks of
+ [] -> putText "Task not found"
+ (task : _) ->
+ if isJsonMode args
+ then outputJson task
+ else showTaskDetailed task
| args `Cli.has` Cli.command "update" = do
tid <- getArgText args "id"
statusStr <- getArgText args "status"
@@ -424,6 +435,20 @@ cliTests =
args `Cli.has` Cli.command "import" Test.@?= True
-- Note: -i is a short option, not an argument
Cli.getArg args (Cli.shortOption 'i') Test.@?= Just "tasks.jsonl",
+ Test.unit "show command" <| do
+ let result = Docopt.parseArgs help ["show", "t-abc123"]
+ case result of
+ Left err -> Test.assertFailure <| "Failed to parse 'show': " <> show err
+ Right args -> do
+ args `Cli.has` Cli.command "show" Test.@?= True
+ Cli.getArg args (Cli.argument "id") Test.@?= Just "t-abc123",
+ Test.unit "show with --json flag" <| do
+ let result = Docopt.parseArgs help ["show", "t-abc123", "--json"]
+ case result of
+ Left err -> Test.assertFailure <| "Failed to parse 'show --json': " <> show err
+ Right args -> do
+ args `Cli.has` Cli.command "show" Test.@?= True
+ args `Cli.has` Cli.longOption "json" Test.@?= True,
Test.unit "sync command" <| do
let result = Docopt.parseArgs help ["sync"]
case result of
diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs
index 6c472c5..1dc31a8 100644
--- a/Omni/Task/Core.hs
+++ b/Omni/Task/Core.hs
@@ -373,6 +373,43 @@ printTask t =
Nothing -> ""
Just ns -> " [" <> ns <> "]"
+-- Show detailed task information (human-readable)
+showTaskDetailed :: Task -> IO ()
+showTaskDetailed t = do
+ putText "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ putText <| "Task: " <> taskId t
+ putText "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ putText <| "Title: " <> taskTitle t
+ putText <| "Type: " <> T.pack (show (taskType t))
+ putText <| "Status: " <> T.pack (show (taskStatus t))
+ putText <| "Priority: " <> T.pack (show (taskPriority t)) <> priorityDesc
+ case taskParent t of
+ Nothing -> pure ()
+ Just p -> putText <| "Parent: " <> p
+ case taskNamespace t of
+ Nothing -> pure ()
+ Just ns -> putText <| "Namespace: " <> ns
+ putText <| "Created: " <> T.pack (show (taskCreatedAt t))
+ putText <| "Updated: " <> T.pack (show (taskUpdatedAt t))
+
+ -- Show dependencies
+ unless (null (taskDependencies t)) <| do
+ putText ""
+ putText "Dependencies:"
+ traverse_ printDependency (taskDependencies t)
+
+ putText "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+ where
+ priorityDesc = case taskPriority t of
+ P0 -> " (Critical)"
+ P1 -> " (High)"
+ P2 -> " (Medium)"
+ P3 -> " (Low)"
+ P4 -> " (Backlog)"
+
+ printDependency dep =
+ putText <| " - " <> depId dep <> " [" <> T.pack (show (depType dep)) <> "]"
+
-- Export tasks: Consolidate JSONL file (remove duplicates, keep latest version)
exportTasks :: IO ()
exportTasks = do