source dump of claude code
at main 138 lines 3.4 kB view raw
1import { z } from 'zod/v4' 2import { buildTool, type ToolDef } from '../../Tool.js' 3import { 4 executeTaskCreatedHooks, 5 getTaskCreatedHookMessage, 6} from '../../utils/hooks.js' 7import { lazySchema } from '../../utils/lazySchema.js' 8import { 9 createTask, 10 deleteTask, 11 getTaskListId, 12 isTodoV2Enabled, 13} from '../../utils/tasks.js' 14import { getAgentName, getTeamName } from '../../utils/teammate.js' 15import { TASK_CREATE_TOOL_NAME } from './constants.js' 16import { DESCRIPTION, getPrompt } from './prompt.js' 17 18const inputSchema = lazySchema(() => 19 z.strictObject({ 20 subject: z.string().describe('A brief title for the task'), 21 description: z.string().describe('What needs to be done'), 22 activeForm: z 23 .string() 24 .optional() 25 .describe( 26 'Present continuous form shown in spinner when in_progress (e.g., "Running tests")', 27 ), 28 metadata: z 29 .record(z.string(), z.unknown()) 30 .optional() 31 .describe('Arbitrary metadata to attach to the task'), 32 }), 33) 34type InputSchema = ReturnType<typeof inputSchema> 35 36const outputSchema = lazySchema(() => 37 z.object({ 38 task: z.object({ 39 id: z.string(), 40 subject: z.string(), 41 }), 42 }), 43) 44type OutputSchema = ReturnType<typeof outputSchema> 45 46export type Output = z.infer<OutputSchema> 47 48export const TaskCreateTool = buildTool({ 49 name: TASK_CREATE_TOOL_NAME, 50 searchHint: 'create a task in the task list', 51 maxResultSizeChars: 100_000, 52 async description() { 53 return DESCRIPTION 54 }, 55 async prompt() { 56 return getPrompt() 57 }, 58 get inputSchema(): InputSchema { 59 return inputSchema() 60 }, 61 get outputSchema(): OutputSchema { 62 return outputSchema() 63 }, 64 userFacingName() { 65 return 'TaskCreate' 66 }, 67 shouldDefer: true, 68 isEnabled() { 69 return isTodoV2Enabled() 70 }, 71 isConcurrencySafe() { 72 return true 73 }, 74 toAutoClassifierInput(input) { 75 return input.subject 76 }, 77 renderToolUseMessage() { 78 return null 79 }, 80 async call({ subject, description, activeForm, metadata }, context) { 81 const taskId = await createTask(getTaskListId(), { 82 subject, 83 description, 84 activeForm, 85 status: 'pending', 86 owner: undefined, 87 blocks: [], 88 blockedBy: [], 89 metadata, 90 }) 91 92 const blockingErrors: string[] = [] 93 const generator = executeTaskCreatedHooks( 94 taskId, 95 subject, 96 description, 97 getAgentName(), 98 getTeamName(), 99 undefined, 100 context?.abortController?.signal, 101 undefined, 102 context, 103 ) 104 for await (const result of generator) { 105 if (result.blockingError) { 106 blockingErrors.push(getTaskCreatedHookMessage(result.blockingError)) 107 } 108 } 109 110 if (blockingErrors.length > 0) { 111 await deleteTask(getTaskListId(), taskId) 112 throw new Error(blockingErrors.join('\n')) 113 } 114 115 // Auto-expand task list when creating tasks 116 context.setAppState(prev => { 117 if (prev.expandedView === 'tasks') return prev 118 return { ...prev, expandedView: 'tasks' as const } 119 }) 120 121 return { 122 data: { 123 task: { 124 id: taskId, 125 subject, 126 }, 127 }, 128 } 129 }, 130 mapToolResultToToolResultBlockParam(content, toolUseID) { 131 const { task } = content as Output 132 return { 133 tool_use_id: toolUseID, 134 type: 'tool_result', 135 content: `Task #${task.id} created successfully: ${task.subject}`, 136 } 137 }, 138} satisfies ToolDef<InputSchema, Output>)