feat(task): add team_name routing to task_get tool
- Add optional team_name parameter to task_get - Route to team-namespaced storage when team_name provided - Preserve existing behavior when team_name absent - Add tests for both team and regular task retrieval - Part of Task 12 (2/4 files complete)
This commit is contained in:
parent
eabc20de9e
commit
3d5754089e
@ -3,6 +3,7 @@ import { existsSync, rmSync, mkdirSync, writeFileSync } from "fs"
|
||||
import { join } from "path"
|
||||
import type { TaskObject } from "./types"
|
||||
import { createTaskGetTool } from "./task-get"
|
||||
import { writeTeamTask } from "../agent-teams/team-task-store"
|
||||
|
||||
const TEST_STORAGE = ".test-task-get-tool"
|
||||
const TEST_DIR = join(process.cwd(), TEST_STORAGE)
|
||||
@ -10,6 +11,7 @@ const TEST_CONFIG = {
|
||||
sisyphus: {
|
||||
tasks: {
|
||||
storage_path: TEST_STORAGE,
|
||||
claude_code_compat: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -218,5 +220,55 @@ describe("task_get tool", () => {
|
||||
expect(result.task.owner).toBeUndefined()
|
||||
expect(result.task.metadata).toBeUndefined()
|
||||
})
|
||||
|
||||
test("retrieves task from team namespace when team_name provided", async () => {
|
||||
//#given
|
||||
const teamName = "test-team"
|
||||
const taskId = "T-team-task-404"
|
||||
const taskData: TaskObject = {
|
||||
id: taskId,
|
||||
subject: "Team task",
|
||||
description: "Team description",
|
||||
status: "pending",
|
||||
blocks: [],
|
||||
blockedBy: [],
|
||||
threadID: TEST_SESSION_ID,
|
||||
}
|
||||
writeTeamTask(teamName, taskId, taskData)
|
||||
|
||||
//#when
|
||||
const resultStr = await tool.execute({ id: taskId, team_name: teamName }, TEST_CONTEXT)
|
||||
const result = JSON.parse(resultStr)
|
||||
|
||||
//#then
|
||||
expect(result).toHaveProperty("task")
|
||||
expect(result.task).not.toBeNull()
|
||||
expect(result.task.id).toBe(taskId)
|
||||
expect(result.task.subject).toBe("Team task")
|
||||
})
|
||||
|
||||
test("retrieves task from regular storage when no team_name", async () => {
|
||||
//#given
|
||||
const taskId = "T-regular-task-505"
|
||||
const taskData: TaskObject = {
|
||||
id: taskId,
|
||||
subject: "Regular task",
|
||||
description: "Regular",
|
||||
status: "pending",
|
||||
blocks: [],
|
||||
blockedBy: [],
|
||||
threadID: TEST_SESSION_ID,
|
||||
}
|
||||
const taskFile = join(TEST_DIR, `${taskId}.json`)
|
||||
writeFileSync(taskFile, JSON.stringify(taskData, null, 2))
|
||||
|
||||
//#when
|
||||
const resultStr = await tool.execute({ id: taskId }, TEST_CONTEXT)
|
||||
const result = JSON.parse(resultStr)
|
||||
|
||||
//#then
|
||||
expect(result.task).not.toBeNull()
|
||||
expect(result.task.subject).toBe("Regular task")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -4,6 +4,7 @@ import type { OhMyOpenCodeConfig } from "../../config/schema"
|
||||
import type { TaskGetInput } from "./types"
|
||||
import { TaskGetInputSchema, TaskObjectSchema } from "./types"
|
||||
import { getTaskDir, readJsonSafe } from "../../features/claude-tasks/storage"
|
||||
import { readTeamTask } from "../agent-teams/team-task-store"
|
||||
|
||||
const TASK_ID_PATTERN = /^T-[A-Za-z0-9-]+$/
|
||||
|
||||
@ -21,6 +22,7 @@ Returns the full task object including all fields: id, subject, description, sta
|
||||
Returns null if the task does not exist or the file is invalid.`,
|
||||
args: {
|
||||
id: tool.schema.string().describe("Task ID to retrieve (format: T-{uuid})"),
|
||||
team_name: tool.schema.string().optional().describe("Optional: team name for team-namespaced tasks"),
|
||||
},
|
||||
execute: async (args: Record<string, unknown>): Promise<string> => {
|
||||
try {
|
||||
@ -31,12 +33,15 @@ Returns null if the task does not exist or the file is invalid.`,
|
||||
return JSON.stringify({ error: "invalid_task_id" })
|
||||
}
|
||||
|
||||
const taskDir = getTaskDir(config)
|
||||
const taskPath = join(taskDir, `${taskId}.json`)
|
||||
|
||||
const task = readJsonSafe(taskPath, TaskObjectSchema)
|
||||
|
||||
return JSON.stringify({ task: task ?? null })
|
||||
if (validatedArgs.team_name) {
|
||||
const task = readTeamTask(validatedArgs.team_name, taskId)
|
||||
return JSON.stringify({ task: task ?? null })
|
||||
} else {
|
||||
const taskDir = getTaskDir(config)
|
||||
const taskPath = join(taskDir, `${taskId}.json`)
|
||||
const task = readJsonSafe(taskPath, TaskObjectSchema)
|
||||
return JSON.stringify({ task: task ?? null })
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes("validation")) {
|
||||
return JSON.stringify({ error: "invalid_arguments" })
|
||||
|
||||
@ -51,6 +51,7 @@ export type TaskListInput = z.infer<typeof TaskListInputSchema>
|
||||
|
||||
export const TaskGetInputSchema = z.object({
|
||||
id: z.string(),
|
||||
team_name: z.string().optional(),
|
||||
})
|
||||
|
||||
export type TaskGetInput = z.infer<typeof TaskGetInputSchema>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user