source dump of claude code
at main 96 lines 3.7 kB view raw
1import { feature } from 'bun:bundle' 2import { randomUUID } from 'crypto' 3import { getSdkBetas, getSessionId } from 'src/bootstrap/state.js' 4import { DEFAULT_OUTPUT_STYLE_NAME } from 'src/constants/outputStyles.js' 5import type { 6 ApiKeySource, 7 PermissionMode, 8 SDKMessage, 9} from 'src/entrypoints/agentSdkTypes.js' 10import { 11 AGENT_TOOL_NAME, 12 LEGACY_AGENT_TOOL_NAME, 13} from 'src/tools/AgentTool/constants.js' 14import { getAnthropicApiKeyWithSource } from '../auth.js' 15import { getCwd } from '../cwd.js' 16import { getFastModeState } from '../fastMode.js' 17import { getSettings_DEPRECATED } from '../settings/settings.js' 18 19// TODO(next-minor): remove this translation once SDK consumers have migrated 20// to the 'Agent' tool name. The wire name was renamed Task → Agent in #19647, 21// but emitting the new name in init/result events broke SDK consumers on a 22// patch-level release. Keep emitting 'Task' until the next minor. 23export function sdkCompatToolName(name: string): string { 24 return name === AGENT_TOOL_NAME ? LEGACY_AGENT_TOOL_NAME : name 25} 26 27type CommandLike = { name: string; userInvocable?: boolean } 28 29export type SystemInitInputs = { 30 tools: ReadonlyArray<{ name: string }> 31 mcpClients: ReadonlyArray<{ name: string; type: string }> 32 model: string 33 permissionMode: PermissionMode 34 commands: ReadonlyArray<CommandLike> 35 agents: ReadonlyArray<{ agentType: string }> 36 skills: ReadonlyArray<CommandLike> 37 plugins: ReadonlyArray<{ name: string; path: string; source: string }> 38 fastMode: boolean | undefined 39} 40 41/** 42 * Build the `system/init` SDKMessage — the first message on the SDK stream 43 * carrying session metadata (cwd, tools, model, commands, etc.) that remote 44 * clients use to render pickers and gate UI. 45 * 46 * Called from two paths that must produce identical shapes: 47 * - QueryEngine (spawn-bridge / print-mode / SDK) — yielded as the first 48 * stream message per query turn 49 * - useReplBridge (REPL Remote Control) — sent via writeSdkMessages() on 50 * bridge connect, since REPL uses query() directly and never hits the 51 * QueryEngine SDKMessage layer 52 */ 53export function buildSystemInitMessage(inputs: SystemInitInputs): SDKMessage { 54 const settings = getSettings_DEPRECATED() 55 const outputStyle = settings?.outputStyle ?? DEFAULT_OUTPUT_STYLE_NAME 56 57 const initMessage: SDKMessage = { 58 type: 'system', 59 subtype: 'init', 60 cwd: getCwd(), 61 session_id: getSessionId(), 62 tools: inputs.tools.map(tool => sdkCompatToolName(tool.name)), 63 mcp_servers: inputs.mcpClients.map(client => ({ 64 name: client.name, 65 status: client.type, 66 })), 67 model: inputs.model, 68 permissionMode: inputs.permissionMode, 69 slash_commands: inputs.commands 70 .filter(c => c.userInvocable !== false) 71 .map(c => c.name), 72 apiKeySource: getAnthropicApiKeyWithSource().source as ApiKeySource, 73 betas: getSdkBetas(), 74 claude_code_version: MACRO.VERSION, 75 output_style: outputStyle, 76 agents: inputs.agents.map(agent => agent.agentType), 77 skills: inputs.skills 78 .filter(s => s.userInvocable !== false) 79 .map(skill => skill.name), 80 plugins: inputs.plugins.map(plugin => ({ 81 name: plugin.name, 82 path: plugin.path, 83 source: plugin.source, 84 })), 85 uuid: randomUUID(), 86 } 87 // Hidden from public SDK types — ant-only UDS messaging socket path 88 if (feature('UDS_INBOX')) { 89 /* eslint-disable @typescript-eslint/no-require-imports */ 90 ;(initMessage as Record<string, unknown>).messaging_socket_path = 91 require('../udsMessaging.js').getUdsMessagingSocketPath() 92 /* eslint-enable @typescript-eslint/no-require-imports */ 93 } 94 initMessage.fast_mode_state = getFastModeState(inputs.model, inputs.fastMode) 95 return initMessage 96}