@within-7/minto 0.1.2 → 0.1.4

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.
Files changed (36) hide show
  1. package/dist/commands/build.js +74 -0
  2. package/dist/commands/build.js.map +7 -0
  3. package/dist/commands/mcp.js +40 -0
  4. package/dist/commands/mcp.js.map +7 -0
  5. package/dist/commands/mcp_refresh.js +40 -0
  6. package/dist/commands/mcp_refresh.js.map +7 -0
  7. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +140 -0
  8. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +7 -0
  9. package/dist/components/AskUserQuestionDialog/QuestionView.js +45 -0
  10. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +7 -0
  11. package/dist/components/AskUserQuestionDialog/index.js +7 -0
  12. package/dist/components/AskUserQuestionDialog/index.js.map +7 -0
  13. package/dist/components/TodoPanel.js +2 -3
  14. package/dist/components/TodoPanel.js.map +2 -2
  15. package/dist/entrypoints/cli-wrapper.js +61 -0
  16. package/dist/entrypoints/cli-wrapper.js.map +7 -0
  17. package/dist/entrypoints/cli.js +0 -0
  18. package/dist/hooks/useAskUser.js +24 -0
  19. package/dist/hooks/useAskUser.js.map +7 -0
  20. package/dist/query.js.map +2 -2
  21. package/dist/screens/REPL.js +18 -5
  22. package/dist/screens/REPL.js.map +2 -2
  23. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +113 -0
  24. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +7 -0
  25. package/dist/tools/AskUserQuestionTool/index.js +5 -0
  26. package/dist/tools/AskUserQuestionTool/index.js.map +7 -0
  27. package/dist/tools/AskUserQuestionTool/prompt.js +167 -0
  28. package/dist/tools/AskUserQuestionTool/prompt.js.map +7 -0
  29. package/dist/tools.js +2 -0
  30. package/dist/tools.js.map +2 -2
  31. package/dist/types/askUserQuestion.js +1 -0
  32. package/dist/types/askUserQuestion.js.map +7 -0
  33. package/dist/version.js +7 -0
  34. package/dist/version.js.map +7 -0
  35. package/package.json +17 -15
  36. package/.npmrc +0 -3
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/hooks/useAskUser.ts"],
4
+ "sourcesContent": ["import * as React from 'react'\nimport { useCallback } from 'react'\nimport type {\n UserQuestion,\n UserAnswer,\n AskUserQuestionContext,\n} from '@minto-types/askUserQuestion'\n\ntype SetState<T> = React.Dispatch<React.SetStateAction<T>>\n\n/**\n * Function type for asking the user questions\n */\nexport type AskUserFn = (questions: UserQuestion[]) => Promise<UserAnswer[]>\n\n/**\n * Hook to provide the askUser function for triggering user question dialogs\n *\n * Similar to useCanUseTool, this creates a Promise-based interaction\n * where the dialog is shown and the promise resolves when the user responds.\n *\n * @param setAskUserQuestionContext - State setter to trigger the dialog\n * @returns Function to ask user questions\n */\nfunction useAskUser(\n setAskUserQuestionContext: SetState<AskUserQuestionContext | null>,\n): AskUserFn {\n return useCallback<AskUserFn>(\n (questions: UserQuestion[]) => {\n return new Promise<UserAnswer[]>((resolve, reject) => {\n // Set the context to trigger the dialog render\n setAskUserQuestionContext({\n questions,\n resolve: (answers: UserAnswer[]) => {\n // User provided answers\n resolve(answers)\n },\n reject: () => {\n // User cancelled\n reject(new Error('User cancelled the question dialog'))\n },\n })\n })\n },\n [setAskUserQuestionContext],\n )\n}\n\nexport default useAskUser\n"],
5
+ "mappings": "AACA,SAAS,mBAAmB;AAuB5B,SAAS,WACP,2BACW;AACX,SAAO;AAAA,IACL,CAAC,cAA8B;AAC7B,aAAO,IAAI,QAAsB,CAAC,SAAS,WAAW;AAEpD,kCAA0B;AAAA,UACxB;AAAA,UACA,SAAS,CAAC,YAA0B;AAElC,oBAAQ,OAAO;AAAA,UACjB;AAAA,UACA,QAAQ,MAAM;AAEZ,mBAAO,IAAI,MAAM,oCAAoC,CAAC;AAAA,UACxD;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,CAAC,yBAAyB;AAAA,EAC5B;AACF;AAEA,IAAO,qBAAQ;",
6
+ "names": []
7
+ }
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: 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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",
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, AskUserFn } 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 askUser?: AskUserFn\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
  }
@@ -63,6 +63,8 @@ import { randomUUID } from "crypto";
63
63
  import { getMessagesPath } from "../utils/log.js";
64
64
  import { BackgroundShellManager } from "../utils/BackgroundShellManager.js";
65
65
  import { BackgroundTasksPanel } from "../components/BackgroundTasksPanel.js";
66
+ import { AskUserQuestionDialog } from "../components/AskUserQuestionDialog/AskUserQuestionDialog.js";
67
+ import useAskUser from "../hooks/useAskUser.js";
66
68
  function REPL({
67
69
  commands,
68
70
  safeMode,
@@ -107,6 +109,7 @@ function REPL({
107
109
  getGlobalConfig().hasAcknowledgedCostThreshold
108
110
  );
109
111
  const [binaryFeedbackContext, setBinaryFeedbackContext] = useState(null);
112
+ const [askUserQuestionContext, setAskUserQuestionContext] = useState(null);
110
113
  const updateAvailableVersion = initialUpdateVersion ?? null;
111
114
  const updateCommands = initialUpdateCommands ?? null;
112
115
  const [isTodoPanelVisible, setIsTodoPanelVisible] = useState(true);
@@ -162,6 +165,7 @@ function REPL({
162
165
  }
163
166
  }, [messages, showCostDialog, haveShownCostDialog]);
164
167
  const canUseTool = useCanUseTool(setToolUseConfirm);
168
+ const askUser = useAskUser(setAskUserQuestionContext);
165
169
  async function onInit() {
166
170
  reverify();
167
171
  if (!initialPrompt) {
@@ -228,7 +232,8 @@ function REPL({
228
232
  messageId: getLastAssistantMessageId([...messages, ...newMessages]),
229
233
  readFileTimestamps: readFileTimestamps.current,
230
234
  abortController: newAbortController,
231
- setToolJSX
235
+ setToolJSX,
236
+ askUser
232
237
  },
233
238
  getBinaryFeedbackResponse
234
239
  )) {
@@ -298,7 +303,8 @@ function REPL({
298
303
  messageId: getLastAssistantMessageId([...messages, lastMessage]),
299
304
  readFileTimestamps: readFileTimestamps.current,
300
305
  abortController: controllerToUse,
301
- setToolJSX
306
+ setToolJSX,
307
+ askUser
302
308
  },
303
309
  getBinaryFeedbackResponse
304
310
  )) {
@@ -527,7 +533,7 @@ function REPL({
527
533
  unresolvedToolUseIDs
528
534
  }
529
535
  ),
530
- !toolJSX && toolUseConfirm && !isMessageSelectorVisible && !binaryFeedbackContext && /* @__PURE__ */ React.createElement(
536
+ !toolJSX && toolUseConfirm && !isMessageSelectorVisible && !binaryFeedbackContext && !askUserQuestionContext && /* @__PURE__ */ React.createElement(
531
537
  PermissionRequest,
532
538
  {
533
539
  toolUseConfirm,
@@ -535,7 +541,14 @@ function REPL({
535
541
  verbose
536
542
  }
537
543
  ),
538
- !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && !binaryFeedbackContext && showingCostDialog && /* @__PURE__ */ React.createElement(
544
+ !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && !binaryFeedbackContext && askUserQuestionContext && /* @__PURE__ */ React.createElement(
545
+ AskUserQuestionDialog,
546
+ {
547
+ context: askUserQuestionContext,
548
+ onDone: () => setAskUserQuestionContext(null)
549
+ }
550
+ ),
551
+ !toolJSX && !toolUseConfirm && !isMessageSelectorVisible && !binaryFeedbackContext && !askUserQuestionContext && showingCostDialog && /* @__PURE__ */ React.createElement(
539
552
  CostThresholdDialog,
540
553
  {
541
554
  onDone: () => {
@@ -549,7 +562,7 @@ function REPL({
549
562
  }
550
563
  }
551
564
  ),
552
- !toolUseConfirm && !toolJSX?.shouldHidePromptInput && shouldShowPromptInput && !isMessageSelectorVisible && !binaryFeedbackContext && !showingCostDialog && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
565
+ !toolUseConfirm && !toolJSX?.shouldHidePromptInput && shouldShowPromptInput && !isMessageSelectorVisible && !binaryFeedbackContext && !askUserQuestionContext && !showingCostDialog && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
553
566
  TodoPanel,
554
567
  {
555
568
  todos: getTodos(),
@@ -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 { 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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",
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'\nimport { AskUserQuestionDialog } from '@components/AskUserQuestionDialog/AskUserQuestionDialog'\nimport type { AskUserQuestionContext } from '@minto-types/askUserQuestion'\nimport useAskUser from '@hooks/useAskUser'\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 const [askUserQuestionContext, setAskUserQuestionContext] =\n useState<AskUserQuestionContext | 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 const askUser = useAskUser(setAskUserQuestionContext)\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 askUser,\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 askUser,\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 !askUserQuestionContext && (\n <PermissionRequest\n toolUseConfirm={toolUseConfirm}\n onDone={() => setToolUseConfirm(null)}\n verbose={verbose}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n askUserQuestionContext && (\n <AskUserQuestionDialog\n context={askUserQuestionContext}\n onDone={() => setAskUserQuestionContext(null)}\n />\n )}\n {!toolJSX &&\n !toolUseConfirm &&\n !isMessageSelectorVisible &&\n !binaryFeedbackContext &&\n !askUserQuestionContext &&\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 !askUserQuestionContext &&\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
6
  "names": ["model"]
7
7
  }
@@ -0,0 +1,113 @@
1
+ import { Box, Text } from "ink";
2
+ import * as React from "react";
3
+ import { z } from "zod";
4
+ import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUseRejectedMessage.js";
5
+ import { DESCRIPTION, PROMPT } from "./prompt.js";
6
+ const inputSchema = z.strictObject({
7
+ questions: z.array(
8
+ z.object({
9
+ question: z.string().describe("The question to ask the user"),
10
+ header: z.string().max(12).optional().describe("Short category label (max 12 chars)"),
11
+ options: z.array(
12
+ z.object({
13
+ label: z.string().describe("Option display text"),
14
+ description: z.string().optional().describe("Option explanation")
15
+ })
16
+ ).min(2).max(4).optional().describe("List of options (2-4 recommended)"),
17
+ multiSelect: z.boolean().optional().default(false).describe("Allow multiple selections")
18
+ })
19
+ ).min(1).max(4).describe("Questions to ask (1-4 questions)")
20
+ });
21
+ const AskUserQuestionTool = {
22
+ name: "AskUserQuestion",
23
+ async description() {
24
+ return DESCRIPTION;
25
+ },
26
+ async prompt() {
27
+ return PROMPT;
28
+ },
29
+ inputSchema,
30
+ userFacingName() {
31
+ return "Ask User Question";
32
+ },
33
+ async isEnabled() {
34
+ return true;
35
+ },
36
+ isReadOnly() {
37
+ return true;
38
+ },
39
+ isConcurrencySafe() {
40
+ return false;
41
+ },
42
+ needsPermissions() {
43
+ return false;
44
+ },
45
+ renderResultForAssistant(output) {
46
+ const formattedAnswers = output.answers.map((answer) => {
47
+ if (answer.customInput) {
48
+ return `Q${answer.questionIndex + 1}: "${answer.customInput}"`;
49
+ }
50
+ if (answer.selectedOptions) {
51
+ return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map((i) => i + 1).join(", ")}`;
52
+ }
53
+ return `Q${answer.questionIndex + 1}: No answer`;
54
+ }).join("\n");
55
+ return `User answered:
56
+ ${formattedAnswers}`;
57
+ },
58
+ renderToolUseMessage(input) {
59
+ const questionCount = input.questions.length;
60
+ const questionText = questionCount === 1 ? input.questions[0].question : `${questionCount} questions`;
61
+ return `Asking user: ${questionText}`;
62
+ },
63
+ renderToolUseRejectedMessage() {
64
+ return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
65
+ },
66
+ renderToolResultMessage(output) {
67
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: "#10B981" }, " ", "\u23BF "), /* @__PURE__ */ React.createElement(Text, null, "User provided answers")), output.answers.map((answer, index) => /* @__PURE__ */ React.createElement(Box, { key: index, flexDirection: "row", paddingLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { color: "#6B7280" }, "\u2022 "), answer.customInput ? /* @__PURE__ */ React.createElement(Text, null, "Q", answer.questionIndex + 1, ': "', answer.customInput, '"') : answer.selectedOptions ? /* @__PURE__ */ React.createElement(Text, null, "Q", answer.questionIndex + 1, ": Option", " ", answer.selectedOptions.map((i) => i + 1).join(", ")) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Q", answer.questionIndex + 1, ": No answer"))));
68
+ },
69
+ async *call({ questions }, context) {
70
+ if (!context.askUser) {
71
+ throw new Error(
72
+ "AskUserQuestion tool requires askUser function in context"
73
+ );
74
+ }
75
+ try {
76
+ const userQuestions = questions.map((q) => ({
77
+ question: q.question,
78
+ header: q.header,
79
+ options: q.options?.map((opt) => ({
80
+ label: opt.label,
81
+ description: opt.description
82
+ })),
83
+ multiSelect: q.multiSelect ?? false
84
+ }));
85
+ const answers = await context.askUser(userQuestions);
86
+ yield {
87
+ type: "result",
88
+ data: {
89
+ answers,
90
+ timestamp: Date.now()
91
+ },
92
+ resultForAssistant: `User answered:
93
+ ${answers.map((answer) => {
94
+ if (answer.customInput) {
95
+ return `Q${answer.questionIndex + 1}: "${answer.customInput}"`;
96
+ }
97
+ if (answer.selectedOptions) {
98
+ return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map((i) => i + 1).join(", ")}`;
99
+ }
100
+ return `Q${answer.questionIndex + 1}: No answer`;
101
+ }).join("\n")}`
102
+ };
103
+ } catch (error) {
104
+ throw new Error(
105
+ `Failed to get user response: ${error instanceof Error ? error.message : "Unknown error"}`
106
+ );
107
+ }
108
+ }
109
+ };
110
+ export {
111
+ AskUserQuestionTool
112
+ };
113
+ //# sourceMappingURL=AskUserQuestionTool.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx"],
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { Tool, type ExtendedToolUseContext } from '@tool'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport type { UserAnswer } from '@minto-types/askUserQuestion'\n\nconst inputSchema = z.strictObject({\n questions: z\n .array(\n z.object({\n question: z.string().describe('The question to ask the user'),\n header: z\n .string()\n .max(12)\n .optional()\n .describe('Short category label (max 12 chars)'),\n options: z\n .array(\n z.object({\n label: z.string().describe('Option display text'),\n description: z.string().optional().describe('Option explanation'),\n }),\n )\n .min(2)\n .max(4)\n .optional()\n .describe('List of options (2-4 recommended)'),\n multiSelect: z\n .boolean()\n .optional()\n .default(false)\n .describe('Allow multiple selections'),\n }),\n )\n .min(1)\n .max(4)\n .describe('Questions to ask (1-4 questions)'),\n})\n\nexport type AskUserQuestionOutput = {\n answers: UserAnswer[]\n timestamp: number\n}\n\nexport const AskUserQuestionTool = {\n name: 'AskUserQuestion',\n\n async description() {\n return DESCRIPTION\n },\n\n async prompt() {\n return PROMPT\n },\n\n inputSchema,\n\n userFacingName() {\n return 'Ask User Question'\n },\n\n async isEnabled() {\n return true\n },\n\n isReadOnly() {\n return true // Doesn't modify files\n },\n\n isConcurrencySafe() {\n return false // User interaction is not concurrent-safe\n },\n\n needsPermissions() {\n return false // No special permissions needed\n },\n\n renderResultForAssistant(output: AskUserQuestionOutput) {\n const formattedAnswers = output.answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')\n\n return `User answered:\\n${formattedAnswers}`\n },\n\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const questionCount = input.questions.length\n const questionText =\n questionCount === 1\n ? input.questions[0]!.question\n : `${questionCount} questions`\n return `Asking user: ${questionText}`\n },\n\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n\n renderToolResultMessage(output: AskUserQuestionOutput) {\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text color=\"#10B981\">{' '}\u23BF </Text>\n <Text>User provided answers</Text>\n </Box>\n {output.answers.map((answer, index) => (\n <Box key={index} flexDirection=\"row\" paddingLeft={4}>\n <Text color=\"#6B7280\">\u2022 </Text>\n {answer.customInput ? (\n <Text>\n Q{answer.questionIndex + 1}: \"{answer.customInput}\"\n </Text>\n ) : answer.selectedOptions ? (\n <Text>\n Q{answer.questionIndex + 1}: Option{' '}\n {answer.selectedOptions.map(i => i + 1).join(', ')}\n </Text>\n ) : (\n <Text dimColor>Q{answer.questionIndex + 1}: No answer</Text>\n )}\n </Box>\n ))}\n </Box>\n )\n },\n\n async *call(\n { questions }: z.infer<typeof inputSchema>,\n context: ExtendedToolUseContext,\n ) {\n // Check if askUser function is available\n if (!context.askUser) {\n throw new Error(\n 'AskUserQuestion tool requires askUser function in context',\n )\n }\n\n try {\n // Convert parsed questions to UserQuestion type\n const userQuestions = questions.map(q => ({\n question: q.question,\n header: q.header,\n options: q.options?.map(opt => ({\n label: opt.label,\n description: opt.description,\n })),\n multiSelect: q.multiSelect ?? false,\n }))\n\n // Call askUser and wait for user response\n const answers = await context.askUser(userQuestions)\n\n // Return the result\n yield {\n type: 'result',\n data: {\n answers,\n timestamp: Date.now(),\n },\n resultForAssistant: `User answered:\\n${answers\n .map(answer => {\n if (answer.customInput) {\n return `Q${answer.questionIndex + 1}: \"${answer.customInput}\"`\n }\n if (answer.selectedOptions) {\n return `Q${answer.questionIndex + 1}: Option ${answer.selectedOptions.map(i => i + 1).join(', ')}`\n }\n return `Q${answer.questionIndex + 1}: No answer`\n })\n .join('\\n')}`,\n }\n } catch (error) {\n // User cancelled or error occurred\n throw new Error(\n `Failed to get user response: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n },\n} satisfies Tool<typeof inputSchema, AskUserQuestionOutput>\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }