source dump of claude code
at main 116 lines 2.8 kB view raw
1import { z } from 'zod/v4' 2import { buildTool, type ToolDef } from '../../Tool.js' 3import { lazySchema } from '../../utils/lazySchema.js' 4import { 5 getTaskListId, 6 isTodoV2Enabled, 7 listTasks, 8 TaskStatusSchema, 9} from '../../utils/tasks.js' 10import { TASK_LIST_TOOL_NAME } from './constants.js' 11import { DESCRIPTION, getPrompt } from './prompt.js' 12 13const inputSchema = lazySchema(() => z.strictObject({})) 14type InputSchema = ReturnType<typeof inputSchema> 15 16const outputSchema = lazySchema(() => 17 z.object({ 18 tasks: z.array( 19 z.object({ 20 id: z.string(), 21 subject: z.string(), 22 status: TaskStatusSchema(), 23 owner: z.string().optional(), 24 blockedBy: z.array(z.string()), 25 }), 26 ), 27 }), 28) 29type OutputSchema = ReturnType<typeof outputSchema> 30 31export type Output = z.infer<OutputSchema> 32 33export const TaskListTool = buildTool({ 34 name: TASK_LIST_TOOL_NAME, 35 searchHint: 'list all tasks', 36 maxResultSizeChars: 100_000, 37 async description() { 38 return DESCRIPTION 39 }, 40 async prompt() { 41 return getPrompt() 42 }, 43 get inputSchema(): InputSchema { 44 return inputSchema() 45 }, 46 get outputSchema(): OutputSchema { 47 return outputSchema() 48 }, 49 userFacingName() { 50 return 'TaskList' 51 }, 52 shouldDefer: true, 53 isEnabled() { 54 return isTodoV2Enabled() 55 }, 56 isConcurrencySafe() { 57 return true 58 }, 59 isReadOnly() { 60 return true 61 }, 62 renderToolUseMessage() { 63 return null 64 }, 65 async call() { 66 const taskListId = getTaskListId() 67 68 const allTasks = (await listTasks(taskListId)).filter( 69 t => !t.metadata?._internal, 70 ) 71 72 // Build a set of resolved task IDs for filtering 73 const resolvedTaskIds = new Set( 74 allTasks.filter(t => t.status === 'completed').map(t => t.id), 75 ) 76 77 const tasks = allTasks.map(task => ({ 78 id: task.id, 79 subject: task.subject, 80 status: task.status, 81 owner: task.owner, 82 blockedBy: task.blockedBy.filter(id => !resolvedTaskIds.has(id)), 83 })) 84 85 return { 86 data: { 87 tasks, 88 }, 89 } 90 }, 91 mapToolResultToToolResultBlockParam(content, toolUseID) { 92 const { tasks } = content as Output 93 if (tasks.length === 0) { 94 return { 95 tool_use_id: toolUseID, 96 type: 'tool_result', 97 content: 'No tasks found', 98 } 99 } 100 101 const lines = tasks.map(task => { 102 const owner = task.owner ? ` (${task.owner})` : '' 103 const blocked = 104 task.blockedBy.length > 0 105 ? ` [blocked by ${task.blockedBy.map(id => `#${id}`).join(', ')}]` 106 : '' 107 return `#${task.id} [${task.status}] ${task.subject}${owner}${blocked}` 108 }) 109 110 return { 111 tool_use_id: toolUseID, 112 type: 'tool_result', 113 content: lines.join('\n'), 114 } 115 }, 116} satisfies ToolDef<InputSchema, Output>)