diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-22 17:00:09 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-22 17:00:09 -0500 |
| commit | 581dc6bfd6408300a6d9d3abadb10c3ed67f1c58 (patch) | |
| tree | 03a5a6734aa558c53168c0e5c4471029cd841a50 | |
| parent | 4b711255cd0eb5ec1a91105a10ec464e46e3589a (diff) | |
| parent | 5213e86447768b5a17cae3c8dfba71771ce2a0cb (diff) | |
task: complete t-1o2bxcq7999.2 (Merge)
Amp-Thread-ID:
https://ampcode.com/threads/T-ca3b086b-5a85-422a-b13d-256784c04221
Co-authored-by: Amp <amp@ampcode.com>
| -rw-r--r-- | .tasks/tasks.jsonl | 3 | ||||
| -rw-r--r-- | Omni/Task.hs | 28 | ||||
| -rw-r--r-- | Omni/Task/Core.hs | 9 |
3 files changed, 33 insertions, 7 deletions
diff --git a/.tasks/tasks.jsonl b/.tasks/tasks.jsonl index aa8c1da..74e18b3 100644 --- a/.tasks/tasks.jsonl +++ b/.tasks/tasks.jsonl @@ -202,8 +202,9 @@ {"taskCreatedAt":"2025-11-22T10:39:11.364170862Z","taskDependencies":[{"depId":"t-rwbmpxabk","depType":"DiscoveredFrom"}],"taskDescription":null,"taskId":"t-rwcm6todb","taskNamespace":null,"taskParent":null,"taskPriority":"P2","taskStatus":"Done","taskTitle":"Fix failing tests in Biz/PodcastItLater/Web.py (UsageLimits and EpisodeDetail)","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T14:32:24.762100815Z"} {"taskCreatedAt":"2025-11-22T20:37:09.166630362Z","taskDependencies":[],"taskDescription":null,"taskId":"t-1o2bxcq7999","taskNamespace":"Omni/Workflow.hs","taskParent":null,"taskPriority":"P2","taskStatus":"Open","taskTitle":"Phase 1: Foundations (Task & CI)","taskType":"Epic","taskUpdatedAt":"2025-11-22T20:37:09.166630362Z"} {"taskCreatedAt":"2025-11-22T20:37:13.980489314Z","taskDependencies":[],"taskDescription":"Configure .gitattributes and .git/config (via Omni/Ide/hooks or setup) to use 'agent merge-driver' for .tasks/tasks.jsonl. This prevents data loss when merging branches with divergent task lists.","taskId":"t-1o2bxcq7999.1","taskNamespace":"Omni/Ide.hs","taskParent":"t-1o2bxcq7999","taskPriority":"P0","taskStatus":"Done","taskTitle":"Configure git merge driver for tasks.jsonl","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:57:23.592078308Z"} -{"taskCreatedAt":"2025-11-22T20:37:18.719690905Z","taskDependencies":[],"taskDescription":"Update Task Core to include Approved status, update CLI to support it, update TaskStats, and fix any compilation errors. Reference plan: /home/ben/omni/_/llm/PLAN_Autonomous_Workflow.md","taskId":"t-1o2bxcq7999.2","taskNamespace":"Omni/Task.hs","taskParent":"t-1o2bxcq7999","taskPriority":"P1","taskStatus":"Review","taskTitle":"Add Approved status to Omni/Task","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:21:07.384080767Z"} +{"taskCreatedAt":"2025-11-22T20:37:18.719690905Z","taskDependencies":[],"taskDescription":"Update Task Core to include Approved status, update CLI to support it, update TaskStats, and fix any compilation errors. Reference plan: /home/ben/omni/_/llm/PLAN_Autonomous_Workflow.md","taskId":"t-1o2bxcq7999.2","taskNamespace":"Omni/Task.hs","taskParent":"t-1o2bxcq7999","taskPriority":"P1","taskStatus":"Done","taskTitle":"Add Approved status to Omni/Task","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:59:08.985299564Z"} {"taskCreatedAt":"2025-11-22T20:37:23.378739333Z","taskDependencies":[],"taskDescription":"Rewrite Omni/Ci.sh into a robust Haskell program (Omni/Ci.hs). Reference plan: /home/ben/omni/_/llm/PLAN_Autonomous_Workflow.md","taskId":"t-1o2bxcq7999.3","taskNamespace":"Omni/Ci.hs","taskParent":"t-1o2bxcq7999","taskPriority":"P1","taskStatus":"Review","taskTitle":"Implement Omni/Ci.hs","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:23:53.72628323Z"} {"taskCreatedAt":"2025-11-22T20:37:27.396872011Z","taskDependencies":[],"taskDescription":"The Time, Thread, and Credits fields in the agent status bar are not being populated. Update Omni/Agent/Log.hs to parse these fields from the JSON log output.","taskId":"t-1o2bxd11zv9","taskNamespace":"Omni/Agent.hs","taskParent":null,"taskPriority":"P1","taskStatus":"Review","taskTitle":"Fix missing Time, Thread, and Credits in Agent Log","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:31:55.395825865Z"} {"taskCreatedAt":"2025-11-22T20:37:31.615764727Z","taskDependencies":[],"taskDescription":"The 'task ready' command currently lists Epics. Update 'getReadyTasks' in Omni/Task/Core.hs to exclude tasks where taskType == Epic.","taskId":"t-1o2bxd3kezj","taskNamespace":"Omni/Task.hs","taskParent":null,"taskPriority":"P1","taskStatus":"Review","taskTitle":"Fix task ready to exclude Epics","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:34:28.577198837Z"} {"taskCreatedAt":"2025-11-22T21:45:10.578083608Z","taskDependencies":[],"taskDescription":"Update Omni/Agent/start-worker.sh to run 'git sync' in the worker directory before building 'task' and 'agent'. This ensures the worker has the latest tools and code from live.","taskId":"t-1o2bxcq7999.4","taskNamespace":"Omni/Agent.hs","taskParent":"t-1o2bxcq7999","taskPriority":"P1","taskStatus":"Review","taskTitle":"Sync worker repo in start-worker.sh","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:46:40.928370623Z"} +{"taskCreatedAt":"2025-11-22T21:19:54.675769476Z","taskDependencies":[],"taskDescription":null,"taskId":"t-rwd249bi3","taskNamespace":"Omni/Task.hs","taskParent":null,"taskPriority":"P2","taskStatus":"Done","taskTitle":"Test Approved Status","taskType":"WorkTask","taskUpdatedAt":"2025-11-22T21:20:10.652509625Z"} diff --git a/Omni/Task.hs b/Omni/Task.hs index 12842db..8abf551 100644 --- a/Omni/Task.hs +++ b/Omni/Task.hs @@ -4,6 +4,7 @@ {-# LANGUAGE NoImplicitPrelude #-} -- : out task +-- : modified by benign worker module Omni.Task where import Alpha @@ -79,8 +80,8 @@ Options: --title=<title> Task title --type=<type> Task type: epic or task --parent=<id> Parent epic ID - --priority=<p> Priority: 0-4 (0=critical, 4=backlog) - --status=<status> Task status (open, in-progress, review, done) + --priority=<p> Priority: 0-4 (0=critical, 4=backlog, default: 2) + --status=<status> Filter by status: open, in-progress, review, approved, done --epic=<id> Filter stats by epic (recursive) --deps=<ids> Comma-separated list of dependency IDs --dep-type=<type> Dependency type: blocks, discovered-from, parent-child, related @@ -95,7 +96,7 @@ Options: Arguments: <title> Task title <id> Task ID - <status> Task status (open, in-progress, review, done) + <status> Task status (open, in-progress, review, approved, done) <file> JSONL file to import |] @@ -255,8 +256,9 @@ move args Just "open" -> pure <| Just Open Just "in-progress" -> pure <| Just InProgress Just "review" -> pure <| Just Review + Just "approved" -> pure <| Just Approved Just "done" -> pure <| Just Done - Just other -> panic <| "Invalid status: " <> T.pack other <> ". Use: open, in-progress, review, or done" + Just other -> panic <| "Invalid status: " <> T.pack other <> ". Use: open, in-progress, review, approved, or done" maybeNamespace <- case Cli.getArg args (Cli.longOption "namespace") of Nothing -> pure Nothing Just ns -> do @@ -306,8 +308,9 @@ move args "open" -> Open "in-progress" -> InProgress "review" -> Review + "approved" -> Approved "done" -> Done - _ -> panic "Invalid status. Use: open, in-progress, review, or done" + _ -> panic "Invalid status. Use: open, in-progress, review, approved, or done" updateTaskStatus tid newStatus deps if isJsonMode args @@ -665,6 +668,13 @@ cliTests = Right args -> do args `Cli.has` Cli.command "list" Test.@?= True Cli.getArg args (Cli.longOption "status") Test.@?= Just "open", + Test.unit "list with --status=approved filter" <| do + let result = Docopt.parseArgs help ["list", "--status=approved"] + case result of + Left err -> Test.assertFailure <| "Failed to parse 'list --status=approved': " <> show err + Right args -> do + args `Cli.has` Cli.command "list" Test.@?= True + Cli.getArg args (Cli.longOption "status") Test.@?= Just "approved", Test.unit "ready command" <| do let result = Docopt.parseArgs help ["ready"] case result of @@ -685,6 +695,14 @@ cliTests = args `Cli.has` Cli.command "update" Test.@?= True Cli.getArg args (Cli.argument "id") Test.@?= Just "t-abc123" Cli.getArg args (Cli.argument "status") Test.@?= Just "done", + Test.unit "update command with approved" <| do + let result = Docopt.parseArgs help ["update", "t-abc123", "approved"] + case result of + Left err -> Test.assertFailure <| "Failed to parse 'update ... approved': " <> show err + Right args -> do + args `Cli.has` Cli.command "update" Test.@?= True + Cli.getArg args (Cli.argument "id") Test.@?= Just "t-abc123" + Cli.getArg args (Cli.argument "status") Test.@?= Just "approved", Test.unit "update with --json flag" <| do let result = Docopt.parseArgs help ["update", "t-abc123", "done", "--json"] case result of diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs index 3de42b2..ebf5390 100644 --- a/Omni/Task/Core.hs +++ b/Omni/Task/Core.hs @@ -42,7 +42,7 @@ data Task = Task data TaskType = Epic | WorkTask deriving (Show, Eq, Generic) -data Status = Open | InProgress | Review | Done +data Status = Open | InProgress | Review | Approved | Done deriving (Show, Eq, Generic) -- Priority levels (matching beads convention) @@ -578,6 +578,7 @@ showTaskTree maybeId = do Open -> "[ ]" InProgress -> "[~]" Review -> "[?]" + Approved -> "[+]" Done -> "[✓]" coloredStatusStr = case taskType task of @@ -586,6 +587,7 @@ showTaskTree maybeId = do Open -> bold statusStr InProgress -> yellow statusStr Review -> magenta statusStr + Approved -> green statusStr Done -> green statusStr nsStr = case taskNamespace task of @@ -645,6 +647,7 @@ printTask t = do Open -> bold s InProgress -> yellow s Review -> magenta s + Approved -> green s Done -> green s coloredTitle = if taskType t == Epic then bold (taskTitle t) else taskTitle t @@ -755,6 +758,7 @@ data TaskStats = TaskStats openTasks :: Int, inProgressTasks :: Int, reviewTasks :: Int, + approvedTasks :: Int, doneTasks :: Int, totalEpics :: Int, readyTasks :: Int, @@ -790,6 +794,7 @@ getTaskStats maybeEpicId = do open = length <| filter (\t -> taskStatus t == Open) tasks inProg = length <| filter (\t -> taskStatus t == InProgress) tasks review = length <| filter (\t -> taskStatus t == Review) tasks + approved = length <| filter (\t -> taskStatus t == Approved) tasks done = length <| filter (\t -> taskStatus t == Done) tasks epics = length <| filter (\t -> taskType t == Epic) tasks readyCount' = readyCount @@ -812,6 +817,7 @@ getTaskStats maybeEpicId = do openTasks = open, inProgressTasks = inProg, reviewTasks = review, + approvedTasks = approved, doneTasks = done, totalEpics = epics, readyTasks = readyCount', @@ -839,6 +845,7 @@ showTaskStats maybeEpicId = do putText <| " Open: " <> T.pack (show (openTasks stats)) putText <| " In Progress: " <> T.pack (show (inProgressTasks stats)) putText <| " Review: " <> T.pack (show (reviewTasks stats)) + putText <| " Approved: " <> T.pack (show (approvedTasks stats)) putText <| " Done: " <> T.pack (show (doneTasks stats)) putText "" putText <| "Epics: " <> T.pack (show (totalEpics stats)) |
