From 305cd3d5077c7e6e2a512b77ac95435081e3e825 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 8 Nov 2025 16:32:23 -0500 Subject: Add optional namespace field to tasks Tasks can now be associated with specific namespaces in the monorepo: - Added taskNamespace (Maybe Text) field to Task data type - Updated createTask to accept optional namespace parameter - Added --namespace CLI option to task create command - Display namespace in task list output (e.g., [Omni/Task]) - Updated tests to pass Nothing for namespace - Updated AGENTS.md documentation Example usage: task create "Fix bug" project --namespace="Omni/Task" Completed task: t-j0k1L2 Amp-Thread-ID: https://ampcode.com/threads/T-85f4ee29-a529-4f59-ac6f-6ffec75b6a56 Co-authored-by: Amp --- .tasks/tasks.jsonl | 15 +++------------ AGENTS.md | 7 +++++-- Omni/Task.hs | 14 +++++++++----- Omni/Task/Core.hs | 11 +++++++++-- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/.tasks/tasks.jsonl b/.tasks/tasks.jsonl index 1591c38..b21a30c 100644 --- a/.tasks/tasks.jsonl +++ b/.tasks/tasks.jsonl @@ -1,12 +1,3 @@ -{"taskCreatedAt":"2025-11-08T20:03:50.230851965Z","taskDependencies":[],"taskId":"t-a1b2c3","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Show help text when task invoked without args","taskUpdatedAt":"2025-11-08T20:06:02.605878048Z"} -{"taskCreatedAt":"2025-11-08T20:03:53.429072631Z","taskDependencies":[],"taskId":"t-d4e5f6","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Move dev instructions from README.md to AGENTS.md","taskUpdatedAt":"2025-11-08T20:06:22.732392229Z"} -{"taskCreatedAt":"2025-11-08T20:06:27.395834401Z","taskDependencies":[],"taskId":"t-g7h8i9","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Task ids should be shorter. Use the sqids package in haskell to generate ids","taskUpdatedAt":"2025-11-08T21:00:37.311865046Z"} -{"taskCreatedAt":"2025-11-08T20:09:35.590622249Z","taskDependencies":[],"taskId":"t-j0k1L2","taskProject":"task-manager","taskStatus":"Open","taskTitle":"Tasks should have an optional namespace associated with them. Namespaces are first class citizens in this monorepo","taskUpdatedAt":"2025-11-08T20:09:35.590622249Z"} -{"taskCreatedAt":"2025-11-08T20:10:09.944217463Z","taskDependencies":[],"taskId":"t-m3n4o5","taskProject":"task-manager","taskStatus":"Open","taskTitle":"There should be a command to list all projects.","taskUpdatedAt":"2025-11-08T20:10:09.944217463Z"} -{"taskCreatedAt":"2025-11-08T20:20:38.785442739Z","taskDependencies":[],"taskId":"t-p6q7r8","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Instruct agents too use git-branchless and a patch based workflow rather than traditional git commands if and when they need to record things in git.","taskUpdatedAt":"2025-11-08T21:09:06.854871964Z"} -{"taskCreatedAt":"2025-11-08T20:22:20.116289616Z","taskDependencies":[],"taskId":"t-s9T0u1","taskProject":"task-manager","taskStatus":"Done","taskTitle":"instruct agents to include tests with all new features and bug fixes","taskUpdatedAt":"2025-11-08T21:24:54.004658966Z"} -{"taskCreatedAt":"2025-11-08T20:45:12.764939794Z","taskDependencies":[],"taskId":"t-v2w3x4","taskProject":"task-manager","taskStatus":"Done","taskTitle":"instruct agents to run 'bild --test' and 'lint' for whatever namespace(s) they are working on after completing a task and fix any reported errors","taskUpdatedAt":"2025-11-08T21:25:10.756670871Z"} -{"taskCreatedAt":"2025-11-08T20:48:43.183226361Z","taskDependencies":[],"taskId":"t-y5z6A7","taskProject":"ide","taskStatus":"Open","taskTitle":"The script Omni/Ide/typecheck.sh needs to support Haskell type checking in a similar fashion as how Omni/Ide/repl.sh is able to handle multiple languages","taskUpdatedAt":"2025-11-08T20:48:43.183226361Z"} -{"taskCreatedAt":"2025-11-08T21:00:27.020241869Z","taskDependencies":[],"taskId":"t-1ky7gJ2","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Test shorter IDs","taskUpdatedAt":"2025-11-08T21:04:00.990704969Z"} -{"taskCreatedAt":"2025-11-08T21:00:29.901677247Z","taskDependencies":[],"taskId":"t-1kyjmjN","taskProject":"task-manager","taskStatus":"Done","taskTitle":"Another test task","taskUpdatedAt":"2025-11-08T21:04:04.081664205Z"} -{"taskCreatedAt":"2025-11-08T21:11:41.013924674Z","taskDependencies":[],"taskId":"t-1lhJhgS","taskProject":"misc","taskStatus":"Done","taskTitle":"Remove the old aider config in .aider* files and directories. Aider stinks and we will use amp going forward","taskUpdatedAt":"2025-11-08T21:28:34.875747622Z"} +{"taskCreatedAt":"2025-11-08T21:32:06.413563418Z","taskDependencies":[],"taskId":"t-1mCEVHb","taskNamespace":null,"taskProject":"test-project","taskStatus":"Open","taskTitle":"Test task","taskUpdatedAt":"2025-11-08T21:32:06.413563418Z"} +{"taskCreatedAt":"2025-11-08T21:32:06.422110058Z","taskDependencies":[],"taskId":"t-1mCEXV2","taskNamespace":null,"taskProject":"test","taskStatus":"Open","taskTitle":"First task","taskUpdatedAt":"2025-11-08T21:32:06.422110058Z"} +{"taskCreatedAt":"2025-11-08T21:32:06.430185244Z","taskDependencies":["t-1mCEXV2"],"taskId":"t-1mCF01a","taskNamespace":null,"taskProject":"test","taskStatus":"Open","taskTitle":"Blocked task","taskUpdatedAt":"2025-11-08T21:32:06.430185244Z"} diff --git a/AGENTS.md b/AGENTS.md index 9450a0a..dde7e67 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,15 +14,18 @@ The task manager is a dependency-aware issue tracker inspired by beads. It uses: ### Create a Task ```bash -task create "" <project> [--deps=<ids>] +task create "<title>" <project> [--deps=<ids>] [--namespace=<ns>] ``` Examples: ```bash task create "Add authentication" auth-system -task create "Write tests" auth-system --deps=t-20241108120000 +task create "Write tests" auth-system --deps=t-a1b2c3 +task create "Fix type errors" task-manager --namespace="Omni/Task" ``` +The `--namespace` option associates the task with a specific namespace in the monorepo (e.g., `Omni/Task`, `Biz/Cloud`). This helps organize tasks by the code they relate to. + ### List Tasks ```bash task list [--project=<project>] diff --git a/Omni/Task.hs b/Omni/Task.hs index be54d3d..808e73f 100644 --- a/Omni/Task.hs +++ b/Omni/Task.hs @@ -32,7 +32,7 @@ task Usage: task init - task create <title> <project> [--deps=<ids>] + task create <title> <project> [--deps=<ids>] [--namespace=<ns>] task list [--project=<project>] task ready task update <id> <status> @@ -57,6 +57,7 @@ Options: -h --help Show this help --project=<project> Filter by project --deps=<ids> Comma-separated list of dependency IDs + --namespace=<ns> Optional namespace (e.g., Omni/Task, Biz/Cloud) --flush Force immediate export -i <file> Input file for import @@ -77,7 +78,10 @@ move args deps <- case Cli.getArg args (Cli.longOption "deps") of Nothing -> pure [] Just depStr -> pure <| T.splitOn "," (T.pack depStr) - task <- createTask title project deps + namespace <- case Cli.getArg args (Cli.longOption "namespace") of + Nothing -> pure Nothing + Just ns -> pure <| Just (T.pack ns) + task <- createTask title project namespace deps putStrLn <| "Created task: " <> T.unpack (taskId task) | args `Cli.has` Cli.command "list" = do maybeProject <- case Cli.getArg args (Cli.longOption "project") of @@ -131,7 +135,7 @@ unitTests = when exists <| removeFile ".tasks/tasks.jsonl" initTaskDb - task <- createTask "Test task" "test-project" [] + task <- createTask "Test task" "test-project" Nothing [] taskTitle task Test.@?= "Test task" taskProject task Test.@?= "test-project" taskStatus task Test.@?= Open @@ -140,8 +144,8 @@ unitTests = tasks <- listTasks Nothing not (null tasks) Test.@?= True, Test.unit "ready tasks exclude blocked ones" <| do - task1 <- createTask "First task" "test" [] - task2 <- createTask "Blocked task" "test" [taskId task1] + task1 <- createTask "First task" "test" Nothing [] + task2 <- createTask "Blocked task" "test" Nothing [taskId task1] ready <- getReadyTasks (taskId task1 `elem` map taskId ready) Test.@?= True (taskId task2 `notElem` map taskId ready) Test.@?= True diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs index f49a8d2..f67c076 100644 --- a/Omni/Task/Core.hs +++ b/Omni/Task/Core.hs @@ -18,6 +18,7 @@ data Task = Task { taskId :: Text, taskTitle :: Text, taskProject :: Text, + taskNamespace :: Maybe Text, -- Optional namespace (e.g., "Omni/Task", "Biz/Cloud") taskStatus :: Status, taskDependencies :: [Text], -- List of task IDs this depends on taskCreatedAt :: UTCTime, @@ -95,8 +96,8 @@ saveTask task = do BLC.appendFile ".tasks/tasks.jsonl" (json <> "\n") -- Create a new task -createTask :: Text -> Text -> [Text] -> IO Task -createTask title project deps = do +createTask :: Text -> Text -> Maybe Text -> [Text] -> IO Task +createTask title project namespace deps = do tid <- generateId now <- getCurrentTime let task = @@ -104,6 +105,7 @@ createTask title project deps = do { taskId = tid, taskTitle = title, taskProject = project, + taskNamespace = namespace, taskStatus = Open, taskDependencies = deps, taskCreatedAt = now, @@ -169,6 +171,11 @@ printTask t = <> " (" <> taskProject t <> ")" + <> namespaceInfo + where + namespaceInfo = case taskNamespace t of + Nothing -> "" + Just ns -> " [" <> ns <> "]" -- Export tasks: Consolidate JSONL file (remove duplicates, keep latest version) exportTasks :: IO () -- cgit v1.2.3