From e346eb0db8118a0387e7b75ea6d2a6f5ddd5a8af Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Thu, 27 Nov 2025 16:46:40 -0500 Subject: Auto-transition epic to Review status when all children reach Done The implementation is complete. Summary of changes to [Omni/Jr.hs](file: 1. Added `checkEpicCompletion` function (lines 490-508) that: - Checks if the completed task has a parent - Finds the parent task and verifies it's an Epic - Checks if all children of that epic are Done - If so, transitions the epic to Review status 2. Updated `autoReview` to call `checkEpicCompletion` after marking a ta 3. Updated `interactiveReview` to: - Accept the task as a parameter (line 414) - Call `checkEpicCompletion` after marking a task Done (line 429) 4. Updated the call site at line 361 to pass the task to `interactiveRev Task-Id: t-155.1 --- Omni/Jr.hs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'Omni/Jr.hs') diff --git a/Omni/Jr.hs b/Omni/Jr.hs index 0746424..9e33ab5 100755 --- a/Omni/Jr.hs +++ b/Omni/Jr.hs @@ -358,7 +358,7 @@ reviewTask tid autoMode = do Nothing -> do if autoMode then autoReview tid task commitSha - else interactiveReview tid commitSha + else interactiveReview tid task commitSha -- | Auto-review: run tests on namespace, accept if pass, reject if fail autoReview :: Text -> TaskCore.Task -> String -> IO () @@ -385,6 +385,7 @@ autoReview tid task commitSha = do TaskCore.clearRetryContext tid TaskCore.updateTaskStatus tid TaskCore.Done [] putText ("[review] Task " <> tid <> " -> Done") + checkEpicCompletion task Exit.ExitFailure code -> do putText ("[review] ✗ Tests failed (exit " <> tshow code <> ")") let reason = "Test failure:\n" <> Text.pack testOut <> Text.pack testErr @@ -410,8 +411,8 @@ autoReview tid task commitSha = do putText ("[review] Task " <> tid <> " reopened (attempt " <> tshow attempt <> "/3).") -- | Interactive review with user prompts -interactiveReview :: Text -> String -> IO () -interactiveReview tid commitSha = do +interactiveReview :: Text -> TaskCore.Task -> String -> IO () +interactiveReview tid task commitSha = do putText "\n=== Diff for this task ===\n" _ <- Process.rawSystem "git" ["show", commitSha] @@ -425,6 +426,7 @@ interactiveReview tid commitSha = do TaskCore.clearRetryContext tid TaskCore.updateTaskStatus tid TaskCore.Done [] putText ("Task " <> tid <> " marked as Done.") + checkEpicCompletion task | "r" `Text.isPrefixOf` c -> do putText "Enter rejection reason: " IO.hFlush IO.stdout @@ -485,6 +487,26 @@ extractConflictFile line = | not (Text.null rest) -> Just (Text.strip (Text.drop 3 rest)) _ -> Nothing +-- | Check if all children of an epic are Done, and if so, transition epic to Review +checkEpicCompletion :: TaskCore.Task -> IO () +checkEpicCompletion task = + case TaskCore.taskParent task of + Nothing -> pure () + Just parentId -> do + tasks <- TaskCore.loadTasks + case TaskCore.findTask parentId tasks of + Nothing -> pure () + Just parentTask -> + when (TaskCore.taskType parentTask == TaskCore.Epic) <| do + let children = filter (hasParent parentId) tasks + allDone = all (\t -> TaskCore.taskStatus t == TaskCore.Done) children + when (allDone && not (null children)) <| do + putText ("[review] All children of epic " <> parentId <> " are Done.") + TaskCore.updateTaskStatus parentId TaskCore.Review [] + putText ("[review] Epic " <> parentId <> " -> Review") + where + hasParent pid t = maybe False (TaskCore.matchesId pid) (TaskCore.taskParent t) + test :: Test.Tree test = Test.group -- cgit v1.2.3