Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
4.1 kB · 134 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135import type { UUID } from 'crypto'import { randomUUID } from 'crypto'import { getIsNonInteractiveSession, getSessionId } from '../bootstrap/state.js'import type { SdkWorkflowProgress } from '../types/tools.js'
type TaskStartedEvent = { type: 'system' subtype: 'task_started' task_id: string tool_use_id?: string description: string task_type?: string workflow_name?: string prompt?: string}
type TaskProgressEvent = { type: 'system' subtype: 'task_progress' task_id: string tool_use_id?: string description: string usage: { total_tokens: number tool_uses: number duration_ms: number } last_tool_name?: string summary?: string // Delta batch of workflow state changes. Clients upsert by // `${type}:${index}` then group by phaseIndex to rebuild the phase tree, // same fold as collectFromEvents + groupByPhase in PhaseProgress.tsx. workflow_progress?: SdkWorkflowProgress[]}
// Emitted when a foreground agent completes without being backgrounded.// Drained by drainSdkEvents() directly into the output stream — does NOT// go through the print.ts XML task_notification parser and does NOT trigger// the LLM loop. Consumers (e.g. VS Code session.ts) use this to remove the// task from the subagent panel.type TaskNotificationSdkEvent = { type: 'system' subtype: 'task_notification' task_id: string tool_use_id?: string status: 'completed' | 'failed' | 'stopped' output_file: string summary: string usage?: { total_tokens: number tool_uses: number duration_ms: number }}
// Mirrors notifySessionStateChanged. The CCR bridge already receives this// via its own listener; SDK consumers (scmuxd, VS Code) need the same signal// to know when the main turn's generator is idle vs actively producing.// The 'idle' transition fires AFTER heldBackResult flushes and the bg-agent// do-while loop exits — so SDK consumers can trust it as the authoritative// "turn is over" signal even when result was withheld for background agents.type SessionStateChangedEvent = { type: 'system' subtype: 'session_state_changed' state: 'idle' | 'running' | 'requires_action'}
export type SdkEvent = | TaskStartedEvent | TaskProgressEvent | TaskNotificationSdkEvent | SessionStateChangedEvent
const MAX_QUEUE_SIZE = 1000const queue: SdkEvent[] = []
export function enqueueSdkEvent(event: SdkEvent): void { // SDK events are only consumed (drained) in headless/streaming mode. // In TUI mode they would accumulate up to the cap and never be read. if (!getIsNonInteractiveSession()) { return } if (queue.length >= MAX_QUEUE_SIZE) { queue.shift() } queue.push(event)}
export function drainSdkEvents(): Array< SdkEvent & { uuid: UUID; session_id: string }> { if (queue.length === 0) { return [] } const events = queue.splice(0) return events.map(e => ({ ...e, uuid: randomUUID(), session_id: getSessionId(), }))}
/** * Emit a task_notification SDK event for a task reaching a terminal state. * * registerTask() always emits task_started; this is the closing bookend. * Call this from any exit path that sets a task terminal WITHOUT going * through enqueuePendingNotification-with-<task-id> (print.ts parses that * XML into the same SDK event, so paths that do both would double-emit). * Paths that suppress the XML notification (notified:true pre-set, kill * paths, abort branches) must call this directly so SDK consumers * (Scuttle's bg-task dot, VS Code subagent panel) see the task close. */export function emitTaskTerminatedSdk( taskId: string, status: 'completed' | 'failed' | 'stopped', opts?: { toolUseId?: string summary?: string outputFile?: string usage?: { total_tokens: number; tool_uses: number; duration_ms: number } },): void { enqueueSdkEvent({ type: 'system', subtype: 'task_notification', task_id: taskId, tool_use_id: opts?.toolUseId, status, output_file: opts?.outputFile ?? '', summary: opts?.summary ?? '', usage: opts?.usage, })}