@within-7/minto 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/query.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/query.ts"],
4
- "sourcesContent": ["import {\n Message as APIAssistantMessage,\n MessageParam,\n ToolUseBlock,\n} from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { UUID } from './types/common'\nimport type { Tool, ToolUseContext } from './Tool'\nimport {\n messagePairValidForBinaryFeedback,\n shouldUseBinaryFeedback,\n} from '@components/binary-feedback/utils'\nimport { CanUseToolFn } from './hooks/useCanUseTool'\nimport {\n formatSystemPromptWithContext,\n queryLLM,\n queryModel,\n} from '@services/claude'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { all } from '@utils/generators'\nimport { logError } from '@utils/log'\nimport {\n debug,\n markPhase,\n getCurrentRequest,\n logUserFriendly,\n} from './utils/debugLogger'\nimport { getModelManager } from '@utils/model'\nimport {\n createAssistantMessage,\n createProgressMessage,\n createToolResultStopMessage,\n createUserMessage,\n FullToolUseResult,\n INTERRUPT_MESSAGE,\n INTERRUPT_MESSAGE_FOR_TOOL_USE,\n NormalizedMessage,\n normalizeMessagesForAPI,\n} from '@utils/messages'\nimport { createToolExecutionController } from '@utils/toolExecutionController'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { getCwd } from './utils/state'\nimport { checkAutoCompact } from './utils/autoCompactCore'\nimport { getHookManager } from '@utils/hookManager'\n\n// Extended ToolUseContext for query functions\ninterface ExtendedToolUseContext extends ToolUseContext {\n abortController: AbortController\n options: {\n commands: any[]\n forkNumber: number\n messageLogName: string\n tools: Tool[]\n verbose: boolean\n safeMode: boolean\n maxThinkingTokens: number\n isKodingRequest?: boolean\n model?: string | import('./utils/config').ModelPointerType\n }\n readFileTimestamps: { [filename: string]: number }\n setToolJSX: (jsx: any) => void\n requestId?: string\n}\n\nexport type Response = { costUSD: number; response: string }\nexport type UserMessage = {\n message: MessageParam\n type: 'user'\n uuid: UUID\n toolUseResult?: FullToolUseResult\n options?: {\n isKodingRequest?: boolean\n kodingContext?: string\n isCustomCommand?: boolean\n commandName?: string\n commandArgs?: string\n }\n}\n\nexport type AssistantMessage = {\n costUSD: number\n durationMs: number\n message: APIAssistantMessage\n type: 'assistant'\n uuid: UUID\n isApiErrorMessage?: boolean\n responseId?: string // For GPT-5 Responses API state management\n}\n\nexport type BinaryFeedbackResult =\n | { message: AssistantMessage | null; shouldSkipPermissionCheck: false }\n | { message: AssistantMessage; shouldSkipPermissionCheck: true }\n\nexport type ProgressMessage = {\n content: AssistantMessage\n normalizedMessages: NormalizedMessage[]\n siblingToolUseIDs: Set<string>\n tools: Tool[]\n toolUseID: string\n type: 'progress'\n uuid: UUID\n}\n\n// Each array item is either a single message or a message-and-response pair\nexport type Message = UserMessage | AssistantMessage | ProgressMessage\n\nconst MAX_TOOL_USE_CONCURRENCY = 10\n\n// Returns a message if we got one, or `null` if the user cancelled\nasync function queryWithBinaryFeedback(\n toolUseContext: ExtendedToolUseContext,\n getAssistantResponse: () => Promise<AssistantMessage>,\n getBinaryFeedbackResponse?: (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ) => Promise<BinaryFeedbackResult>,\n): Promise<BinaryFeedbackResult> {\n if (\n process.env.USER_TYPE !== 'ant' ||\n !getBinaryFeedbackResponse ||\n !(await shouldUseBinaryFeedback())\n ) {\n const assistantMessage = await getAssistantResponse()\n if (toolUseContext.abortController.signal.aborted) {\n return { message: null, shouldSkipPermissionCheck: false }\n }\n return { message: assistantMessage, shouldSkipPermissionCheck: false }\n }\n const [m1, m2] = await Promise.all([\n getAssistantResponse(),\n getAssistantResponse(),\n ])\n if (toolUseContext.abortController.signal.aborted) {\n return { message: null, shouldSkipPermissionCheck: false }\n }\n if (m2.isApiErrorMessage) {\n // If m2 is an error, we might as well return m1, even if it's also an error --\n // the UI will display it as an error as it would in the non-feedback path.\n return { message: m1, shouldSkipPermissionCheck: false }\n }\n if (m1.isApiErrorMessage) {\n return { message: m2, shouldSkipPermissionCheck: false }\n }\n if (!messagePairValidForBinaryFeedback(m1, m2)) {\n return { message: m1, shouldSkipPermissionCheck: false }\n }\n return await getBinaryFeedbackResponse(m1, m2)\n}\n\n/**\n * The rules of thinking are lengthy and fortuitous. They require plenty of thinking\n * of most long duration and deep meditation for a wizard to wrap one's noggin around.\n *\n * The rules follow:\n * 1. A message that contains a thinking or redacted_thinking block must be part of a query whose max_thinking_length > 0\n * 2. A thinking block may not be the last message in a block\n * 3. Thinking blocks must be preserved for the duration of an assistant trajectory (a single turn, or if that turn includes a tool_use block then also its subsequent tool_result and the following assistant message)\n *\n * Heed these rules well, young wizard. For they are the rules of thinking, and\n * the rules of thinking are the rules of the universe. If ye does not heed these\n * rules, ye will be punished with an entire day of debugging and hair pulling.\n */\nexport async function* query(\n messages: Message[],\n systemPrompt: string[],\n context: { [k: string]: string },\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n getBinaryFeedbackResponse?: (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ) => Promise<BinaryFeedbackResult>,\n): AsyncGenerator<Message, void> {\n const currentRequest = getCurrentRequest()\n\n markPhase('QUERY_INIT')\n\n // Auto-compact check\n const { messages: processedMessages, wasCompacted } = await checkAutoCompact(\n messages,\n toolUseContext,\n )\n if (wasCompacted) {\n messages = processedMessages\n }\n\n markPhase('SYSTEM_PROMPT_BUILD')\n \n const { systemPrompt: fullSystemPrompt, reminders } =\n formatSystemPromptWithContext(systemPrompt, context, toolUseContext.agentId)\n\n // Emit session startup event\n emitReminderEvent('session:startup', {\n agentId: toolUseContext.agentId,\n messages: messages.length,\n timestamp: Date.now(),\n })\n\n // Inject reminders into the latest user message\n if (reminders && messages.length > 0) {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg?.type === 'user') {\n const lastUserMessage = msg as UserMessage\n messages[i] = {\n ...lastUserMessage,\n message: {\n ...lastUserMessage.message,\n content:\n typeof lastUserMessage.message.content === 'string'\n ? reminders + lastUserMessage.message.content\n : [\n ...(Array.isArray(lastUserMessage.message.content)\n ? lastUserMessage.message.content\n : []),\n { type: 'text', text: reminders },\n ],\n },\n }\n break\n }\n }\n }\n\n markPhase('LLM_PREPARATION')\n\n function getAssistantResponse() {\n return queryLLM(\n normalizeMessagesForAPI(messages),\n fullSystemPrompt,\n toolUseContext.options.maxThinkingTokens,\n toolUseContext.options.tools,\n toolUseContext.abortController.signal,\n {\n safeMode: toolUseContext.options.safeMode ?? false,\n model: toolUseContext.options.model || 'main',\n prependCLISysprompt: true,\n toolUseContext: toolUseContext,\n },\n )\n }\n\n const result = await queryWithBinaryFeedback(\n toolUseContext,\n getAssistantResponse,\n getBinaryFeedbackResponse,\n )\n\n // If request was cancelled, return immediately with interrupt message \n if (toolUseContext.abortController.signal.aborted) {\n yield createAssistantMessage(INTERRUPT_MESSAGE)\n return\n }\n\n if (result.message === null) {\n yield createAssistantMessage(INTERRUPT_MESSAGE)\n return\n }\n\n const assistantMessage = result.message\n const shouldSkipPermissionCheck = result.shouldSkipPermissionCheck\n\n yield assistantMessage\n\n // @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use\n // Note: stop_reason === 'tool_use' is unreliable -- it's not always set correctly\n const toolUseMessages = assistantMessage.message.content.filter(\n _ => _.type === 'tool_use',\n )\n\n // If there's no more tool use, we're done\n if (!toolUseMessages.length) {\n return\n }\n\n const toolResults: UserMessage[] = []\n \n // Simple concurrency check like original system\n const canRunConcurrently = toolUseMessages.every(msg =>\n toolUseContext.options.tools.find(t => t.name === msg.name)?.isReadOnly(),\n )\n\n if (canRunConcurrently) {\n for await (const message of runToolsConcurrently(\n toolUseMessages,\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )) {\n yield message\n // progress messages are not sent to the server, so don't need to be accumulated for the next turn\n if (message.type === 'user') {\n toolResults.push(message)\n }\n }\n } else {\n for await (const message of runToolsSerially(\n toolUseMessages,\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )) {\n yield message\n // progress messages are not sent to the server, so don't need to be accumulated for the next turn\n if (message.type === 'user') {\n toolResults.push(message)\n }\n }\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n yield createAssistantMessage(INTERRUPT_MESSAGE_FOR_TOOL_USE)\n return\n }\n\n // Sort toolResults to match the order of toolUseMessages\n const orderedToolResults = toolResults.sort((a, b) => {\n const aIndex = toolUseMessages.findIndex(\n tu => tu.id === (a.message.content[0] as ToolUseBlock).id,\n )\n const bIndex = toolUseMessages.findIndex(\n tu => tu.id === (b.message.content[0] as ToolUseBlock).id,\n )\n return aIndex - bIndex\n })\n\n // Recursive query\n\n try {\n yield* await query(\n [...messages, assistantMessage, ...orderedToolResults],\n systemPrompt,\n context,\n canUseTool,\n toolUseContext,\n getBinaryFeedbackResponse,\n )\n } catch (error) {\n // Re-throw the error to maintain the original behavior\n throw error\n }\n}\n\nasync function* runToolsConcurrently(\n toolUseMessages: ToolUseBlock[],\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n yield* all(\n toolUseMessages.map(toolUse =>\n runToolUse(\n toolUse,\n new Set(toolUseMessages.map(_ => _.id)),\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n ),\n ),\n MAX_TOOL_USE_CONCURRENCY,\n )\n}\n\nasync function* runToolsSerially(\n toolUseMessages: ToolUseBlock[],\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n for (const toolUse of toolUseMessages) {\n yield* runToolUse(\n toolUse,\n new Set(toolUseMessages.map(_ => _.id)),\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )\n }\n}\n\nexport async function* runToolUse(\n toolUse: ToolUseBlock,\n siblingToolUseIDs: Set<string>,\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n const currentRequest = getCurrentRequest()\n\n // \uD83D\uDD0D Debug: \u5DE5\u5177\u8C03\u7528\u5F00\u59CB\n debug.flow('TOOL_USE_START', {\n toolName: toolUse.name,\n toolUseID: toolUse.id,\n inputSize: JSON.stringify(toolUse.input).length,\n siblingToolCount: siblingToolUseIDs.size,\n shouldSkipPermissionCheck: !!shouldSkipPermissionCheck,\n requestId: currentRequest?.id,\n })\n\n logUserFriendly(\n 'TOOL_EXECUTION',\n {\n toolName: toolUse.name,\n action: 'Starting',\n target: toolUse.input ? Object.keys(toolUse.input).join(', ') : '',\n },\n currentRequest?.id,\n )\n\n\n \n\n const toolName = toolUse.name\n const tool = toolUseContext.options.tools.find(t => t.name === toolName)\n\n // Check if the tool exists\n if (!tool) {\n debug.error('TOOL_NOT_FOUND', {\n requestedTool: toolName,\n availableTools: toolUseContext.options.tools.map(t => t.name),\n toolUseID: toolUse.id,\n requestId: currentRequest?.id,\n })\n\n \n\n yield createUserMessage([\n {\n type: 'tool_result',\n content: `Error: No such tool available: ${toolName}`,\n is_error: true,\n tool_use_id: toolUse.id,\n },\n ])\n return\n }\n\n const toolInput = toolUse.input as { [key: string]: string }\n\n debug.flow('TOOL_VALIDATION_START', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n inputKeys: Object.keys(toolInput),\n requestId: currentRequest?.id,\n })\n\n try {\n // \uD83D\uDD27 Check for cancellation before starting tool execution\n if (toolUseContext.abortController.signal.aborted) {\n debug.flow('TOOL_USE_CANCELLED_BEFORE_START', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n abortReason: 'AbortController signal',\n requestId: currentRequest?.id,\n })\n\n \n\n const message = createUserMessage([\n createToolResultStopMessage(toolUse.id),\n ])\n yield message\n return\n }\n\n // Track if any progress messages were yielded\n let hasProgressMessages = false\n \n for await (const message of checkPermissionsAndCallTool(\n tool,\n toolUse.id,\n siblingToolUseIDs,\n toolInput,\n toolUseContext,\n canUseTool,\n assistantMessage,\n shouldSkipPermissionCheck,\n )) {\n // \uD83D\uDD27 Check for cancellation during tool execution\n if (toolUseContext.abortController.signal.aborted) {\n debug.flow('TOOL_USE_CANCELLED_DURING_EXECUTION', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n hasProgressMessages,\n abortReason: 'AbortController signal during execution',\n requestId: currentRequest?.id,\n })\n\n // If we yielded progress messages but got cancelled, yield a cancellation result\n if (hasProgressMessages && message.type === 'progress') {\n yield message // yield the last progress message first\n }\n \n // Always yield a tool result message for cancellation to clear UI state\n const cancelMessage = createUserMessage([\n createToolResultStopMessage(toolUse.id),\n ])\n yield cancelMessage\n return\n }\n\n if (message.type === 'progress') {\n hasProgressMessages = true\n }\n \n yield message\n }\n } catch (e) {\n logError(e)\n \n // \uD83D\uDD27 Even on error, ensure we yield a tool result to clear UI state\n const errorMessage = createUserMessage([\n {\n type: 'tool_result',\n content: `Tool execution failed: ${e instanceof Error ? e.message : String(e)}`,\n is_error: true,\n tool_use_id: toolUse.id,\n },\n ])\n yield errorMessage\n }\n}\n\n// TODO: Generalize this to all tools\nexport function normalizeToolInput(\n tool: Tool,\n input: { [key: string]: boolean | string | number },\n): { [key: string]: boolean | string | number } {\n switch (tool) {\n case BashTool: {\n const { command, timeout } = BashTool.inputSchema.parse(input) // already validated upstream, won't throw\n return {\n command: command.replace(`cd ${getCwd()} && `, ''),\n ...(timeout ? { timeout } : {}),\n }\n }\n default:\n return input\n }\n}\n\nasync function* checkPermissionsAndCallTool(\n tool: Tool,\n toolUseID: string,\n siblingToolUseIDs: Set<string>,\n input: { [key: string]: boolean | string | number },\n context: ToolUseContext,\n canUseTool: CanUseToolFn,\n assistantMessage: AssistantMessage,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<UserMessage | ProgressMessage, void> {\n // Validate input types with zod\n // (surprisingly, the model is not great at generating valid input)\n const isValidInput = tool.inputSchema.safeParse(input)\n if (!isValidInput.success) {\n // Create a more helpful error message for common cases\n let errorMessage = `InputValidationError: ${isValidInput.error.message}`\n \n // Special handling for the \"View\" tool (FileReadTool) being called with empty parameters\n if (tool.name === 'View' && Object.keys(input).length === 0) {\n errorMessage = `Error: The View tool requires a 'file_path' parameter to specify which file to read. Please provide the absolute path to the file you want to view. For example: {\"file_path\": \"/path/to/file.txt\"}`\n }\n \n \n yield createUserMessage([\n {\n type: 'tool_result',\n content: errorMessage,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n const normalizedInput = normalizeToolInput(tool, input)\n\n // Validate input values. Each tool has its own validation logic\n const isValidCall = await tool.validateInput?.(\n normalizedInput as never,\n context,\n )\n if (isValidCall?.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: isValidCall!.message,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n // Check whether we have permission to use the tool,\n // and ask the user for permission if we don't\n const permissionResult = shouldSkipPermissionCheck\n ? ({ result: true } as const)\n : await canUseTool(tool, normalizedInput, context, assistantMessage)\n if (permissionResult.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: permissionResult.message,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n // PreToolUse hooks\n const hookManager = getHookManager()\n if (hookManager) {\n try {\n const decision = await hookManager.executePreToolUse(\n tool.name,\n normalizedInput as Record<string, unknown>,\n )\n\n if (!decision.shouldContinue) {\n if (decision.shouldAskUser) {\n // Ask user for approval via permission system\n const approved = await canUseTool(tool, normalizedInput, context, assistantMessage)\n if (approved.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: decision.reason || 'Hook requested approval but user denied',\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n } else {\n // Hook blocked the tool\n yield createUserMessage([\n {\n type: 'tool_result',\n content: decision.reason || 'Tool execution blocked by hook',\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n }\n } catch (error) {\n debug.error('PreToolUse hook failed', { error })\n // Continue on error (fail-safe)\n }\n }\n\n // Call the tool\n let toolOutput: Record<string, unknown> | null = null\n try {\n const generator = tool.call(normalizedInput as never, context)\n for await (const result of generator) {\n switch (result.type) {\n case 'result':\n toolOutput = {\n data: result.data,\n resultForAssistant: result.resultForAssistant || String(result.data),\n }\n\n yield createUserMessage(\n [\n {\n type: 'tool_result',\n content: result.resultForAssistant || String(result.data),\n tool_use_id: toolUseID,\n },\n ],\n toolOutput as Record<string, unknown>,\n )\n\n // PostToolUse hooks (fire-and-forget)\n if (hookManager && toolOutput) {\n hookManager.executePostToolUse(\n tool.name,\n normalizedInput as Record<string, unknown>,\n toolOutput as any,\n ).catch(err => {\n debug.error('PostToolUse hook failed', { error: err })\n })\n }\n\n return\n case 'progress':\n \n yield createProgressMessage(\n toolUseID,\n siblingToolUseIDs,\n result.content,\n result.normalizedMessages || [],\n result.tools || [],\n )\n break\n }\n }\n } catch (error) {\n const content = formatError(error)\n logError(error)\n \n yield createUserMessage([\n {\n type: 'tool_result',\n content,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n }\n}\n\nfunction formatError(error: unknown): string {\n if (!(error instanceof Error)) {\n return String(error)\n }\n const parts = [error.message]\n if ('stderr' in error && typeof error.stderr === 'string') {\n parts.push(error.stderr)\n }\n if ('stdout' in error && typeof error.stdout === 'string') {\n parts.push(error.stdout)\n }\n const fullMessage = parts.filter(Boolean).join('\\n')\n if (fullMessage.length <= 10000) {\n return fullMessage\n }\n const halfLength = 5000\n const start = fullMessage.slice(0, halfLength)\n const end = fullMessage.slice(-halfLength)\n return `${start}\\n\\n... [${fullMessage.length - 10000} characters truncated] ...\\n\\n${end}`\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n Message as APIAssistantMessage,\n MessageParam,\n ToolUseBlock,\n} from '@anthropic-ai/sdk/resources/index.mjs'\nimport type { UUID } from './types/common'\nimport type { Tool, ToolUseContext } from './Tool'\nimport {\n messagePairValidForBinaryFeedback,\n shouldUseBinaryFeedback,\n} from '@components/binary-feedback/utils'\nimport { CanUseToolFn } from './hooks/useCanUseTool'\nimport {\n formatSystemPromptWithContext,\n queryLLM,\n queryModel,\n} from '@services/claude'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { all } from '@utils/generators'\nimport { logError } from '@utils/log'\nimport {\n debug,\n markPhase,\n getCurrentRequest,\n logUserFriendly,\n} from './utils/debugLogger'\nimport { getModelManager } from '@utils/model'\nimport {\n createAssistantMessage,\n createProgressMessage,\n createToolResultStopMessage,\n createUserMessage,\n FullToolUseResult,\n INTERRUPT_MESSAGE,\n INTERRUPT_MESSAGE_FOR_TOOL_USE,\n NormalizedMessage,\n normalizeMessagesForAPI,\n} from '@utils/messages'\nimport { createToolExecutionController } from '@utils/toolExecutionController'\nimport { BashTool } from '@tools/BashTool/BashTool'\nimport { getCwd } from './utils/state'\nimport { checkAutoCompact } from './utils/autoCompactCore'\nimport { getHookManager } from '@utils/hookManager'\n\n// Extended ToolUseContext for query functions\ninterface ExtendedToolUseContext extends ToolUseContext {\n abortController: AbortController\n options: {\n commands: any[]\n forkNumber: number\n messageLogName: string\n tools: Tool[]\n verbose: boolean\n safeMode: boolean\n maxThinkingTokens: number\n isKodingRequest?: boolean\n model?: string | import('./utils/config').ModelPointerType\n }\n readFileTimestamps: { [filename: string]: number }\n setToolJSX: (jsx: any) => void\n requestId?: string\n}\n\nexport type Response = { costUSD: number; response: string }\nexport type UserMessage = {\n message: MessageParam\n type: 'user'\n uuid: UUID\n toolUseResult?: FullToolUseResult\n options?: {\n isKodingRequest?: boolean\n kodingContext?: string\n isCustomCommand?: boolean\n commandName?: string\n commandArgs?: string\n }\n}\n\nexport type AssistantMessage = {\n costUSD: number\n durationMs: number\n message: APIAssistantMessage\n type: 'assistant'\n uuid: UUID\n isApiErrorMessage?: boolean\n responseId?: string // For GPT-5 Responses API state management\n}\n\nexport type BinaryFeedbackResult =\n | { message: AssistantMessage | null; shouldSkipPermissionCheck: false }\n | { message: AssistantMessage; shouldSkipPermissionCheck: true }\n\nexport type ProgressMessage = {\n content: AssistantMessage\n normalizedMessages: NormalizedMessage[]\n siblingToolUseIDs: Set<string>\n tools: Tool[]\n toolUseID: string\n type: 'progress'\n uuid: UUID\n}\n\n// Each array item is either a single message or a message-and-response pair\nexport type Message = UserMessage | AssistantMessage | ProgressMessage\n\nconst MAX_TOOL_USE_CONCURRENCY = 10\n\n// Returns a message if we got one, or `null` if the user cancelled\nasync function queryWithBinaryFeedback(\n toolUseContext: ExtendedToolUseContext,\n getAssistantResponse: () => Promise<AssistantMessage>,\n getBinaryFeedbackResponse?: (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ) => Promise<BinaryFeedbackResult>,\n): Promise<BinaryFeedbackResult> {\n if (\n process.env.USER_TYPE !== 'ant' ||\n !getBinaryFeedbackResponse ||\n !(await shouldUseBinaryFeedback())\n ) {\n const assistantMessage = await getAssistantResponse()\n if (toolUseContext.abortController.signal.aborted) {\n return { message: null, shouldSkipPermissionCheck: false }\n }\n return { message: assistantMessage, shouldSkipPermissionCheck: false }\n }\n const [m1, m2] = await Promise.all([\n getAssistantResponse(),\n getAssistantResponse(),\n ])\n if (toolUseContext.abortController.signal.aborted) {\n return { message: null, shouldSkipPermissionCheck: false }\n }\n if (m2.isApiErrorMessage) {\n // If m2 is an error, we might as well return m1, even if it's also an error --\n // the UI will display it as an error as it would in the non-feedback path.\n return { message: m1, shouldSkipPermissionCheck: false }\n }\n if (m1.isApiErrorMessage) {\n return { message: m2, shouldSkipPermissionCheck: false }\n }\n if (!messagePairValidForBinaryFeedback(m1, m2)) {\n return { message: m1, shouldSkipPermissionCheck: false }\n }\n return await getBinaryFeedbackResponse(m1, m2)\n}\n\n/**\n * The rules of thinking are lengthy and fortuitous. They require plenty of thinking\n * of most long duration and deep meditation for a wizard to wrap one's noggin around.\n *\n * The rules follow:\n * 1. A message that contains a thinking or redacted_thinking block must be part of a query whose max_thinking_length > 0\n * 2. A thinking block may not be the last message in a block\n * 3. Thinking blocks must be preserved for the duration of an assistant trajectory (a single turn, or if that turn includes a tool_use block then also its subsequent tool_result and the following assistant message)\n *\n * Heed these rules well, young wizard. For they are the rules of thinking, and\n * the rules of thinking are the rules of the universe. If ye does not heed these\n * rules, ye will be punished with an entire day of debugging and hair pulling.\n */\nexport async function* query(\n messages: Message[],\n systemPrompt: string[],\n context: { [k: string]: string },\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n getBinaryFeedbackResponse?: (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ) => Promise<BinaryFeedbackResult>,\n): AsyncGenerator<Message, void> {\n const currentRequest = getCurrentRequest()\n\n markPhase('QUERY_INIT')\n\n // Auto-compact check\n const { messages: processedMessages, wasCompacted } = await checkAutoCompact(\n messages,\n toolUseContext,\n )\n if (wasCompacted) {\n messages = processedMessages\n }\n\n markPhase('SYSTEM_PROMPT_BUILD')\n \n const { systemPrompt: fullSystemPrompt, reminders } =\n formatSystemPromptWithContext(systemPrompt, context, toolUseContext.agentId)\n\n // Emit session startup event\n emitReminderEvent('session:startup', {\n agentId: toolUseContext.agentId,\n messages: messages.length,\n timestamp: Date.now(),\n })\n\n // Inject reminders into the latest user message\n if (reminders && messages.length > 0) {\n // Find the last user message\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg?.type === 'user') {\n const lastUserMessage = msg as UserMessage\n messages[i] = {\n ...lastUserMessage,\n message: {\n ...lastUserMessage.message,\n content:\n typeof lastUserMessage.message.content === 'string'\n ? reminders + lastUserMessage.message.content\n : [\n ...(Array.isArray(lastUserMessage.message.content)\n ? lastUserMessage.message.content\n : []),\n { type: 'text', text: reminders },\n ],\n },\n }\n break\n }\n }\n }\n\n markPhase('LLM_PREPARATION')\n\n function getAssistantResponse() {\n return queryLLM(\n normalizeMessagesForAPI(messages),\n fullSystemPrompt,\n toolUseContext.options.maxThinkingTokens,\n toolUseContext.options.tools,\n toolUseContext.abortController.signal,\n {\n safeMode: toolUseContext.options.safeMode ?? false,\n model: toolUseContext.options.model || 'main',\n prependCLISysprompt: true,\n toolUseContext: toolUseContext,\n },\n )\n }\n\n const result = await queryWithBinaryFeedback(\n toolUseContext,\n getAssistantResponse,\n getBinaryFeedbackResponse,\n )\n\n // If request was cancelled, return immediately with interrupt message \n if (toolUseContext.abortController.signal.aborted) {\n yield createAssistantMessage(INTERRUPT_MESSAGE)\n return\n }\n\n if (result.message === null) {\n yield createAssistantMessage(INTERRUPT_MESSAGE)\n return\n }\n\n const assistantMessage = result.message\n const shouldSkipPermissionCheck = result.shouldSkipPermissionCheck\n\n yield assistantMessage\n\n // @see https://docs.anthropic.com/en/docs/build-with-claude/tool-use\n // Note: stop_reason === 'tool_use' is unreliable -- it's not always set correctly\n const toolUseMessages = assistantMessage.message.content.filter(\n _ => _.type === 'tool_use',\n )\n\n // If there's no more tool use, we're done\n if (!toolUseMessages.length) {\n return\n }\n\n const toolResults: UserMessage[] = []\n \n // Simple concurrency check like original system\n const canRunConcurrently = toolUseMessages.every(msg =>\n toolUseContext.options.tools.find(t => t.name === msg.name)?.isReadOnly(),\n )\n\n if (canRunConcurrently) {\n for await (const message of runToolsConcurrently(\n toolUseMessages,\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )) {\n yield message\n // progress messages are not sent to the server, so don't need to be accumulated for the next turn\n if (message.type === 'user') {\n toolResults.push(message)\n }\n }\n } else {\n for await (const message of runToolsSerially(\n toolUseMessages,\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )) {\n yield message\n // progress messages are not sent to the server, so don't need to be accumulated for the next turn\n if (message.type === 'user') {\n toolResults.push(message)\n }\n }\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n yield createAssistantMessage(INTERRUPT_MESSAGE_FOR_TOOL_USE)\n return\n }\n\n // Sort toolResults to match the order of toolUseMessages\n const orderedToolResults = toolResults.sort((a, b) => {\n const aIndex = toolUseMessages.findIndex(\n tu => tu.id === (a.message.content[0] as ToolUseBlock).id,\n )\n const bIndex = toolUseMessages.findIndex(\n tu => tu.id === (b.message.content[0] as ToolUseBlock).id,\n )\n return aIndex - bIndex\n })\n\n // Recursive query\n\n try {\n yield* await query(\n [...messages, assistantMessage, ...orderedToolResults],\n systemPrompt,\n context,\n canUseTool,\n toolUseContext,\n getBinaryFeedbackResponse,\n )\n } catch (error) {\n // Re-throw the error to maintain the original behavior\n throw error\n }\n}\n\nasync function* runToolsConcurrently(\n toolUseMessages: ToolUseBlock[],\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n yield* all(\n toolUseMessages.map(toolUse =>\n runToolUse(\n toolUse,\n new Set(toolUseMessages.map(_ => _.id)),\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n ),\n ),\n MAX_TOOL_USE_CONCURRENCY,\n )\n}\n\nasync function* runToolsSerially(\n toolUseMessages: ToolUseBlock[],\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n for (const toolUse of toolUseMessages) {\n yield* runToolUse(\n toolUse,\n new Set(toolUseMessages.map(_ => _.id)),\n assistantMessage,\n canUseTool,\n toolUseContext,\n shouldSkipPermissionCheck,\n )\n }\n}\n\nexport async function* runToolUse(\n toolUse: ToolUseBlock,\n siblingToolUseIDs: Set<string>,\n assistantMessage: AssistantMessage,\n canUseTool: CanUseToolFn,\n toolUseContext: ExtendedToolUseContext,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<Message, void> {\n const currentRequest = getCurrentRequest()\n\n // \uD83D\uDD0D Debug: \u5DE5\u5177\u8C03\u7528\u5F00\u59CB\n debug.flow('TOOL_USE_START', {\n toolName: toolUse.name,\n toolUseID: toolUse.id,\n inputSize: JSON.stringify(toolUse.input).length,\n siblingToolCount: siblingToolUseIDs.size,\n shouldSkipPermissionCheck: !!shouldSkipPermissionCheck,\n requestId: currentRequest?.id,\n })\n\n logUserFriendly(\n 'TOOL_EXECUTION',\n {\n toolName: toolUse.name,\n action: 'Starting',\n target: toolUse.input ? Object.keys(toolUse.input).join(', ') : '',\n },\n currentRequest?.id,\n )\n\n\n \n\n const toolName = toolUse.name\n const tool = toolUseContext.options.tools.find(t => t.name === toolName)\n\n // Check if the tool exists\n if (!tool) {\n debug.error('TOOL_NOT_FOUND', {\n requestedTool: toolName,\n availableTools: toolUseContext.options.tools.map(t => t.name),\n toolUseID: toolUse.id,\n requestId: currentRequest?.id,\n })\n\n \n\n yield createUserMessage([\n {\n type: 'tool_result',\n content: `Error: No such tool available: ${toolName}`,\n is_error: true,\n tool_use_id: toolUse.id,\n },\n ])\n return\n }\n\n const toolInput = toolUse.input as { [key: string]: string }\n\n debug.flow('TOOL_VALIDATION_START', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n inputKeys: Object.keys(toolInput),\n requestId: currentRequest?.id,\n })\n\n try {\n // \uD83D\uDD27 Check for cancellation before starting tool execution\n if (toolUseContext.abortController.signal.aborted) {\n debug.flow('TOOL_USE_CANCELLED_BEFORE_START', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n abortReason: 'AbortController signal',\n requestId: currentRequest?.id,\n })\n\n \n\n const message = createUserMessage([\n createToolResultStopMessage(toolUse.id),\n ])\n yield message\n return\n }\n\n // Track if any progress messages were yielded\n let hasProgressMessages = false\n \n for await (const message of checkPermissionsAndCallTool(\n tool,\n toolUse.id,\n siblingToolUseIDs,\n toolInput,\n toolUseContext,\n canUseTool,\n assistantMessage,\n shouldSkipPermissionCheck,\n )) {\n // \uD83D\uDD27 Check for cancellation during tool execution\n if (toolUseContext.abortController.signal.aborted) {\n debug.flow('TOOL_USE_CANCELLED_DURING_EXECUTION', {\n toolName: tool.name,\n toolUseID: toolUse.id,\n hasProgressMessages,\n abortReason: 'AbortController signal during execution',\n requestId: currentRequest?.id,\n })\n\n // If we yielded progress messages but got cancelled, yield a cancellation result\n if (hasProgressMessages && message.type === 'progress') {\n yield message // yield the last progress message first\n }\n \n // Always yield a tool result message for cancellation to clear UI state\n const cancelMessage = createUserMessage([\n createToolResultStopMessage(toolUse.id),\n ])\n yield cancelMessage\n return\n }\n\n if (message.type === 'progress') {\n hasProgressMessages = true\n }\n \n yield message\n }\n } catch (e) {\n logError(e)\n \n // \uD83D\uDD27 Even on error, ensure we yield a tool result to clear UI state\n const errorMessage = createUserMessage([\n {\n type: 'tool_result',\n content: `Tool execution failed: ${e instanceof Error ? e.message : String(e)}`,\n is_error: true,\n tool_use_id: toolUse.id,\n },\n ])\n yield errorMessage\n }\n}\n\n// TODO: Generalize this to all tools\nexport function normalizeToolInput(\n tool: Tool,\n input: { [key: string]: boolean | string | number },\n): { [key: string]: boolean | string | number } {\n switch (tool) {\n case BashTool: {\n const { command, timeout } = BashTool.inputSchema.parse(input) // already validated upstream, won't throw\n return {\n command: command.replace(`cd ${getCwd()} && `, ''),\n ...(timeout ? { timeout } : {}),\n }\n }\n default:\n return input\n }\n}\n\nasync function* checkPermissionsAndCallTool(\n tool: Tool,\n toolUseID: string,\n siblingToolUseIDs: Set<string>,\n input: { [key: string]: boolean | string | number },\n context: ToolUseContext,\n canUseTool: CanUseToolFn,\n assistantMessage: AssistantMessage,\n shouldSkipPermissionCheck?: boolean,\n): AsyncGenerator<UserMessage | ProgressMessage, void> {\n // Validate input types with zod\n // (surprisingly, the model is not great at generating valid input)\n const isValidInput = tool.inputSchema.safeParse(input)\n if (!isValidInput.success) {\n // Create a more helpful error message for common cases\n let errorMessage = `InputValidationError: ${isValidInput.error.message}`\n \n // Special handling for the \"View\" tool (FileReadTool) being called with empty parameters\n if (tool.name === 'View' && Object.keys(input).length === 0) {\n errorMessage = `Error: The View tool requires a 'file_path' parameter to specify which file to read. Please provide the absolute path to the file you want to view. For example: {\"file_path\": \"/path/to/file.txt\"}`\n }\n \n \n yield createUserMessage([\n {\n type: 'tool_result',\n content: errorMessage,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n const normalizedInput = normalizeToolInput(tool, input)\n\n // Validate input values. Each tool has its own validation logic\n const isValidCall = await tool.validateInput?.(\n normalizedInput as never,\n context,\n )\n if (isValidCall?.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: isValidCall!.message,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n // Check whether we have permission to use the tool,\n // and ask the user for permission if we don't\n const permissionResult = shouldSkipPermissionCheck\n ? ({ result: true } as const)\n : await canUseTool(tool, normalizedInput, context, assistantMessage)\n if (permissionResult.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: permissionResult.message,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n\n // PreToolUse hooks\n const hookManager = getHookManager()\n if (hookManager) {\n try {\n const decision = await hookManager.executePreToolUse(\n tool.name,\n normalizedInput as Record<string, unknown>,\n )\n\n if (!decision.shouldContinue) {\n if (decision.shouldAskUser) {\n // Ask user for approval via permission system\n const approved = await canUseTool(tool, normalizedInput, context, assistantMessage)\n if (approved.result === false) {\n yield createUserMessage([\n {\n type: 'tool_result',\n content: decision.reason || 'Hook requested approval but user denied',\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n } else {\n // Hook blocked the tool\n yield createUserMessage([\n {\n type: 'tool_result',\n content: decision.reason || 'Tool execution blocked by hook',\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n return\n }\n }\n } catch (error) {\n debug.error('PreToolUse hook failed', { error })\n // Continue on error (fail-safe)\n }\n }\n\n // Call the tool\n let toolOutput: FullToolUseResult | null = null\n try {\n const generator = tool.call(normalizedInput as never, context)\n for await (const result of generator) {\n switch (result.type) {\n case 'result':\n toolOutput = {\n data: result.data,\n resultForAssistant: result.resultForAssistant || String(result.data),\n }\n\n yield createUserMessage(\n [\n {\n type: 'tool_result',\n content: result.resultForAssistant || String(result.data),\n tool_use_id: toolUseID,\n },\n ],\n toolOutput,\n )\n\n // PostToolUse hooks (fire-and-forget)\n if (hookManager && toolOutput) {\n hookManager.executePostToolUse(\n tool.name,\n normalizedInput as Record<string, unknown>,\n toolOutput as any,\n ).catch(err => {\n debug.error('PostToolUse hook failed', { error: err })\n })\n }\n\n return\n case 'progress':\n \n yield createProgressMessage(\n toolUseID,\n siblingToolUseIDs,\n result.content,\n result.normalizedMessages || [],\n result.tools || [],\n )\n break\n }\n }\n } catch (error) {\n const content = formatError(error)\n logError(error)\n \n yield createUserMessage([\n {\n type: 'tool_result',\n content,\n is_error: true,\n tool_use_id: toolUseID,\n },\n ])\n }\n}\n\nfunction formatError(error: unknown): string {\n if (!(error instanceof Error)) {\n return String(error)\n }\n const parts = [error.message]\n if ('stderr' in error && typeof error.stderr === 'string') {\n parts.push(error.stderr)\n }\n if ('stdout' in error && typeof error.stdout === 'string') {\n parts.push(error.stdout)\n }\n const fullMessage = parts.filter(Boolean).join('\\n')\n if (fullMessage.length <= 10000) {\n return fullMessage\n }\n const halfLength = 5000\n const start = fullMessage.slice(0, halfLength)\n const end = fullMessage.slice(-halfLength)\n return `${start}\\n\\n... [${fullMessage.length - 10000} characters truncated] ...\\n\\n${end}`\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -56,6 +56,7 @@ import { BinaryFeedback } from "../components/binary-feedback/BinaryFeedback.js"
56
56
  import { getMaxThinkingTokens } from "../utils/thinking.js";
57
57
  import { getOriginalCwd } from "../utils/state.js";
58
58
  import { handleHashCommand } from "../commands/terminalSetup.js";
59
+ import { debug as debugLogger } from "../utils/debugLogger.js";
59
60
  import { initializeHookManager } from "../utils/hookManager.js";
60
61
  import { loadAllPlugins } from "../utils/pluginLoader.js";
61
62
  import { randomUUID } from "crypto";
@@ -65,7 +66,7 @@ import { BackgroundTasksPanel } from "../components/BackgroundTasksPanel.js";
65
66
  function REPL({
66
67
  commands,
67
68
  safeMode,
68
- debug: debug2 = false,
69
+ debug = false,
69
70
  initialForkNumber = 0,
70
71
  initialPrompt,
71
72
  messageLogName,
@@ -342,15 +343,15 @@ function REPL({
342
343
  const hookManager = initializeHookManager(sessionId, transcriptPath, plugins);
343
344
  hookManagerRef.current = hookManager;
344
345
  hookManager.executeSessionStart().catch((err) => {
345
- debug2.error("SessionStart hooks failed", { error: err });
346
+ debugLogger.error("SessionStart hooks failed", { error: err });
346
347
  });
347
348
  return () => {
348
349
  hookManager.executeSessionEnd("other").catch((err) => {
349
- debug2.error("SessionEnd hooks failed", { error: err });
350
+ debugLogger.error("SessionEnd hooks failed", { error: err });
350
351
  });
351
352
  };
352
353
  } catch (err) {
353
- debug2.error("Failed to initialize hook manager", { error: err });
354
+ debugLogger.error("Failed to initialize hook manager", { error: err });
354
355
  }
355
356
  }, [messageLogName, forkNumber]);
356
357
  useEffect(() => {
@@ -406,7 +407,7 @@ function REPL({
406
407
  addMargin: false,
407
408
  tools: _.tools,
408
409
  verbose: verbose ?? false,
409
- debug: debug2,
410
+ debug,
410
411
  erroredToolUseIDs: /* @__PURE__ */ new Set(),
411
412
  inProgressToolUseIDs: /* @__PURE__ */ new Set(),
412
413
  unresolvedToolUseIDs: /* @__PURE__ */ new Set(),
@@ -421,7 +422,7 @@ function REPL({
421
422
  addMargin: false,
422
423
  tools: _.tools,
423
424
  verbose: verbose ?? false,
424
- debug: debug2,
425
+ debug,
425
426
  erroredToolUseIDs: /* @__PURE__ */ new Set(),
426
427
  inProgressToolUseIDs: /* @__PURE__ */ new Set(),
427
428
  unresolvedToolUseIDs: /* @__PURE__ */ new Set([
@@ -438,7 +439,7 @@ function REPL({
438
439
  addMargin: true,
439
440
  tools,
440
441
  verbose,
441
- debug: debug2,
442
+ debug,
442
443
  erroredToolUseIDs,
443
444
  inProgressToolUseIDs,
444
445
  shouldAnimate: !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && (!toolUseID || inProgressToolUseIDs.has(toolUseID)),
@@ -451,7 +452,7 @@ function REPL({
451
452
  normalizedMessages,
452
453
  unresolvedToolUseIDs
453
454
  ) ? "static" : "transient";
454
- if (debug2) {
455
+ if (debug) {
455
456
  return {
456
457
  type,
457
458
  jsx: /* @__PURE__ */ React.createElement(
@@ -477,7 +478,7 @@ function REPL({
477
478
  normalizedMessages,
478
479
  tools,
479
480
  verbose,
480
- debug2,
481
+ debug,
481
482
  erroredToolUseIDs,
482
483
  inProgressToolUseIDs,
483
484
  toolJSX,
@@ -502,7 +503,7 @@ function REPL({
502
503
  Box,
503
504
  {
504
505
  borderColor: "red",
505
- borderStyle: debug2 ? "single" : void 0,
506
+ borderStyle: debug ? "single" : void 0,
506
507
  flexDirection: "column",
507
508
  width: "100%"
508
509
  },
@@ -520,7 +521,7 @@ function REPL({
520
521
  verbose,
521
522
  normalizedMessages,
522
523
  tools,
523
- debug: debug2,
524
+ debug,
524
525
  erroredToolUseIDs,
525
526
  inProgressToolUseIDs,
526
527
  unresolvedToolUseIDs
@@ -580,7 +581,7 @@ function REPL({
580
581
  isDisabled: apiKeyStatus === "invalid",
581
582
  isLoading,
582
583
  onQuery,
583
- debug: debug2,
584
+ debug,
584
585
  verbose,
585
586
  messages,
586
587
  setToolJSX,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/screens/REPL.tsx"],
4
- "sourcesContent": ["import { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box, Newline, Static, Text } from 'ink'\nimport ProjectOnboarding, {\n markProjectOnboardingComplete,\n} from '@components/ProjectOnboarding'\nimport { CostThresholdDialog } from '@components/CostThresholdDialog'\nimport * as React from 'react'\nimport { useEffect, useMemo, useRef, useState, useCallback } from 'react'\nimport { Command } from '@commands'\nimport { Logo } from '@components/Logo'\nimport { Message } from '@components/Message'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { MessageSelector } from '@components/MessageSelector'\nimport {\n PermissionRequest,\n type ToolUseConfirm,\n} from '@components/permissions/PermissionRequest'\nimport PromptInput from '@components/PromptInput'\nimport { Spinner } from '@components/Spinner'\nimport { getSystemPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { getTotalCost, useCostSummary } from '@costTracker'\nimport { useLogStartupTime } from '@hooks/useLogStartupTime'\nimport { addToHistory } from '@history'\nimport { useApiKeyVerification } from '@hooks/useApiKeyVerification'\nimport { useCancelRequest } from '@hooks/useCancelRequest'\nimport useCanUseTool from '@hooks/useCanUseTool'\nimport { useLogMessages } from '@hooks/useLogMessages'\nimport { PermissionProvider } from '@context/PermissionContext'\nimport { ModeIndicator } from '@components/ModeIndicator'\nimport { TodoPanel } from '@components/TodoPanel'\nimport { getTodos } from '@utils/todoStorage'\nimport {\n setMessagesGetter,\n setMessagesSetter,\n setModelConfigChangeHandler,\n} from '@messages'\nimport {\n type AssistantMessage,\n type BinaryFeedbackResult,\n type Message as MessageType,\n type ProgressMessage,\n query,\n} from '@query'\nimport type { WrappedClient } from '@services/mcpClient'\nimport type { Tool } from '@tool'\n// Auto-updater removed; only show a new version banner passed from CLI\nimport { getGlobalConfig, saveGlobalConfig } from '@utils/config'\nimport { debug } from '@utils/debugLogger'\nimport { MACRO } from '@constants/macros'\nimport { getNextAvailableLogForkNumber } from '@utils/log'\nimport {\n getErroredToolUseMessages,\n getInProgressToolUseIDs,\n getLastAssistantMessageId,\n getToolUseID,\n getUnresolvedToolUseIDs,\n INTERRUPT_MESSAGE,\n isNotEmptyMessage,\n type NormalizedMessage,\n normalizeMessages,\n normalizeMessagesForAPI,\n processUserInput,\n reorderMessages,\n extractTag,\n createAssistantMessage,\n} from '@utils/messages'\nimport { getModelManager, ModelManager } from '@utils/model'\nimport { clearTerminal, updateTerminalTitle } from '@utils/terminal'\nimport { BinaryFeedback } from '@components/binary-feedback/BinaryFeedback'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getOriginalCwd } from '@utils/state'\nimport { handleHashCommand } from '@commands/terminalSetup'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { initializeHookManager, getHookManager, type HookManager } from '@utils/hookManager'\nimport { loadAllPlugins } from '@utils/pluginLoader'\nimport { randomUUID } from 'crypto'\nimport { getMessagesPath } from '@utils/log'\nimport { BackgroundShellManager, type BackgroundShell } from '@utils/BackgroundShellManager'\nimport { BackgroundTasksPanel } from '@components/BackgroundTasksPanel'\n\ntype Props = {\n commands: Command[]\n safeMode?: boolean\n debug?: boolean\n initialForkNumber?: number | undefined\n initialPrompt: string | undefined\n // A unique name for the message log file, used to identify the fork\n messageLogName: string\n shouldShowPromptInput: boolean\n tools: Tool[]\n verbose: boolean | undefined\n // Initial messages to populate the REPL with\n initialMessages?: MessageType[]\n // MCP clients\n mcpClients?: WrappedClient[]\n // Flag to indicate if current model is default\n isDefaultModel?: boolean\n // Update banner info passed from CLI before first render\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n // Whether to use limited input mode (raw mode not supported)\n fallbackMode?: boolean\n}\n\nexport type BinaryFeedbackContext = {\n m1: AssistantMessage\n m2: AssistantMessage\n resolve: (result: BinaryFeedbackResult) => void\n}\n\nexport function REPL({\n commands,\n safeMode,\n debug = false,\n initialForkNumber = 0,\n initialPrompt,\n messageLogName,\n shouldShowPromptInput,\n tools,\n verbose: verboseFromCLI,\n initialMessages,\n mcpClients = [],\n isDefaultModel = true,\n initialUpdateVersion,\n initialUpdateCommands,\n fallbackMode = false,\n}: Props): React.ReactNode {\n // Verbose mode state - can be toggled at runtime with Ctrl+O\n const [verbose, setVerbose] = useState(() => verboseFromCLI ?? getGlobalConfig().verbose)\n\n // Used to force the logo to re-render and conversation log to use a new file\n const [forkNumber, setForkNumber] = useState(\n getNextAvailableLogForkNumber(messageLogName, initialForkNumber, 0),\n )\n\n const [\n forkConvoWithMessagesOnTheNextRender,\n setForkConvoWithMessagesOnTheNextRender,\n ] = useState<MessageType[] | null>(null)\n\n // \uD83D\uDD27 Simplified AbortController management - inspired by reference system\n const [abortController, setAbortController] = useState<AbortController | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n // No auto-updater state\n const [toolJSX, setToolJSX] = useState<{\n jsx: React.ReactNode | null\n shouldHidePromptInput: boolean\n } | null>(null)\n const [toolUseConfirm, setToolUseConfirm] = useState<ToolUseConfirm | null>(\n null,\n )\n const [messages, setMessages] = useState<MessageType[]>(initialMessages ?? [])\n // Phase 4.1: Message history stack for Esc Esc rollback\n const [messageHistory, setMessageHistory] = useState<MessageType[][]>([])\n const [inputValue, setInputValue] = useState('')\n const [inputMode, setInputMode] = useState<'bash' | 'prompt' | 'koding'>(\n 'prompt',\n )\n const [submitCount, setSubmitCount] = useState(0)\n const [isMessageSelectorVisible, setIsMessageSelectorVisible] =\n useState(false)\n const [showCostDialog, setShowCostDialog] = useState(false)\n const [haveShownCostDialog, setHaveShownCostDialog] = useState(\n getGlobalConfig().hasAcknowledgedCostThreshold,\n )\n\n const [binaryFeedbackContext, setBinaryFeedbackContext] =\n useState<BinaryFeedbackContext | null>(null)\n // New version banner: passed in from CLI to guarantee top placement\n const updateAvailableVersion = initialUpdateVersion ?? null\n const updateCommands = initialUpdateCommands ?? null\n // No separate Static for banner; it renders inside Logo\n\n // TodoPanel state\n const [isTodoPanelVisible, setIsTodoPanelVisible] = useState(true)\n const [startTime] = useState(Date.now())\n\n // Background tasks state\n const [backgroundShells, setBackgroundShells] = useState<BackgroundShell[]>([])\n const [showBackgroundPanel, setShowBackgroundPanel] = useState(false)\n\n const getBinaryFeedbackResponse = useCallback(\n (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ): Promise<BinaryFeedbackResult> => {\n return new Promise<BinaryFeedbackResult>(resolvePromise => {\n setBinaryFeedbackContext({\n m1,\n m2,\n resolve: resolvePromise,\n })\n })\n },\n [],\n )\n\n const readFileTimestamps = useRef<{\n [filename: string]: number\n }>({})\n\n // Hook manager for plugin hooks\n const hookManagerRef = useRef<HookManager | null>(null)\n\n const { status: apiKeyStatus, reverify } = useApiKeyVerification()\n function onCancel() {\n if (!isLoading) {\n return\n }\n setIsLoading(false)\n if (toolUseConfirm) {\n toolUseConfirm.onAbort()\n } else if (abortController && !abortController.signal.aborted) {\n abortController.abort()\n }\n }\n\n useCancelRequest(\n setToolJSX,\n setToolUseConfirm,\n setBinaryFeedbackContext,\n onCancel,\n isLoading,\n isMessageSelectorVisible,\n abortController?.signal,\n )\n\n useEffect(() => {\n if (forkConvoWithMessagesOnTheNextRender) {\n setForkNumber(_ => _ + 1)\n setForkConvoWithMessagesOnTheNextRender(null)\n setMessages(forkConvoWithMessagesOnTheNextRender)\n }\n }, [forkConvoWithMessagesOnTheNextRender])\n\n useEffect(() => {\n const totalCost = getTotalCost()\n if (totalCost >= 5 /* $5 */ && !showCostDialog && !haveShownCostDialog) {\n \n setShowCostDialog(true)\n }\n }, [messages, showCostDialog, haveShownCostDialog])\n\n // Update banner is provided by CLI at startup; no async check here.\n\n const canUseTool = useCanUseTool(setToolUseConfirm)\n\n async function onInit() {\n reverify()\n\n if (!initialPrompt) {\n return\n }\n\n setIsLoading(true)\n\n const newAbortController = new AbortController()\n setAbortController(newAbortController)\n\n // \uD83D\uDD27 Force fresh config read to ensure model switching works\n const model = new ModelManager(getGlobalConfig()).getModelName('main')\n const newMessages = await processUserInput(\n initialPrompt,\n 'prompt',\n setToolJSX,\n {\n abortController: newAbortController,\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n maxThinkingTokens: 0,\n },\n messageId: getLastAssistantMessageId(messages),\n setForkConvoWithMessagesOnTheNextRender,\n readFileTimestamps: readFileTimestamps.current,\n },\n null,\n )\n\n if (newMessages.length) {\n for (const message of newMessages) {\n if (message.type === 'user') {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n }\n setMessages(_ => [..._, ...newMessages])\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, ...newMessages]),\n ])\n\n for await (const message of query(\n [...messages, ...newMessages],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n },\n messageId: getLastAssistantMessageId([...messages, ...newMessages]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: newAbortController,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n }\n } else {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n\n setHaveShownCostDialog(\n getGlobalConfig().hasAcknowledgedCostThreshold || false,\n )\n\n // \uD83D\uDD27 Fix: Clean up state after onInit completion\n setIsLoading(false)\n setAbortController(null)\n }\n\n // Phase 4.1: Rollback to previous message state\n function rollbackConversation(): boolean {\n if (messageHistory.length === 0) {\n return false // No history to rollback to\n }\n\n // Pop the last snapshot and restore it\n const previousMessages = messageHistory[messageHistory.length - 1]!\n setMessages(previousMessages)\n setMessageHistory(history => history.slice(0, -1))\n\n return true // Successfully rolled back\n }\n\n async function onQuery(newMessages: MessageType[], passedAbortController?: AbortController) {\n // Use passed AbortController or create new one\n const controllerToUse = passedAbortController || new AbortController()\n if (!passedAbortController) {\n setAbortController(controllerToUse)\n }\n\n // Check if this is a Koding request based on last message's options\n const isKodingRequest =\n newMessages.length > 0 &&\n newMessages[0].type === 'user' &&\n 'options' in newMessages[0] &&\n newMessages[0].options?.isKodingRequest === true\n\n // Phase 4.1: Save message history snapshot before adding new messages\n setMessages(oldMessages => {\n // Save current state to history stack (limit to last 10 snapshots)\n setMessageHistory(history => [...history, oldMessages].slice(-10))\n return [...oldMessages, ...newMessages]\n })\n\n // Mark onboarding as complete when any user message is sent to the assistant\n markProjectOnboardingComplete()\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n\n // Update terminal title based on user message\n if (\n lastMessage.type === 'user' &&\n typeof lastMessage.message.content === 'string'\n ) {\n // updateTerminalTitle(lastMessage.message.content)\n }\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, lastMessage]),\n ])\n\n let lastAssistantMessage: MessageType | null = null\n\n // query the API\n for await (const message of query(\n [...messages, lastMessage],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n // If this came from Koding mode, pass that along\n isKodingRequest: isKodingRequest || undefined,\n },\n messageId: getLastAssistantMessageId([...messages, lastMessage]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: controllerToUse,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n\n // Keep track of the last assistant message for Koding mode\n if (message.type === 'assistant') {\n lastAssistantMessage = message\n }\n }\n\n // If this was a Koding request and we got an assistant message back,\n // save it to MINTO.md (and CLAUDE.md if exists)\n if (\n isKodingRequest &&\n lastAssistantMessage &&\n lastAssistantMessage.type === 'assistant'\n ) {\n try {\n const content =\n typeof lastAssistantMessage.message.content === 'string'\n ? lastAssistantMessage.message.content\n : lastAssistantMessage.message.content\n .filter(block => block.type === 'text')\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n\n // Add the content to MINTO.md (and CLAUDE.md if exists)\n if (content && content.trim().length > 0) {\n handleHashCommand(content)\n }\n } catch (error) {\n console.error('Error saving response to project docs:', error)\n }\n }\n\n setIsLoading(false)\n }\n\n // Register cost summary tracker\n useCostSummary()\n\n // Register messages getter and setter\n useEffect(() => {\n const getMessages = () => messages\n setMessagesGetter(getMessages)\n setMessagesSetter(setMessages)\n }, [messages])\n\n // Register model config change handler for UI refresh\n useEffect(() => {\n setModelConfigChangeHandler(() => {\n setForkNumber(prev => prev + 1)\n })\n }, [])\n\n // Record transcripts locally, for debugging and conversation recovery\n useLogMessages(messages, messageLogName, forkNumber)\n\n // Log startup time\n useLogStartupTime()\n\n // Initial load\n useEffect(() => {\n onInit()\n // TODO: fix this\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // Initialize hook manager\n useEffect(() => {\n try {\n const plugins = loadAllPlugins()\n const sessionId = randomUUID()\n const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0)\n\n const hookManager = initializeHookManager(sessionId, transcriptPath, plugins)\n hookManagerRef.current = hookManager\n\n // Execute SessionStart hooks\n hookManager.executeSessionStart().catch(err => {\n debug.error('SessionStart hooks failed', { error: err })\n })\n\n // Cleanup: Execute SessionEnd hooks\n return () => {\n hookManager.executeSessionEnd('other').catch(err => {\n debug.error('SessionEnd hooks failed', { error: err })\n })\n }\n } catch (err) {\n debug.error('Failed to initialize hook manager', { error: err })\n }\n }, [messageLogName, forkNumber])\n\n // Update background shells periodically\n useEffect(() => {\n const interval = setInterval(() => {\n const shells = BackgroundShellManager.getInstance().list()\n setBackgroundShells(shells)\n }, 1000)\n\n return () => clearInterval(interval)\n }, [])\n\n const normalizedMessages = useMemo(\n () => normalizeMessages(messages).filter(isNotEmptyMessage),\n [messages],\n )\n\n const unresolvedToolUseIDs = useMemo(\n () => getUnresolvedToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const inProgressToolUseIDs = useMemo(\n () => getInProgressToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const erroredToolUseIDs = useMemo(\n () =>\n new Set(\n getErroredToolUseMessages(normalizedMessages).map(\n _ => (_.message.content[0]! as ToolUseBlockParam).id,\n ),\n ),\n [normalizedMessages],\n )\n\n const messagesJSX = useMemo(() => {\n return [\n {\n type: 'static',\n jsx: (\n <Box flexDirection=\"column\" key={`logo${forkNumber}`}>\n <Logo\n mcpClients={mcpClients}\n isDefaultModel={isDefaultModel}\n updateBannerVersion={updateAvailableVersion}\n updateBannerCommands={updateCommands}\n />\n <ProjectOnboarding workspaceDir={getOriginalCwd()} />\n </Box>\n ),\n },\n ...reorderMessages(normalizedMessages).map(_ => {\n const toolUseID = getToolUseID(_)\n const message =\n _.type === 'progress' ? (\n _.content.message.content[0]?.type === 'text' &&\n // TaskTool interrupts use Progress messages without extra \u23BF \n // since <Message /> component already adds the margin\n _.content.message.content[0].text === INTERRUPT_MESSAGE ? (\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={new Set()}\n shouldAnimate={false}\n shouldShowDot={false}\n />\n ) : (\n <MessageResponse children={\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={\n new Set([\n (_.content.message.content[0]! as ToolUseBlockParam).id,\n ])\n }\n shouldAnimate={false}\n shouldShowDot={false}\n />\n } />\n )\n ) : (\n <Message\n message={_}\n messages={normalizedMessages}\n addMargin={true}\n tools={tools}\n verbose={verbose}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n shouldAnimate={\n !toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n (!toolUseID || inProgressToolUseIDs.has(toolUseID))\n }\n shouldShowDot={true}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )\n\n const type = shouldRenderStatically(\n _,\n normalizedMessages,\n unresolvedToolUseIDs,\n )\n ? 'static'\n : 'transient'\n\n if (debug) {\n return {\n type,\n jsx: (\n <Box\n borderStyle=\"single\"\n borderColor={type === 'static' ? 'green' : 'red'}\n key={_.uuid}\n width=\"100%\"\n >\n {message}\n </Box>\n ),\n }\n }\n\n return {\n type,\n jsx: (\n <Box key={_.uuid} width=\"100%\">\n {message}\n </Box>\n ),\n }\n }),\n ]\n }, [\n forkNumber,\n normalizedMessages,\n tools,\n verbose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n toolJSX,\n toolUseConfirm,\n isMessageSelectorVisible,\n unresolvedToolUseIDs,\n mcpClients,\n isDefaultModel,\n ])\n\n // only show the dialog once not loading\n const showingCostDialog = !isLoading && showCostDialog\n\n return (\n <PermissionProvider \n isBypassPermissionsModeAvailable={!safeMode}\n children={\n <React.Fragment>\n {/* Update banner now renders inside Logo for stable placement */}\n <ModeIndicator />\n <React.Fragment key={`static-messages-${forkNumber}`}>\n <Static\n items={messagesJSX.filter(_ => _.type === 'static')}\n children={(item: any) => item.jsx}\n />\n </React.Fragment>\n {messagesJSX.filter(_ => _.type === 'transient').map(_ => _.jsx)}\n <Box\n borderColor=\"red\"\n borderStyle={debug ? 'single' : undefined}\n flexDirection=\"column\"\n width=\"100%\"\n >\n {!toolJSX && !toolUseConfirm && !binaryFeedbackContext && isLoading && (\n <Spinner />\n )}\n {toolJSX ? toolJSX.jsx : null}\n {!toolJSX && binaryFeedbackContext && !isMessageSelectorVisible && (\n <BinaryFeedback\n m1={binaryFeedbackContext.m1}\n m2={binaryFeedbackContext.m2}\n resolve={result => {\n binaryFeedbackContext.resolve(result)\n setTimeout(() => setBinaryFeedbackContext(null), 0)\n }}\n verbose={verbose}\n normalizedMessages={normalizedMessages}\n tools={tools}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )}\n {!toolJSX &&\n toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext && (\n <PermissionRequest\n toolUseConfirm={toolUseConfirm}\n onDone={() => setToolUseConfirm(null)}\n verbose={verbose}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n showingCostDialog && (\n <CostThresholdDialog\n onDone={() => {\n setShowCostDialog(false)\n setHaveShownCostDialog(true)\n const projectConfig = getGlobalConfig()\n saveGlobalConfig({\n ...projectConfig,\n hasAcknowledgedCostThreshold: true,\n })\n \n }}\n />\n )}\n\n {!toolUseConfirm &&\n !toolJSX?.shouldHidePromptInput &&\n shouldShowPromptInput &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n !showingCostDialog && (\n <>\n {/* TodoPanel - Fixed display above input */}\n <TodoPanel\n todos={getTodos()}\n isVisible={isTodoPanelVisible}\n elapsedTime={Math.floor((Date.now() - startTime) / 1000)}\n tokenCount={0}\n isLoading={isLoading}\n />\n {/* BackgroundTasksPanel */}\n <BackgroundTasksPanel\n shells={backgroundShells}\n isVisible={showBackgroundPanel}\n onSelect={(shell) => {\n // View shell details (could show detailed output)\n setShowBackgroundPanel(false)\n }}\n onKill={(shell) => {\n BackgroundShellManager.getInstance().kill(shell.id)\n }}\n onClose={() => setShowBackgroundPanel(false)}\n />\n <PromptInput\n commands={commands}\n forkNumber={forkNumber}\n messageLogName={messageLogName}\n tools={tools}\n isDisabled={apiKeyStatus === 'invalid'}\n isLoading={isLoading}\n onQuery={onQuery}\n debug={debug}\n verbose={verbose}\n messages={messages}\n setToolJSX={setToolJSX}\n input={inputValue}\n onInputChange={setInputValue}\n mode={inputMode}\n onModeChange={setInputMode}\n submitCount={submitCount}\n onSubmitCountChange={setSubmitCount}\n setIsLoading={setIsLoading}\n setAbortController={setAbortController}\n onShowMessageSelector={() =>\n setIsMessageSelectorVisible(prev => !prev)\n }\n setForkConvoWithMessagesOnTheNextRender={\n setForkConvoWithMessagesOnTheNextRender\n }\n readFileTimestamps={readFileTimestamps.current}\n abortController={abortController}\n onModelChange={() => setForkNumber(prev => prev + 1)}\n onRollbackConversation={rollbackConversation}\n onToggleTodoPanel={() => setIsTodoPanelVisible(prev => !prev)}\n onToggleVerbose={() => setVerbose(prev => !prev)}\n onToggleBackgroundPanel={() => setShowBackgroundPanel(prev => !prev)}\n backgroundShellCount={backgroundShells.filter(s => s.status === 'running').length}\n isBackgroundPanelOpen={showBackgroundPanel}\n fallbackMode={fallbackMode}\n />\n </>\n )}\n </Box>\n {isMessageSelectorVisible && (\n <MessageSelector\n erroredToolUseIDs={erroredToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n messages={normalizeMessagesForAPI(messages)}\n onSelect={async message => {\n setIsMessageSelectorVisible(false)\n\n // If the user selected the current prompt, do nothing\n if (!messages.includes(message)) {\n return\n }\n\n // Cancel tool use calls/requests\n onCancel()\n\n // Hack: make sure the \"Interrupted by user\" message is\n // rendered in response to the cancellation. Otherwise,\n // the screen will be cleared but there will remain a\n // vestigial \"Interrupted by user\" message at the top.\n setImmediate(async () => {\n // Clear messages, and re-render\n await clearTerminal()\n setMessages([])\n setForkConvoWithMessagesOnTheNextRender(\n messages.slice(0, messages.indexOf(message)),\n )\n\n // Populate/reset the prompt input\n if (typeof message.message.content === 'string') {\n setInputValue(message.message.content)\n }\n })\n }}\n onEscape={() => setIsMessageSelectorVisible(false)}\n tools={tools}\n />\n )}\n {/** Fix occasional rendering artifact */}\n <Newline />\n </React.Fragment>\n }\n />\n )\n}\n\nfunction shouldRenderStatically(\n message: NormalizedMessage,\n messages: NormalizedMessage[],\n unresolvedToolUseIDs: Set<string>,\n): boolean {\n switch (message.type) {\n case 'user':\n case 'assistant': {\n const toolUseID = getToolUseID(message)\n if (!toolUseID) {\n return true\n }\n if (unresolvedToolUseIDs.has(toolUseID)) {\n return false\n }\n\n const correspondingProgressMessage = messages.find(\n _ => _.type === 'progress' && _.toolUseID === toolUseID,\n ) as ProgressMessage | null\n if (!correspondingProgressMessage) {\n return true\n }\n\n return !intersects(\n unresolvedToolUseIDs,\n correspondingProgressMessage.siblingToolUseIDs,\n )\n }\n case 'progress':\n return !intersects(unresolvedToolUseIDs, message.siblingToolUseIDs)\n }\n}\n\nfunction intersects<A>(a: Set<A>, b: Set<A>): boolean {\n return a.size > 0 && b.size > 0 && [...a].some(_ => b.has(_))\n}\n"],
5
- "mappings": "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",
6
- "names": ["debug", "model"]
4
+ "sourcesContent": ["import { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { Box, Newline, Static, Text } from 'ink'\nimport ProjectOnboarding, {\n markProjectOnboardingComplete,\n} from '@components/ProjectOnboarding'\nimport { CostThresholdDialog } from '@components/CostThresholdDialog'\nimport * as React from 'react'\nimport { useEffect, useMemo, useRef, useState, useCallback } from 'react'\nimport { Command } from '@commands'\nimport { Logo } from '@components/Logo'\nimport { Message } from '@components/Message'\nimport { MessageResponse } from '@components/MessageResponse'\nimport { MessageSelector } from '@components/MessageSelector'\nimport {\n PermissionRequest,\n type ToolUseConfirm,\n} from '@components/permissions/PermissionRequest'\nimport PromptInput from '@components/PromptInput'\nimport { Spinner } from '@components/Spinner'\nimport { getSystemPrompt } from '@constants/prompts'\nimport { getContext } from '@context'\nimport { getTotalCost, useCostSummary } from '@costTracker'\nimport { useLogStartupTime } from '@hooks/useLogStartupTime'\nimport { addToHistory } from '@history'\nimport { useApiKeyVerification } from '@hooks/useApiKeyVerification'\nimport { useCancelRequest } from '@hooks/useCancelRequest'\nimport useCanUseTool from '@hooks/useCanUseTool'\nimport { useLogMessages } from '@hooks/useLogMessages'\nimport { PermissionProvider } from '@context/PermissionContext'\nimport { ModeIndicator } from '@components/ModeIndicator'\nimport { TodoPanel } from '@components/TodoPanel'\nimport { getTodos } from '@utils/todoStorage'\nimport {\n setMessagesGetter,\n setMessagesSetter,\n setModelConfigChangeHandler,\n} from '@messages'\nimport {\n type AssistantMessage,\n type BinaryFeedbackResult,\n type Message as MessageType,\n type ProgressMessage,\n query,\n} from '@query'\nimport type { WrappedClient } from '@services/mcpClient'\nimport type { Tool } from '@tool'\n// Auto-updater removed; only show a new version banner passed from CLI\nimport { getGlobalConfig, saveGlobalConfig } from '@utils/config'\nimport { MACRO } from '@constants/macros'\nimport { getNextAvailableLogForkNumber } from '@utils/log'\nimport {\n getErroredToolUseMessages,\n getInProgressToolUseIDs,\n getLastAssistantMessageId,\n getToolUseID,\n getUnresolvedToolUseIDs,\n INTERRUPT_MESSAGE,\n isNotEmptyMessage,\n type NormalizedMessage,\n normalizeMessages,\n normalizeMessagesForAPI,\n processUserInput,\n reorderMessages,\n extractTag,\n createAssistantMessage,\n} from '@utils/messages'\nimport { getModelManager, ModelManager } from '@utils/model'\nimport { clearTerminal, updateTerminalTitle } from '@utils/terminal'\nimport { BinaryFeedback } from '@components/binary-feedback/BinaryFeedback'\nimport { getMaxThinkingTokens } from '@utils/thinking'\nimport { getOriginalCwd } from '@utils/state'\nimport { handleHashCommand } from '@commands/terminalSetup'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { initializeHookManager, getHookManager, type HookManager } from '@utils/hookManager'\nimport { loadAllPlugins } from '@utils/pluginLoader'\nimport { randomUUID } from 'crypto'\nimport { getMessagesPath } from '@utils/log'\nimport { BackgroundShellManager, type BackgroundShell } from '@utils/BackgroundShellManager'\nimport { BackgroundTasksPanel } from '@components/BackgroundTasksPanel'\n\ntype Props = {\n commands: Command[]\n safeMode?: boolean\n debug?: boolean\n initialForkNumber?: number | undefined\n initialPrompt: string | undefined\n // A unique name for the message log file, used to identify the fork\n messageLogName: string\n shouldShowPromptInput: boolean\n tools: Tool[]\n verbose: boolean | undefined\n // Initial messages to populate the REPL with\n initialMessages?: MessageType[]\n // MCP clients\n mcpClients?: WrappedClient[]\n // Flag to indicate if current model is default\n isDefaultModel?: boolean\n // Update banner info passed from CLI before first render\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n // Whether to use limited input mode (raw mode not supported)\n fallbackMode?: boolean\n}\n\nexport type BinaryFeedbackContext = {\n m1: AssistantMessage\n m2: AssistantMessage\n resolve: (result: BinaryFeedbackResult) => void\n}\n\nexport function REPL({\n commands,\n safeMode,\n debug = false,\n initialForkNumber = 0,\n initialPrompt,\n messageLogName,\n shouldShowPromptInput,\n tools,\n verbose: verboseFromCLI,\n initialMessages,\n mcpClients = [],\n isDefaultModel = true,\n initialUpdateVersion,\n initialUpdateCommands,\n fallbackMode = false,\n}: Props): React.ReactNode {\n // Verbose mode state - can be toggled at runtime with Ctrl+O\n const [verbose, setVerbose] = useState(() => verboseFromCLI ?? getGlobalConfig().verbose)\n\n // Used to force the logo to re-render and conversation log to use a new file\n const [forkNumber, setForkNumber] = useState(\n getNextAvailableLogForkNumber(messageLogName, initialForkNumber, 0),\n )\n\n const [\n forkConvoWithMessagesOnTheNextRender,\n setForkConvoWithMessagesOnTheNextRender,\n ] = useState<MessageType[] | null>(null)\n\n // \uD83D\uDD27 Simplified AbortController management - inspired by reference system\n const [abortController, setAbortController] = useState<AbortController | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n // No auto-updater state\n const [toolJSX, setToolJSX] = useState<{\n jsx: React.ReactNode | null\n shouldHidePromptInput: boolean\n } | null>(null)\n const [toolUseConfirm, setToolUseConfirm] = useState<ToolUseConfirm | null>(\n null,\n )\n const [messages, setMessages] = useState<MessageType[]>(initialMessages ?? [])\n // Phase 4.1: Message history stack for Esc Esc rollback\n const [messageHistory, setMessageHistory] = useState<MessageType[][]>([])\n const [inputValue, setInputValue] = useState('')\n const [inputMode, setInputMode] = useState<'bash' | 'prompt' | 'koding'>(\n 'prompt',\n )\n const [submitCount, setSubmitCount] = useState(0)\n const [isMessageSelectorVisible, setIsMessageSelectorVisible] =\n useState(false)\n const [showCostDialog, setShowCostDialog] = useState(false)\n const [haveShownCostDialog, setHaveShownCostDialog] = useState(\n getGlobalConfig().hasAcknowledgedCostThreshold,\n )\n\n const [binaryFeedbackContext, setBinaryFeedbackContext] =\n useState<BinaryFeedbackContext | null>(null)\n // New version banner: passed in from CLI to guarantee top placement\n const updateAvailableVersion = initialUpdateVersion ?? null\n const updateCommands = initialUpdateCommands ?? null\n // No separate Static for banner; it renders inside Logo\n\n // TodoPanel state\n const [isTodoPanelVisible, setIsTodoPanelVisible] = useState(true)\n const [startTime] = useState(Date.now())\n\n // Background tasks state\n const [backgroundShells, setBackgroundShells] = useState<BackgroundShell[]>([])\n const [showBackgroundPanel, setShowBackgroundPanel] = useState(false)\n\n const getBinaryFeedbackResponse = useCallback(\n (\n m1: AssistantMessage,\n m2: AssistantMessage,\n ): Promise<BinaryFeedbackResult> => {\n return new Promise<BinaryFeedbackResult>(resolvePromise => {\n setBinaryFeedbackContext({\n m1,\n m2,\n resolve: resolvePromise,\n })\n })\n },\n [],\n )\n\n const readFileTimestamps = useRef<{\n [filename: string]: number\n }>({})\n\n // Hook manager for plugin hooks\n const hookManagerRef = useRef<HookManager | null>(null)\n\n const { status: apiKeyStatus, reverify } = useApiKeyVerification()\n function onCancel() {\n if (!isLoading) {\n return\n }\n setIsLoading(false)\n if (toolUseConfirm) {\n toolUseConfirm.onAbort()\n } else if (abortController && !abortController.signal.aborted) {\n abortController.abort()\n }\n }\n\n useCancelRequest(\n setToolJSX,\n setToolUseConfirm,\n setBinaryFeedbackContext,\n onCancel,\n isLoading,\n isMessageSelectorVisible,\n abortController?.signal,\n )\n\n useEffect(() => {\n if (forkConvoWithMessagesOnTheNextRender) {\n setForkNumber(_ => _ + 1)\n setForkConvoWithMessagesOnTheNextRender(null)\n setMessages(forkConvoWithMessagesOnTheNextRender)\n }\n }, [forkConvoWithMessagesOnTheNextRender])\n\n useEffect(() => {\n const totalCost = getTotalCost()\n if (totalCost >= 5 /* $5 */ && !showCostDialog && !haveShownCostDialog) {\n \n setShowCostDialog(true)\n }\n }, [messages, showCostDialog, haveShownCostDialog])\n\n // Update banner is provided by CLI at startup; no async check here.\n\n const canUseTool = useCanUseTool(setToolUseConfirm)\n\n async function onInit() {\n reverify()\n\n if (!initialPrompt) {\n return\n }\n\n setIsLoading(true)\n\n const newAbortController = new AbortController()\n setAbortController(newAbortController)\n\n // \uD83D\uDD27 Force fresh config read to ensure model switching works\n const model = new ModelManager(getGlobalConfig()).getModelName('main')\n const newMessages = await processUserInput(\n initialPrompt,\n 'prompt',\n setToolJSX,\n {\n abortController: newAbortController,\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n maxThinkingTokens: 0,\n },\n messageId: getLastAssistantMessageId(messages),\n setForkConvoWithMessagesOnTheNextRender,\n readFileTimestamps: readFileTimestamps.current,\n },\n null,\n )\n\n if (newMessages.length) {\n for (const message of newMessages) {\n if (message.type === 'user') {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n }\n setMessages(_ => [..._, ...newMessages])\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, ...newMessages]),\n ])\n\n for await (const message of query(\n [...messages, ...newMessages],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n },\n messageId: getLastAssistantMessageId([...messages, ...newMessages]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: newAbortController,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n }\n } else {\n addToHistory(initialPrompt)\n // TODO: setHistoryIndex\n }\n\n setHaveShownCostDialog(\n getGlobalConfig().hasAcknowledgedCostThreshold || false,\n )\n\n // \uD83D\uDD27 Fix: Clean up state after onInit completion\n setIsLoading(false)\n setAbortController(null)\n }\n\n // Phase 4.1: Rollback to previous message state\n function rollbackConversation(): boolean {\n if (messageHistory.length === 0) {\n return false // No history to rollback to\n }\n\n // Pop the last snapshot and restore it\n const previousMessages = messageHistory[messageHistory.length - 1]!\n setMessages(previousMessages)\n setMessageHistory(history => history.slice(0, -1))\n\n return true // Successfully rolled back\n }\n\n async function onQuery(newMessages: MessageType[], passedAbortController?: AbortController) {\n // Use passed AbortController or create new one\n const controllerToUse = passedAbortController || new AbortController()\n if (!passedAbortController) {\n setAbortController(controllerToUse)\n }\n\n // Check if this is a Koding request based on last message's options\n const isKodingRequest =\n newMessages.length > 0 &&\n newMessages[0].type === 'user' &&\n 'options' in newMessages[0] &&\n newMessages[0].options?.isKodingRequest === true\n\n // Phase 4.1: Save message history snapshot before adding new messages\n setMessages(oldMessages => {\n // Save current state to history stack (limit to last 10 snapshots)\n setMessageHistory(history => [...history, oldMessages].slice(-10))\n return [...oldMessages, ...newMessages]\n })\n\n // Mark onboarding as complete when any user message is sent to the assistant\n markProjectOnboardingComplete()\n\n // The last message is an assistant message if the user input was a bash command,\n // or if the user input was an invalid slash command.\n const lastMessage = newMessages[newMessages.length - 1]!\n\n // Update terminal title based on user message\n if (\n lastMessage.type === 'user' &&\n typeof lastMessage.message.content === 'string'\n ) {\n // updateTerminalTitle(lastMessage.message.content)\n }\n if (lastMessage.type === 'assistant') {\n setAbortController(null)\n setIsLoading(false)\n return\n }\n\n const [systemPrompt, context, model, maxThinkingTokens] =\n await Promise.all([\n getSystemPrompt(),\n getContext(),\n new ModelManager(getGlobalConfig()).getModelName('main'),\n getMaxThinkingTokens([...messages, lastMessage]),\n ])\n\n let lastAssistantMessage: MessageType | null = null\n\n // query the API\n for await (const message of query(\n [...messages, lastMessage],\n systemPrompt,\n context,\n canUseTool,\n {\n options: {\n commands,\n forkNumber,\n messageLogName,\n tools,\n verbose,\n safeMode,\n maxThinkingTokens,\n // If this came from Koding mode, pass that along\n isKodingRequest: isKodingRequest || undefined,\n },\n messageId: getLastAssistantMessageId([...messages, lastMessage]),\n readFileTimestamps: readFileTimestamps.current,\n abortController: controllerToUse,\n setToolJSX,\n },\n getBinaryFeedbackResponse,\n )) {\n setMessages(oldMessages => [...oldMessages, message])\n\n // Keep track of the last assistant message for Koding mode\n if (message.type === 'assistant') {\n lastAssistantMessage = message\n }\n }\n\n // If this was a Koding request and we got an assistant message back,\n // save it to MINTO.md (and CLAUDE.md if exists)\n if (\n isKodingRequest &&\n lastAssistantMessage &&\n lastAssistantMessage.type === 'assistant'\n ) {\n try {\n const content =\n typeof lastAssistantMessage.message.content === 'string'\n ? lastAssistantMessage.message.content\n : lastAssistantMessage.message.content\n .filter(block => block.type === 'text')\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n')\n\n // Add the content to MINTO.md (and CLAUDE.md if exists)\n if (content && content.trim().length > 0) {\n handleHashCommand(content)\n }\n } catch (error) {\n console.error('Error saving response to project docs:', error)\n }\n }\n\n setIsLoading(false)\n }\n\n // Register cost summary tracker\n useCostSummary()\n\n // Register messages getter and setter\n useEffect(() => {\n const getMessages = () => messages\n setMessagesGetter(getMessages)\n setMessagesSetter(setMessages)\n }, [messages])\n\n // Register model config change handler for UI refresh\n useEffect(() => {\n setModelConfigChangeHandler(() => {\n setForkNumber(prev => prev + 1)\n })\n }, [])\n\n // Record transcripts locally, for debugging and conversation recovery\n useLogMessages(messages, messageLogName, forkNumber)\n\n // Log startup time\n useLogStartupTime()\n\n // Initial load\n useEffect(() => {\n onInit()\n // TODO: fix this\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // Initialize hook manager\n useEffect(() => {\n try {\n const plugins = loadAllPlugins()\n const sessionId = randomUUID()\n const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0)\n\n const hookManager = initializeHookManager(sessionId, transcriptPath, plugins)\n hookManagerRef.current = hookManager\n\n // Execute SessionStart hooks\n hookManager.executeSessionStart().catch(err => {\n debugLogger.error('SessionStart hooks failed', { error: err })\n })\n\n // Cleanup: Execute SessionEnd hooks\n return () => {\n hookManager.executeSessionEnd('other').catch(err => {\n debugLogger.error('SessionEnd hooks failed', { error: err })\n })\n }\n } catch (err) {\n debugLogger.error('Failed to initialize hook manager', { error: err })\n }\n }, [messageLogName, forkNumber])\n\n // Update background shells periodically\n useEffect(() => {\n const interval = setInterval(() => {\n const shells = BackgroundShellManager.getInstance().list()\n setBackgroundShells(shells)\n }, 1000)\n\n return () => clearInterval(interval)\n }, [])\n\n const normalizedMessages = useMemo(\n () => normalizeMessages(messages).filter(isNotEmptyMessage),\n [messages],\n )\n\n const unresolvedToolUseIDs = useMemo(\n () => getUnresolvedToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const inProgressToolUseIDs = useMemo(\n () => getInProgressToolUseIDs(normalizedMessages),\n [normalizedMessages],\n )\n\n const erroredToolUseIDs = useMemo(\n () =>\n new Set(\n getErroredToolUseMessages(normalizedMessages).map(\n _ => (_.message.content[0]! as ToolUseBlockParam).id,\n ),\n ),\n [normalizedMessages],\n )\n\n const messagesJSX = useMemo(() => {\n return [\n {\n type: 'static',\n jsx: (\n <Box flexDirection=\"column\" key={`logo${forkNumber}`}>\n <Logo\n mcpClients={mcpClients}\n isDefaultModel={isDefaultModel}\n updateBannerVersion={updateAvailableVersion}\n updateBannerCommands={updateCommands}\n />\n <ProjectOnboarding workspaceDir={getOriginalCwd()} />\n </Box>\n ),\n },\n ...reorderMessages(normalizedMessages).map(_ => {\n const toolUseID = getToolUseID(_)\n const message =\n _.type === 'progress' ? (\n _.content.message.content[0]?.type === 'text' &&\n // TaskTool interrupts use Progress messages without extra \u23BF \n // since <Message /> component already adds the margin\n _.content.message.content[0].text === INTERRUPT_MESSAGE ? (\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={new Set()}\n shouldAnimate={false}\n shouldShowDot={false}\n />\n ) : (\n <MessageResponse children={\n <Message\n message={_.content}\n messages={_.normalizedMessages}\n addMargin={false}\n tools={_.tools}\n verbose={verbose ?? false}\n debug={debug}\n erroredToolUseIDs={new Set()}\n inProgressToolUseIDs={new Set()}\n unresolvedToolUseIDs={\n new Set([\n (_.content.message.content[0]! as ToolUseBlockParam).id,\n ])\n }\n shouldAnimate={false}\n shouldShowDot={false}\n />\n } />\n )\n ) : (\n <Message\n message={_}\n messages={normalizedMessages}\n addMargin={true}\n tools={tools}\n verbose={verbose}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n shouldAnimate={\n !toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n (!toolUseID || inProgressToolUseIDs.has(toolUseID))\n }\n shouldShowDot={true}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )\n\n const type = shouldRenderStatically(\n _,\n normalizedMessages,\n unresolvedToolUseIDs,\n )\n ? 'static'\n : 'transient'\n\n if (debug) {\n return {\n type,\n jsx: (\n <Box\n borderStyle=\"single\"\n borderColor={type === 'static' ? 'green' : 'red'}\n key={_.uuid}\n width=\"100%\"\n >\n {message}\n </Box>\n ),\n }\n }\n\n return {\n type,\n jsx: (\n <Box key={_.uuid} width=\"100%\">\n {message}\n </Box>\n ),\n }\n }),\n ]\n }, [\n forkNumber,\n normalizedMessages,\n tools,\n verbose,\n debug,\n erroredToolUseIDs,\n inProgressToolUseIDs,\n toolJSX,\n toolUseConfirm,\n isMessageSelectorVisible,\n unresolvedToolUseIDs,\n mcpClients,\n isDefaultModel,\n ])\n\n // only show the dialog once not loading\n const showingCostDialog = !isLoading && showCostDialog\n\n return (\n <PermissionProvider \n isBypassPermissionsModeAvailable={!safeMode}\n children={\n <React.Fragment>\n {/* Update banner now renders inside Logo for stable placement */}\n <ModeIndicator />\n <React.Fragment key={`static-messages-${forkNumber}`}>\n <Static\n items={messagesJSX.filter(_ => _.type === 'static')}\n children={(item: any) => item.jsx}\n />\n </React.Fragment>\n {messagesJSX.filter(_ => _.type === 'transient').map(_ => _.jsx)}\n <Box\n borderColor=\"red\"\n borderStyle={debug ? 'single' : undefined}\n flexDirection=\"column\"\n width=\"100%\"\n >\n {!toolJSX && !toolUseConfirm && !binaryFeedbackContext && isLoading && (\n <Spinner />\n )}\n {toolJSX ? toolJSX.jsx : null}\n {!toolJSX && binaryFeedbackContext && !isMessageSelectorVisible && (\n <BinaryFeedback\n m1={binaryFeedbackContext.m1}\n m2={binaryFeedbackContext.m2}\n resolve={result => {\n binaryFeedbackContext.resolve(result)\n setTimeout(() => setBinaryFeedbackContext(null), 0)\n }}\n verbose={verbose}\n normalizedMessages={normalizedMessages}\n tools={tools}\n debug={debug}\n erroredToolUseIDs={erroredToolUseIDs}\n inProgressToolUseIDs={inProgressToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n />\n )}\n {!toolJSX &&\n toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext && (\n <PermissionRequest\n toolUseConfirm={toolUseConfirm}\n onDone={() => setToolUseConfirm(null)}\n verbose={verbose}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n showingCostDialog && (\n <CostThresholdDialog\n onDone={() => {\n setShowCostDialog(false)\n setHaveShownCostDialog(true)\n const projectConfig = getGlobalConfig()\n saveGlobalConfig({\n ...projectConfig,\n hasAcknowledgedCostThreshold: true,\n })\n \n }}\n />\n )}\n\n {!toolUseConfirm &&\n !toolJSX?.shouldHidePromptInput &&\n shouldShowPromptInput &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n !showingCostDialog && (\n <>\n {/* TodoPanel - Fixed display above input */}\n <TodoPanel\n todos={getTodos()}\n isVisible={isTodoPanelVisible}\n elapsedTime={Math.floor((Date.now() - startTime) / 1000)}\n tokenCount={0}\n isLoading={isLoading}\n />\n {/* BackgroundTasksPanel */}\n <BackgroundTasksPanel\n shells={backgroundShells}\n isVisible={showBackgroundPanel}\n onSelect={(shell) => {\n // View shell details (could show detailed output)\n setShowBackgroundPanel(false)\n }}\n onKill={(shell) => {\n BackgroundShellManager.getInstance().kill(shell.id)\n }}\n onClose={() => setShowBackgroundPanel(false)}\n />\n <PromptInput\n commands={commands}\n forkNumber={forkNumber}\n messageLogName={messageLogName}\n tools={tools}\n isDisabled={apiKeyStatus === 'invalid'}\n isLoading={isLoading}\n onQuery={onQuery}\n debug={debug}\n verbose={verbose}\n messages={messages}\n setToolJSX={setToolJSX}\n input={inputValue}\n onInputChange={setInputValue}\n mode={inputMode}\n onModeChange={setInputMode}\n submitCount={submitCount}\n onSubmitCountChange={setSubmitCount}\n setIsLoading={setIsLoading}\n setAbortController={setAbortController}\n onShowMessageSelector={() =>\n setIsMessageSelectorVisible(prev => !prev)\n }\n setForkConvoWithMessagesOnTheNextRender={\n setForkConvoWithMessagesOnTheNextRender\n }\n readFileTimestamps={readFileTimestamps.current}\n abortController={abortController}\n onModelChange={() => setForkNumber(prev => prev + 1)}\n onRollbackConversation={rollbackConversation}\n onToggleTodoPanel={() => setIsTodoPanelVisible(prev => !prev)}\n onToggleVerbose={() => setVerbose(prev => !prev)}\n onToggleBackgroundPanel={() => setShowBackgroundPanel(prev => !prev)}\n backgroundShellCount={backgroundShells.filter(s => s.status === 'running').length}\n isBackgroundPanelOpen={showBackgroundPanel}\n fallbackMode={fallbackMode}\n />\n </>\n )}\n </Box>\n {isMessageSelectorVisible && (\n <MessageSelector\n erroredToolUseIDs={erroredToolUseIDs}\n unresolvedToolUseIDs={unresolvedToolUseIDs}\n messages={normalizeMessagesForAPI(messages)}\n onSelect={async message => {\n setIsMessageSelectorVisible(false)\n\n // If the user selected the current prompt, do nothing\n if (!messages.includes(message)) {\n return\n }\n\n // Cancel tool use calls/requests\n onCancel()\n\n // Hack: make sure the \"Interrupted by user\" message is\n // rendered in response to the cancellation. Otherwise,\n // the screen will be cleared but there will remain a\n // vestigial \"Interrupted by user\" message at the top.\n setImmediate(async () => {\n // Clear messages, and re-render\n await clearTerminal()\n setMessages([])\n setForkConvoWithMessagesOnTheNextRender(\n messages.slice(0, messages.indexOf(message)),\n )\n\n // Populate/reset the prompt input\n if (typeof message.message.content === 'string') {\n setInputValue(message.message.content)\n }\n })\n }}\n onEscape={() => setIsMessageSelectorVisible(false)}\n tools={tools}\n />\n )}\n {/** Fix occasional rendering artifact */}\n <Newline />\n </React.Fragment>\n }\n />\n )\n}\n\nfunction shouldRenderStatically(\n message: NormalizedMessage,\n messages: NormalizedMessage[],\n unresolvedToolUseIDs: Set<string>,\n): boolean {\n switch (message.type) {\n case 'user':\n case 'assistant': {\n const toolUseID = getToolUseID(message)\n if (!toolUseID) {\n return true\n }\n if (unresolvedToolUseIDs.has(toolUseID)) {\n return false\n }\n\n const correspondingProgressMessage = messages.find(\n _ => _.type === 'progress' && _.toolUseID === toolUseID,\n ) as ProgressMessage | null\n if (!correspondingProgressMessage) {\n return true\n }\n\n return !intersects(\n unresolvedToolUseIDs,\n correspondingProgressMessage.siblingToolUseIDs,\n )\n }\n case 'progress':\n return !intersects(unresolvedToolUseIDs, message.siblingToolUseIDs)\n }\n}\n\nfunction intersects<A>(a: Set<A>, b: Set<A>): boolean {\n return a.size > 0 && b.size > 0 && [...a].some(_ => b.has(_))\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["model"]
7
7
  }
@@ -58,10 +58,11 @@ async function executeHook(hook, input, options) {
58
58
  output
59
59
  };
60
60
  } catch (error) {
61
- logError(`Hook ${hook.name} execution error:`, error);
61
+ const errorMsg = error instanceof Error ? error.message : String(error);
62
+ logError(`Hook ${hook.name} execution error: ${errorMsg}`);
62
63
  return {
63
64
  success: false,
64
- error: error instanceof Error ? error.message : String(error)
65
+ error: errorMsg
65
66
  };
66
67
  }
67
68
  }
@@ -162,7 +163,8 @@ function parseHookOutput(stdout) {
162
163
  }
163
164
  return output;
164
165
  } catch (error) {
165
- logError("Failed to parse hook output JSON:", error);
166
+ const errorMsg = error instanceof Error ? error.message : String(error);
167
+ logError(`Failed to parse hook output JSON: ${errorMsg}`);
166
168
  logDebug("Raw output:", stdout);
167
169
  return null;
168
170
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/services/hookExecutor.ts"],
4
- "sourcesContent": ["/**\n * Hook Execution Engine\n *\n * Executes plugin hooks with bash command execution, JSON I/O,\n * and decision processing (approve/block/ask).\n *\n * Fully compatible with Claude Code CLI hooks specification.\n */\n\nimport { spawn } from 'child_process'\nimport { homedir } from 'os'\nimport { join } from 'path'\nimport {\n HookEvent,\n HookInput,\n HookOutput,\n HookDecision,\n PreToolUseInput,\n PostToolUseInput,\n UserPromptSubmitInput,\n SessionStartInput,\n SessionEndInput,\n} from '../types/hooks'\nimport { LoadedHook } from '../types/plugin'\nimport { getCwd } from '../utils/state'\nimport { logError } from '../utils/log'\n\n// Simple logging helpers\nconst logInfo = (msg: string) => {\n // Only log in debug mode to reduce noise\n if (process.env.DEBUG) console.log(`[INFO] ${msg}`)\n}\nconst logDebug = (msg: string, ...args: any[]) => {\n if (process.env.DEBUG) console.log(`[DEBUG] ${msg}`, ...args)\n}\n\n/**\n * Hook execution result\n */\nexport interface HookExecutionResult {\n success: boolean\n decision?: HookDecision\n output?: HookOutput\n error?: string\n timedOut?: boolean\n}\n\n/**\n * Hook execution options\n */\nexport interface HookExecutionOptions {\n timeout?: number\n sessionId: string\n transcriptPath?: string\n pluginRoot: string\n}\n\n/**\n * Execute a hook with bash command\n */\nexport async function executeHook(\n hook: LoadedHook,\n input: HookInput,\n options: HookExecutionOptions,\n): Promise<HookExecutionResult> {\n // Only execute command-type hooks\n if (hook.config.type !== 'command' || !hook.config.command) {\n return {\n success: false,\n error: `Hook type \"${hook.config.type}\" not yet implemented`,\n }\n }\n\n const timeout = hook.config.timeout || options.timeout || 30000 // 30 seconds default\n\n try {\n logDebug(`Executing hook: ${hook.name}`)\n logDebug(`Command: ${hook.config.command}`)\n\n // Execute bash command with JSON input via stdin\n const result = await executeBashCommand(\n hook.config.command,\n input,\n {\n ...options,\n timeout,\n pluginRoot: options.pluginRoot,\n },\n )\n\n if (result.timedOut) {\n logError(`Hook ${hook.name} timed out after ${timeout}ms`)\n return {\n success: false,\n timedOut: true,\n error: `Hook execution timed out after ${timeout}ms`,\n }\n }\n\n if (result.error) {\n logError(`Hook ${hook.name} failed: ${result.error}`)\n return {\n success: false,\n error: result.error,\n }\n }\n\n // Parse JSON output\n const output = parseHookOutput(result.stdout)\n\n if (!output) {\n // No output means hook executed successfully but didn't return decisions\n return {\n success: true,\n }\n }\n\n logDebug(`Hook ${hook.name} output:`, output)\n\n return {\n success: true,\n decision: output.decision,\n output,\n }\n } catch (error) {\n logError(`Hook ${hook.name} execution error:`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n/**\n * Execute bash command with JSON stdin/stdout\n */\nasync function executeBashCommand(\n command: string,\n input: HookInput,\n options: {\n timeout: number\n sessionId: string\n transcriptPath?: string\n pluginRoot: string\n },\n): Promise<{\n stdout: string\n stderr: string\n error?: string\n timedOut?: boolean\n}> {\n return new Promise((resolve) => {\n // Prepare environment variables\n const env = {\n ...process.env,\n CLAUDE_PLUGIN_ROOT: options.pluginRoot,\n CLAUDE_SESSION_ID: options.sessionId,\n CLAUDE_CWD: getCwd(),\n CLAUDE_TRANSCRIPT_PATH: options.transcriptPath || '',\n }\n\n // Spawn bash process\n const child = spawn('bash', ['-c', command], {\n env,\n cwd: getCwd(),\n })\n\n let stdout = ''\n let stderr = ''\n let timedOut = false\n\n // Set timeout\n const timer = setTimeout(() => {\n timedOut = true\n child.kill('SIGTERM')\n setTimeout(() => {\n if (!child.killed) {\n child.kill('SIGKILL')\n }\n }, 1000)\n }, options.timeout)\n\n // Collect stdout\n child.stdout?.on('data', (data) => {\n stdout += data.toString()\n })\n\n // Collect stderr\n child.stderr?.on('data', (data) => {\n stderr += data.toString()\n })\n\n // Handle completion\n child.on('close', (code) => {\n clearTimeout(timer)\n\n if (timedOut) {\n resolve({\n stdout: '',\n stderr: '',\n timedOut: true,\n })\n return\n }\n\n if (code !== 0 && code !== null) {\n resolve({\n stdout,\n stderr,\n error: `Command exited with code ${code}: ${stderr}`,\n })\n return\n }\n\n resolve({\n stdout,\n stderr,\n })\n })\n\n // Handle errors\n child.on('error', (error) => {\n clearTimeout(timer)\n resolve({\n stdout: '',\n stderr: '',\n error: `Failed to spawn process: ${error.message}`,\n })\n })\n\n // Send JSON input via stdin\n try {\n if (child.stdin) {\n child.stdin.write(JSON.stringify(input, null, 2))\n child.stdin.end()\n }\n } catch (error) {\n clearTimeout(timer)\n child.kill()\n resolve({\n stdout: '',\n stderr: '',\n error: `Failed to write to stdin: ${error instanceof Error ? error.message : String(error)}`,\n })\n }\n })\n}\n\n/**\n * Parse hook output JSON\n */\nfunction parseHookOutput(stdout: string): HookOutput | null {\n if (!stdout.trim()) {\n return null\n }\n\n try {\n // Try to extract JSON from output (hook might print other things)\n const jsonMatch = stdout.match(/\\{[\\s\\S]*\\}/)\n if (!jsonMatch) {\n logDebug('No JSON found in hook output')\n return null\n }\n\n const output = JSON.parse(jsonMatch[0]) as HookOutput\n\n // Validate decision if present\n if (output.decision) {\n if (!['approve', 'block', 'ask'].includes(output.decision)) {\n logError(`Invalid hook decision: ${output.decision}`)\n return null\n }\n }\n\n return output\n } catch (error) {\n logError('Failed to parse hook output JSON:', error)\n logDebug('Raw output:', stdout)\n return null\n }\n}\n\n/**\n * Execute all matching hooks for an event\n */\nexport async function executeHooksForEvent(\n event: HookEvent,\n hooks: LoadedHook[],\n input: HookInput,\n options: HookExecutionOptions,\n): Promise<HookExecutionResult[]> {\n // Filter hooks for this event\n const matchingHooks = hooks.filter((hook) => hook.event === event)\n\n if (matchingHooks.length === 0) {\n return []\n }\n\n logInfo(`Executing ${matchingHooks.length} hook(s) for event: ${event}`)\n\n // Execute all matching hooks in parallel (Claude Code behavior)\n const results = await Promise.all(\n matchingHooks.map((hook) => executeHook(hook, input, options)),\n )\n\n return results\n}\n\n/**\n * Process hook decisions to determine final action\n */\nexport function processHookDecisions(\n results: HookExecutionResult[],\n): {\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n} {\n // If any hook says \"block\", we block\n const blockedResult = results.find(\n (r) => r.success && r.decision === 'block',\n )\n if (blockedResult) {\n return {\n shouldContinue: false,\n shouldAskUser: false,\n reason: blockedResult.output?.reason || 'Blocked by hook',\n }\n }\n\n // If any hook says \"ask\", we ask the user\n const askResult = results.find((r) => r.success && r.decision === 'ask')\n if (askResult) {\n return {\n shouldContinue: false,\n shouldAskUser: true,\n reason: askResult.output?.reason || 'Hook requested user approval',\n }\n }\n\n // If any hook failed, we ask the user (fail-safe)\n const failedResult = results.find((r) => !r.success)\n if (failedResult) {\n return {\n shouldContinue: false,\n shouldAskUser: true,\n reason: `Hook execution failed: ${failedResult.error}`,\n }\n }\n\n // All hooks approved or had no decision\n return {\n shouldContinue: true,\n shouldAskUser: false,\n }\n}\n\n/**\n * Create hook input for PreToolUse event\n */\nexport function createPreToolUseInput(\n sessionId: string,\n transcriptPath: string,\n toolName: string,\n toolInput: Record<string, unknown>,\n): PreToolUseInput {\n return {\n hook_event_name: HookEvent.PreToolUse,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n tool_name: toolName,\n tool_input: toolInput,\n }\n}\n\n/**\n * Create hook input for PostToolUse event\n */\nexport function createPostToolUseInput(\n sessionId: string,\n transcriptPath: string,\n toolName: string,\n toolInput: Record<string, unknown>,\n toolOutput: Record<string, unknown>,\n): PostToolUseInput {\n return {\n hook_event_name: HookEvent.PostToolUse,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n tool_name: toolName,\n tool_input: toolInput,\n tool_output: toolOutput,\n }\n}\n\n/**\n * Create hook input for UserPromptSubmit event\n */\nexport function createUserPromptSubmitInput(\n sessionId: string,\n transcriptPath: string,\n userPrompt: string,\n): UserPromptSubmitInput {\n return {\n hook_event_name: HookEvent.UserPromptSubmit,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n user_prompt: userPrompt,\n }\n}\n\n/**\n * Create hook input for SessionStart event\n */\nexport function createSessionStartInput(\n sessionId: string,\n transcriptPath: string,\n): SessionStartInput {\n return {\n hook_event_name: HookEvent.SessionStart,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n source: 'startup' as const,\n permission_mode: 'default',\n }\n}\n\n/**\n * Create hook input for SessionEnd event\n */\nexport function createSessionEndInput(\n sessionId: string,\n transcriptPath: string,\n reason: 'clear' | 'logout' | 'prompt_input_exit' | 'other',\n): SessionEndInput {\n return {\n hook_event_name: HookEvent.SessionEnd,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n reason: reason,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Hook Execution Engine\n *\n * Executes plugin hooks with bash command execution, JSON I/O,\n * and decision processing (approve/block/ask).\n *\n * Fully compatible with Claude Code CLI hooks specification.\n */\n\nimport { spawn } from 'child_process'\nimport { homedir } from 'os'\nimport { join } from 'path'\nimport {\n HookEvent,\n HookInput,\n HookOutput,\n HookDecision,\n PreToolUseInput,\n PostToolUseInput,\n UserPromptSubmitInput,\n SessionStartInput,\n SessionEndInput,\n} from '../types/hooks'\nimport { LoadedHook } from '../types/plugin'\nimport { getCwd } from '../utils/state'\nimport { logError } from '../utils/log'\n\n// Simple logging helpers\nconst logInfo = (msg: string) => {\n // Only log in debug mode to reduce noise\n if (process.env.DEBUG) console.log(`[INFO] ${msg}`)\n}\nconst logDebug = (msg: string, ...args: any[]) => {\n if (process.env.DEBUG) console.log(`[DEBUG] ${msg}`, ...args)\n}\n\n/**\n * Hook execution result\n */\nexport interface HookExecutionResult {\n success: boolean\n decision?: 'approve' | 'block' | 'ask'\n output?: HookOutput\n error?: string\n timedOut?: boolean\n}\n\n/**\n * Hook execution options\n */\nexport interface HookExecutionOptions {\n timeout?: number\n sessionId: string\n transcriptPath?: string\n pluginRoot: string\n}\n\n/**\n * Execute a hook with bash command\n */\nexport async function executeHook(\n hook: LoadedHook,\n input: HookInput,\n options: HookExecutionOptions,\n): Promise<HookExecutionResult> {\n // Only execute command-type hooks\n if (hook.config.type !== 'command' || !hook.config.command) {\n return {\n success: false,\n error: `Hook type \"${hook.config.type}\" not yet implemented`,\n }\n }\n\n const timeout = hook.config.timeout || options.timeout || 30000 // 30 seconds default\n\n try {\n logDebug(`Executing hook: ${hook.name}`)\n logDebug(`Command: ${hook.config.command}`)\n\n // Execute bash command with JSON input via stdin\n const result = await executeBashCommand(\n hook.config.command,\n input,\n {\n ...options,\n timeout,\n pluginRoot: options.pluginRoot,\n },\n )\n\n if (result.timedOut) {\n logError(`Hook ${hook.name} timed out after ${timeout}ms`)\n return {\n success: false,\n timedOut: true,\n error: `Hook execution timed out after ${timeout}ms`,\n }\n }\n\n if (result.error) {\n logError(`Hook ${hook.name} failed: ${result.error}`)\n return {\n success: false,\n error: result.error,\n }\n }\n\n // Parse JSON output\n const output = parseHookOutput(result.stdout)\n\n if (!output) {\n // No output means hook executed successfully but didn't return decisions\n return {\n success: true,\n }\n }\n\n logDebug(`Hook ${hook.name} output:`, output)\n\n return {\n success: true,\n decision: output.decision,\n output,\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n logError(`Hook ${hook.name} execution error: ${errorMsg}`)\n return {\n success: false,\n error: errorMsg,\n }\n }\n}\n\n/**\n * Execute bash command with JSON stdin/stdout\n */\nasync function executeBashCommand(\n command: string,\n input: HookInput,\n options: {\n timeout: number\n sessionId: string\n transcriptPath?: string\n pluginRoot: string\n },\n): Promise<{\n stdout: string\n stderr: string\n error?: string\n timedOut?: boolean\n}> {\n return new Promise((resolve) => {\n // Prepare environment variables\n const env = {\n ...process.env,\n CLAUDE_PLUGIN_ROOT: options.pluginRoot,\n CLAUDE_SESSION_ID: options.sessionId,\n CLAUDE_CWD: getCwd(),\n CLAUDE_TRANSCRIPT_PATH: options.transcriptPath || '',\n }\n\n // Spawn bash process\n const child = spawn('bash', ['-c', command], {\n env,\n cwd: getCwd(),\n })\n\n let stdout = ''\n let stderr = ''\n let timedOut = false\n\n // Set timeout\n const timer = setTimeout(() => {\n timedOut = true\n child.kill('SIGTERM')\n setTimeout(() => {\n if (!child.killed) {\n child.kill('SIGKILL')\n }\n }, 1000)\n }, options.timeout)\n\n // Collect stdout\n child.stdout?.on('data', (data) => {\n stdout += data.toString()\n })\n\n // Collect stderr\n child.stderr?.on('data', (data) => {\n stderr += data.toString()\n })\n\n // Handle completion\n child.on('close', (code) => {\n clearTimeout(timer)\n\n if (timedOut) {\n resolve({\n stdout: '',\n stderr: '',\n timedOut: true,\n })\n return\n }\n\n if (code !== 0 && code !== null) {\n resolve({\n stdout,\n stderr,\n error: `Command exited with code ${code}: ${stderr}`,\n })\n return\n }\n\n resolve({\n stdout,\n stderr,\n })\n })\n\n // Handle errors\n child.on('error', (error) => {\n clearTimeout(timer)\n resolve({\n stdout: '',\n stderr: '',\n error: `Failed to spawn process: ${error.message}`,\n })\n })\n\n // Send JSON input via stdin\n try {\n if (child.stdin) {\n child.stdin.write(JSON.stringify(input, null, 2))\n child.stdin.end()\n }\n } catch (error) {\n clearTimeout(timer)\n child.kill()\n resolve({\n stdout: '',\n stderr: '',\n error: `Failed to write to stdin: ${error instanceof Error ? error.message : String(error)}`,\n })\n }\n })\n}\n\n/**\n * Parse hook output JSON\n */\nfunction parseHookOutput(stdout: string): HookOutput | null {\n if (!stdout.trim()) {\n return null\n }\n\n try {\n // Try to extract JSON from output (hook might print other things)\n const jsonMatch = stdout.match(/\\{[\\s\\S]*\\}/)\n if (!jsonMatch) {\n logDebug('No JSON found in hook output')\n return null\n }\n\n const output = JSON.parse(jsonMatch[0]) as HookOutput\n\n // Validate decision if present\n if (output.decision) {\n if (!['approve', 'block', 'ask'].includes(output.decision)) {\n logError(`Invalid hook decision: ${output.decision}`)\n return null\n }\n }\n\n return output\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error)\n logError(`Failed to parse hook output JSON: ${errorMsg}`)\n logDebug('Raw output:', stdout)\n return null\n }\n}\n\n/**\n * Execute all matching hooks for an event\n */\nexport async function executeHooksForEvent(\n event: HookEvent,\n hooks: LoadedHook[],\n input: HookInput,\n options: HookExecutionOptions,\n): Promise<HookExecutionResult[]> {\n // Filter hooks for this event\n const matchingHooks = hooks.filter((hook) => hook.event === event)\n\n if (matchingHooks.length === 0) {\n return []\n }\n\n logInfo(`Executing ${matchingHooks.length} hook(s) for event: ${event}`)\n\n // Execute all matching hooks in parallel (Claude Code behavior)\n const results = await Promise.all(\n matchingHooks.map((hook) => executeHook(hook, input, options)),\n )\n\n return results\n}\n\n/**\n * Process hook decisions to determine final action\n */\nexport function processHookDecisions(\n results: HookExecutionResult[],\n): {\n shouldContinue: boolean\n shouldAskUser: boolean\n reason?: string\n} {\n // If any hook says \"block\", we block\n const blockedResult = results.find(\n (r) => r.success && r.decision === 'block',\n )\n if (blockedResult) {\n return {\n shouldContinue: false,\n shouldAskUser: false,\n reason: blockedResult.output?.reason || 'Blocked by hook',\n }\n }\n\n // If any hook says \"ask\", we ask the user\n const askResult = results.find((r) => r.success && r.decision === 'ask')\n if (askResult) {\n return {\n shouldContinue: false,\n shouldAskUser: true,\n reason: askResult.output?.reason || 'Hook requested user approval',\n }\n }\n\n // If any hook failed, we ask the user (fail-safe)\n const failedResult = results.find((r) => !r.success)\n if (failedResult) {\n return {\n shouldContinue: false,\n shouldAskUser: true,\n reason: `Hook execution failed: ${failedResult.error}`,\n }\n }\n\n // All hooks approved or had no decision\n return {\n shouldContinue: true,\n shouldAskUser: false,\n }\n}\n\n/**\n * Create hook input for PreToolUse event\n */\nexport function createPreToolUseInput(\n sessionId: string,\n transcriptPath: string,\n toolName: string,\n toolInput: Record<string, unknown>,\n): PreToolUseInput {\n return {\n hook_event_name: HookEvent.PreToolUse,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n tool_name: toolName,\n tool_input: toolInput,\n }\n}\n\n/**\n * Create hook input for PostToolUse event\n */\nexport function createPostToolUseInput(\n sessionId: string,\n transcriptPath: string,\n toolName: string,\n toolInput: Record<string, unknown>,\n toolOutput: Record<string, unknown>,\n): PostToolUseInput {\n return {\n hook_event_name: HookEvent.PostToolUse,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n tool_name: toolName,\n tool_input: toolInput,\n tool_output: toolOutput,\n }\n}\n\n/**\n * Create hook input for UserPromptSubmit event\n */\nexport function createUserPromptSubmitInput(\n sessionId: string,\n transcriptPath: string,\n userPrompt: string,\n): UserPromptSubmitInput {\n return {\n hook_event_name: HookEvent.UserPromptSubmit,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n user_prompt: userPrompt,\n }\n}\n\n/**\n * Create hook input for SessionStart event\n */\nexport function createSessionStartInput(\n sessionId: string,\n transcriptPath: string,\n): SessionStartInput {\n return {\n hook_event_name: HookEvent.SessionStart,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n source: 'startup' as const,\n permission_mode: 'default',\n }\n}\n\n/**\n * Create hook input for SessionEnd event\n */\nexport function createSessionEndInput(\n sessionId: string,\n transcriptPath: string,\n reason: 'clear' | 'logout' | 'prompt_input_exit' | 'other',\n): SessionEndInput {\n return {\n hook_event_name: HookEvent.SessionEnd,\n session_id: sessionId,\n transcript_path: transcriptPath,\n cwd: getCwd(),\n permission_mode: 'default',\n reason: reason,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -437,7 +437,8 @@ async function installPluginFromMarketplace(pluginName, marketplaceName, targetD
437
437
  if (!existsSync(pluginManifestPath)) {
438
438
  const pluginManifest = {
439
439
  name: plugin.name,
440
- displayName: plugin.displayName || plugin.name,
440
+ displayName: plugin.name,
441
+ // Use name as displayName for marketplace plugins
441
442
  version: plugin.version || "1.0.0",
442
443
  description: plugin.description || "",
443
444
  author: plugin.author,