Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
claude-code Task.ts
3.2 kB · 125 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126import { randomBytes } from 'crypto'import type { AppState } from './state/AppState.js'import type { AgentId } from './types/ids.js'import { getTaskOutputPath } from './utils/task/diskOutput.js'
export type TaskType = | 'local_bash' | 'local_agent' | 'remote_agent' | 'in_process_teammate' | 'local_workflow' | 'monitor_mcp' | 'dream'
export type TaskStatus = | 'pending' | 'running' | 'completed' | 'failed' | 'killed'
/** * True when a task is in a terminal state and will not transition further. * Used to guard against injecting messages into dead teammates, evicting * finished tasks from AppState, and orphan-cleanup paths. */export function isTerminalTaskStatus(status: TaskStatus): boolean { return status === 'completed' || status === 'failed' || status === 'killed'}
export type TaskHandle = { taskId: string cleanup?: () => void}
export type SetAppState = (f: (prev: AppState) => AppState) => void
export type TaskContext = { abortController: AbortController getAppState: () => AppState setAppState: SetAppState}
// Base fields shared by all task statesexport type TaskStateBase = { id: string type: TaskType status: TaskStatus description: string toolUseId?: string startTime: number endTime?: number totalPausedMs?: number outputFile: string outputOffset: number notified: boolean}
export type LocalShellSpawnInput = { command: string description: string timeout?: number toolUseId?: string agentId?: AgentId /** UI display variant: description-as-label, dialog title, status bar pill. */ kind?: 'bash' | 'monitor'}
// What getTaskByType dispatches for: kill. spawn/render were never// called polymorphically (removed in #22546). All six kill implementations// use only setAppState — getAppState/abortController were dead weight.export type Task = { name: string type: TaskType kill(taskId: string, setAppState: SetAppState): Promise<void>}
// Task ID prefixesconst TASK_ID_PREFIXES: Record<string, string> = { local_bash: 'b', // Keep as 'b' for backward compatibility local_agent: 'a', remote_agent: 'r', in_process_teammate: 't', local_workflow: 'w', monitor_mcp: 'm', dream: 'd',}
// Get task ID prefixfunction getTaskIdPrefix(type: TaskType): string { return TASK_ID_PREFIXES[type] ?? 'x'}
// Case-insensitive-safe alphabet (digits + lowercase) for task IDs.// 36^8 ≈ 2.8 trillion combinations, sufficient to resist brute-force symlink attacks.const TASK_ID_ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'
export function generateTaskId(type: TaskType): string { const prefix = getTaskIdPrefix(type) const bytes = randomBytes(8) let id = prefix for (let i = 0; i < 8; i++) { id += TASK_ID_ALPHABET[bytes[i]! % TASK_ID_ALPHABET.length] } return id}
export function createTaskStateBase( id: string, type: TaskType, description: string, toolUseId?: string,): TaskStateBase { return { id, type, status: 'pending', description, toolUseId, startTime: Date.now(), outputFile: getTaskOutputPath(id), outputOffset: 0, notified: false, }}