deepagentsdk 0.11.0 → 0.12.0

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 (103) hide show
  1. package/dist/adapters/elements/index.cjs +324 -0
  2. package/dist/adapters/elements/index.cjs.map +1 -0
  3. package/dist/adapters/elements/index.d.cts +212 -0
  4. package/dist/adapters/elements/index.d.mts +212 -0
  5. package/dist/adapters/elements/index.mjs +320 -0
  6. package/dist/adapters/elements/index.mjs.map +1 -0
  7. package/dist/agent-CrH-He58.mjs +2974 -0
  8. package/dist/agent-CrH-He58.mjs.map +1 -0
  9. package/dist/agent-Cuks-Idh.cjs +3396 -0
  10. package/dist/agent-Cuks-Idh.cjs.map +1 -0
  11. package/dist/chunk-CbDLau6x.cjs +34 -0
  12. package/dist/cli/index.cjs +3162 -0
  13. package/dist/cli/index.cjs.map +1 -0
  14. package/dist/cli/index.d.cts +1 -0
  15. package/dist/cli/index.d.mts +1 -0
  16. package/dist/cli/index.mjs +3120 -0
  17. package/dist/cli/index.mjs.map +1 -0
  18. package/dist/file-saver-BJCqMIb5.mjs +655 -0
  19. package/dist/file-saver-BJCqMIb5.mjs.map +1 -0
  20. package/dist/file-saver-C6O2LAvg.cjs +679 -0
  21. package/dist/file-saver-C6O2LAvg.cjs.map +1 -0
  22. package/dist/index.cjs +1471 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +1581 -0
  25. package/dist/index.d.mts +1581 -0
  26. package/dist/index.mjs +1371 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/load-79a2H4m0.cjs +163 -0
  29. package/dist/load-79a2H4m0.cjs.map +1 -0
  30. package/dist/load-94gjHorc.mjs +3 -0
  31. package/dist/load-B6CA5js_.mjs +142 -0
  32. package/dist/load-B6CA5js_.mjs.map +1 -0
  33. package/dist/load-C2qVmZMp.cjs +3 -0
  34. package/dist/types-4g9UvXal.d.mts +1151 -0
  35. package/dist/types-IulnvhFg.d.cts +1151 -0
  36. package/package.json +26 -12
  37. package/src/adapters/elements/index.ts +0 -27
  38. package/src/adapters/elements/messageAdapter.ts +0 -165
  39. package/src/adapters/elements/statusAdapter.ts +0 -39
  40. package/src/adapters/elements/types.ts +0 -97
  41. package/src/adapters/elements/useElementsAdapter.ts +0 -261
  42. package/src/agent.ts +0 -1258
  43. package/src/backends/composite.ts +0 -273
  44. package/src/backends/filesystem.ts +0 -692
  45. package/src/backends/index.ts +0 -22
  46. package/src/backends/local-sandbox.ts +0 -175
  47. package/src/backends/persistent.ts +0 -593
  48. package/src/backends/sandbox.ts +0 -510
  49. package/src/backends/state.ts +0 -244
  50. package/src/backends/utils.ts +0 -287
  51. package/src/checkpointer/file-saver.ts +0 -98
  52. package/src/checkpointer/index.ts +0 -5
  53. package/src/checkpointer/kv-saver.ts +0 -82
  54. package/src/checkpointer/memory-saver.ts +0 -82
  55. package/src/checkpointer/types.ts +0 -125
  56. package/src/cli/components/ApiKeyInput.tsx +0 -300
  57. package/src/cli/components/FilePreview.tsx +0 -237
  58. package/src/cli/components/Input.tsx +0 -277
  59. package/src/cli/components/Message.tsx +0 -93
  60. package/src/cli/components/ModelSelection.tsx +0 -338
  61. package/src/cli/components/SlashMenu.tsx +0 -101
  62. package/src/cli/components/StatusBar.tsx +0 -89
  63. package/src/cli/components/Subagent.tsx +0 -91
  64. package/src/cli/components/TodoList.tsx +0 -133
  65. package/src/cli/components/ToolApproval.tsx +0 -70
  66. package/src/cli/components/ToolCall.tsx +0 -144
  67. package/src/cli/components/ToolCallSummary.tsx +0 -175
  68. package/src/cli/components/Welcome.tsx +0 -75
  69. package/src/cli/components/index.ts +0 -24
  70. package/src/cli/hooks/index.ts +0 -12
  71. package/src/cli/hooks/useAgent.ts +0 -933
  72. package/src/cli/index.tsx +0 -1066
  73. package/src/cli/theme.ts +0 -205
  74. package/src/cli/utils/model-list.ts +0 -365
  75. package/src/constants/errors.ts +0 -29
  76. package/src/constants/limits.ts +0 -195
  77. package/src/index.ts +0 -176
  78. package/src/middleware/agent-memory.ts +0 -330
  79. package/src/prompts.ts +0 -196
  80. package/src/skills/index.ts +0 -2
  81. package/src/skills/load.ts +0 -191
  82. package/src/skills/types.ts +0 -53
  83. package/src/tools/execute.ts +0 -167
  84. package/src/tools/filesystem.ts +0 -418
  85. package/src/tools/index.ts +0 -39
  86. package/src/tools/subagent.ts +0 -443
  87. package/src/tools/todos.ts +0 -101
  88. package/src/tools/web.ts +0 -567
  89. package/src/types/backend.ts +0 -177
  90. package/src/types/core.ts +0 -220
  91. package/src/types/events.ts +0 -430
  92. package/src/types/index.ts +0 -94
  93. package/src/types/structured-output.ts +0 -43
  94. package/src/types/subagent.ts +0 -96
  95. package/src/types.ts +0 -22
  96. package/src/utils/approval.ts +0 -213
  97. package/src/utils/events.ts +0 -416
  98. package/src/utils/eviction.ts +0 -181
  99. package/src/utils/index.ts +0 -34
  100. package/src/utils/model-parser.ts +0 -38
  101. package/src/utils/patch-tool-calls.ts +0 -233
  102. package/src/utils/project-detection.ts +0 -32
  103. package/src/utils/summarization.ts +0 -254
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/hooks/useAgent.ts","../../src/cli/theme.ts","../../src/cli/components/Welcome.tsx","../../src/cli/components/SlashMenu.tsx","../../src/cli/components/Input.tsx","../../src/cli/components/TodoList.tsx","../../src/cli/components/FilePreview.tsx","../../src/cli/components/ToolCall.tsx","../../src/cli/components/Subagent.tsx","../../src/cli/components/StatusBar.tsx","../../src/cli/utils/model-list.ts","../../src/cli/components/ModelSelection.tsx","../../src/cli/components/ApiKeyInput.tsx","../../src/cli/components/ToolApproval.tsx","../../src/cli/index.tsx"],"sourcesContent":["/**\n * Hook for managing agent streaming and events.\n */\nimport { useState, useCallback, useRef } from \"react\";\nimport type {\n DeepAgentState,\n DeepAgentEvent,\n TodoItem,\n ModelMessage,\n SummarizationConfig,\n InterruptOnConfig,\n} from \"../../types\";\nimport type { BaseCheckpointSaver } from \"../../checkpointer/types\";\nimport { createDeepAgent } from \"../../agent\";\nimport { parseModelString } from \"../../utils/model-parser\";\nimport type { SandboxBackendProtocol } from \"../../types\";\nimport type { ToolCallData } from \"../components/Message\";\nimport { useEffect } from \"react\";\n\nexport type AgentStatus =\n | \"idle\"\n | \"thinking\"\n | \"streaming\"\n | \"tool-call\"\n | \"subagent\"\n | \"done\"\n | \"error\";\n\nexport interface AgentEventLog {\n id: string;\n type: DeepAgentEvent[\"type\"] | \"text-segment\";\n event: DeepAgentEvent | { type: \"text-segment\"; text: string };\n timestamp: Date;\n}\n\nexport interface UseAgentOptions {\n model: string;\n maxSteps: number;\n systemPrompt?: string;\n backend: SandboxBackendProtocol;\n /** Enable Anthropic prompt caching */\n enablePromptCaching?: boolean;\n /** Token limit before evicting large tool results */\n toolResultEvictionLimit?: number;\n /** Summarization configuration */\n summarization?: SummarizationConfig;\n /** \n * Default interruptOn config for CLI.\n * Default: { execute: true, write_file: true, edit_file: true }\n */\n interruptOn?: InterruptOnConfig;\n /** Session ID for checkpoint persistence */\n sessionId?: string;\n /** Checkpoint saver for session persistence */\n checkpointer?: BaseCheckpointSaver;\n}\n\nexport interface UseAgentReturn {\n /** Current agent status */\n status: AgentStatus;\n /** Current streaming text */\n streamingText: string;\n /** Final text from the last completed generation */\n lastCompletedText: string;\n /** Event log for rendering */\n events: AgentEventLog[];\n /** Current state (todos, files) */\n state: DeepAgentState;\n /** Conversation history */\n messages: ModelMessage[];\n /** Tool calls from the current/last generation */\n toolCalls: ToolCallData[];\n /** Current error if any */\n error: Error | null;\n /** Send a prompt to the agent, returns the final text and tool calls */\n sendPrompt: (prompt: string) => Promise<{ text: string; toolCalls: ToolCallData[] }>;\n /** Abort current generation */\n abort: () => void;\n /** Clear events, messages, and reset */\n clear: () => void;\n /** Clear only the streaming text (after saving to messages) */\n clearStreamingText: () => void;\n /** Clear only the events (after saving to messages) */\n clearEvents: () => void;\n /** Update model */\n setModel: (model: string) => void;\n /** Current model */\n currentModel: string;\n /** Feature flags */\n features: {\n promptCaching: boolean;\n eviction: boolean;\n summarization: boolean;\n };\n /** Toggle prompt caching */\n setPromptCaching: (enabled: boolean) => void;\n /** Toggle eviction */\n setEviction: (enabled: boolean) => void;\n /** Toggle summarization */\n setSummarization: (enabled: boolean) => void;\n /** Current approval request if any */\n pendingApproval: {\n approvalId: string;\n toolName: string;\n args: unknown;\n } | null;\n /** Respond to approval request */\n respondToApproval: (approved: boolean) => void;\n /** Whether auto-approve mode is enabled */\n autoApproveEnabled: boolean;\n /** Toggle auto-approve mode */\n setAutoApprove: (enabled: boolean) => void;\n}\n\nlet eventCounter = 0;\n\nfunction createEventId(): string {\n return `event-${++eventCounter}`;\n}\n\n// Default interruptOn config for CLI - safe defaults\n// Based on LangChain DeepAgents approval pattern\nconst DEFAULT_CLI_INTERRUPT_ON: InterruptOnConfig = {\n execute: true,\n write_file: true,\n edit_file: true,\n web_search: true,\n fetch_url: true,\n // Note: http_request does NOT require approval per LangChain pattern\n};\n\nexport function useAgent(options: UseAgentOptions): UseAgentReturn {\n const [status, setStatus] = useState<AgentStatus>(\"idle\");\n const [streamingText, setStreamingText] = useState(\"\");\n const [lastCompletedText, setLastCompletedText] = useState(\"\");\n const [events, setEvents] = useState<AgentEventLog[]>([]);\n const [state, setState] = useState<DeepAgentState>({\n todos: [],\n files: {},\n });\n const [messages, setMessages] = useState<ModelMessage[]>([]);\n const [toolCalls, setToolCalls] = useState<ToolCallData[]>([]);\n const [error, setError] = useState<Error | null>(null);\n const [currentModel, setCurrentModel] = useState(options.model);\n \n // Load session on mount if sessionId and checkpointer are provided\n useEffect(() => {\n const loadSession = async () => {\n if (!options.sessionId || !options.checkpointer) return;\n \n const checkpoint = await options.checkpointer.load(options.sessionId);\n if (checkpoint) {\n setState(checkpoint.state);\n setMessages(checkpoint.messages);\n messagesRef.current = checkpoint.messages;\n // Show restore message via addEvent\n addEvent({\n type: \"checkpoint-loaded\",\n threadId: options.sessionId,\n step: checkpoint.step,\n messagesCount: checkpoint.messages.length,\n });\n }\n };\n \n loadSession().catch(console.error);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options.sessionId]);\n \n // Feature flag states (can be toggled at runtime)\n const [promptCachingEnabled, setPromptCachingEnabled] = useState(options.enablePromptCaching ?? false);\n const [evictionLimit, setEvictionLimit] = useState(options.toolResultEvictionLimit ?? 0);\n const [summarizationEnabled, setSummarizationEnabled] = useState(options.summarization?.enabled ?? false);\n const [summarizationConfig, setSummarizationConfig] = useState(options.summarization);\n \n // Auto-approve mode state\n const [autoApproveEnabled, setAutoApproveEnabled] = useState(false);\n \n // Pending approval state\n const [pendingApproval, setPendingApproval] = useState<{\n approvalId: string;\n toolName: string;\n args: unknown;\n } | null>(null);\n const approvalResolverRef = useRef<((approved: boolean) => void) | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n // Use a ref to track accumulated text during streaming (current segment, gets flushed)\n const accumulatedTextRef = useRef(\"\");\n // Use a ref to track total text for return value (never reset mid-generation)\n const totalTextRef = useRef(\"\");\n // Use a ref to track messages during streaming (to pass to agent)\n const messagesRef = useRef<ModelMessage[]>([]);\n // Use a ref to track tool calls during streaming\n const toolCallsRef = useRef<ToolCallData[]>([]);\n // Map to track pending tool calls by ID\n const pendingToolCallsRef = useRef<Map<string, ToolCallData>>(new Map());\n \n // Track feature flags (derived from state)\n const features = {\n promptCaching: promptCachingEnabled,\n eviction: evictionLimit > 0,\n summarization: summarizationEnabled,\n };\n \n const agentRef = useRef(\n createDeepAgent({\n model: parseModelString(currentModel),\n maxSteps: options.maxSteps,\n systemPrompt: options.systemPrompt,\n backend: options.backend,\n enablePromptCaching: promptCachingEnabled,\n toolResultEvictionLimit: evictionLimit,\n summarization: summarizationConfig,\n interruptOn: autoApproveEnabled ? undefined : (options.interruptOn ?? DEFAULT_CLI_INTERRUPT_ON),\n checkpointer: options.checkpointer,\n })\n );\n\n const addEvent = useCallback((event: DeepAgentEvent | { type: \"text-segment\"; text: string }) => {\n setEvents((prev) => [\n ...prev,\n {\n id: createEventId(),\n type: event.type,\n event,\n timestamp: new Date(),\n },\n ]);\n }, []);\n\n // Flush accumulated text as a text-segment event\n const flushTextSegment = useCallback(() => {\n if (accumulatedTextRef.current.trim()) {\n addEvent({\n type: \"text-segment\",\n text: accumulatedTextRef.current,\n });\n accumulatedTextRef.current = \"\";\n setStreamingText(\"\");\n }\n }, [addEvent]);\n\n // ============================================================================\n // Event Handler Context\n // ============================================================================\n\n /**\n * Context object shared by all event handlers.\n * Contains all refs and setters needed for event processing.\n */\n interface EventHandlerContext {\n setStatus: (status: AgentStatus) => void;\n setState: React.Dispatch<React.SetStateAction<DeepAgentState>>;\n setMessages: React.Dispatch<React.SetStateAction<ModelMessage[]>>;\n setToolCalls: React.Dispatch<React.SetStateAction<ToolCallData[]>>;\n setError: React.Dispatch<React.SetStateAction<Error | null>>;\n addEvent: (event: DeepAgentEvent | { type: \"text-segment\"; text: string }) => void;\n flushTextSegment: () => void;\n accumulatedTextRef: React.MutableRefObject<string>;\n totalTextRef: React.MutableRefObject<string>;\n toolCallsRef: React.MutableRefObject<ToolCallData[]>;\n pendingToolCallsRef: React.MutableRefObject<Map<string, ToolCallData>>;\n messagesRef: React.MutableRefObject<ModelMessage[]>;\n }\n\n // ============================================================================\n // Helper Functions for Common Patterns\n // ============================================================================\n\n /**\n * Common pattern: flush text, set status to \"tool-call\", add event\n */\n const handleToolEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n ctx.flushTextSegment();\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n // ============================================================================\n // Event Handlers\n // ============================================================================\n\n /**\n * Handle text streaming events.\n * Accumulates text and updates streaming display.\n */\n const handleTextEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"text\") return;\n ctx.setStatus(\"streaming\");\n ctx.accumulatedTextRef.current += event.text;\n ctx.totalTextRef.current += event.text;\n setStreamingText(ctx.accumulatedTextRef.current);\n };\n\n /**\n * Handle step-start events.\n * Marks beginning of a new reasoning step.\n */\n const handleStepStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"step-start\") return;\n // Don't flush here - steps are just markers, text comes after tool results\n if (event.stepNumber > 1) {\n ctx.addEvent(event);\n }\n };\n\n /**\n * Handle tool-call events.\n * Tracks pending tool calls until results arrive.\n */\n const handleToolCallEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"tool-call\") return;\n ctx.flushTextSegment();\n ctx.setStatus(\"tool-call\");\n const pendingToolCall: ToolCallData = {\n toolName: event.toolName,\n args: event.args,\n status: \"success\", // Will be updated on result\n };\n ctx.pendingToolCallsRef.current.set(event.toolCallId, pendingToolCall);\n ctx.addEvent(event);\n };\n\n /**\n * Handle tool-result events.\n * Updates pending tool call with result and moves to completed list.\n */\n const handleToolResultEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"tool-result\") return;\n const completedToolCall = ctx.pendingToolCallsRef.current.get(\n event.toolCallId\n );\n if (completedToolCall) {\n completedToolCall.result = event.result;\n // Move from pending to completed\n ctx.toolCallsRef.current.push(completedToolCall);\n ctx.setToolCalls([...ctx.toolCallsRef.current]);\n ctx.pendingToolCallsRef.current.delete(event.toolCallId);\n }\n ctx.addEvent(event);\n };\n\n /**\n * Handle todos-changed events.\n * Updates the todos list in state.\n */\n const handleTodosChangedEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"todos-changed\") return;\n ctx.flushTextSegment();\n ctx.setStatus(\"tool-call\");\n ctx.setState((prev) => ({ ...prev, todos: event.todos }));\n ctx.addEvent(event);\n };\n\n /**\n * Handle file-write-start events.\n */\n const handleFileWriteStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"file-write-start\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle file-written events.\n */\n const handleFileWrittenEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"file-written\") return;\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle file-edited events.\n */\n const handleFileEditedEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"file-edited\") return;\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle file-read events.\n */\n const handleFileReadEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"file-read\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle ls events.\n */\n const handleLsEvent = (event: DeepAgentEvent, ctx: EventHandlerContext) => {\n if (event.type !== \"ls\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle glob events.\n */\n const handleGlobEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"glob\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle grep events.\n */\n const handleGrepEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"grep\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle web-search-start events.\n */\n const handleWebSearchStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"web-search-start\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle web-search-finish events.\n */\n const handleWebSearchFinishEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"web-search-finish\") return;\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle http-request-start events.\n */\n const handleHttpRequestStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"http-request-start\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle http-request-finish events.\n */\n const handleHttpRequestFinishEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"http-request-finish\") return;\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle fetch-url-start events.\n */\n const handleFetchUrlStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"fetch-url-start\") return;\n handleToolEvent(event, ctx);\n };\n\n /**\n * Handle fetch-url-finish events.\n */\n const handleFetchUrlFinishEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"fetch-url-finish\") return;\n ctx.setStatus(\"tool-call\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle subagent-start events.\n */\n const handleSubagentStartEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"subagent-start\") return;\n ctx.setStatus(\"subagent\");\n ctx.addEvent(event);\n };\n\n /**\n * Handle subagent-finish events.\n */\n const handleSubagentFinishEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"subagent-finish\") return;\n ctx.addEvent(event);\n };\n\n /**\n * Handle approval-requested events.\n * Already handled in onApprovalRequest callback, so no-op here.\n */\n const handleApprovalRequestedEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n // Approval request is handled in onApprovalRequest callback\n // Event is already emitted there, no need to duplicate\n };\n\n /**\n * Handle approval-response events.\n * Already handled in respondToApproval callback, so no-op here.\n */\n const handleApprovalResponseEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n // Approval response is handled in respondToApproval callback\n // Event is already emitted there, no need to duplicate\n };\n\n /**\n * Handle done events.\n * Flushes remaining text and updates final state.\n */\n const handleDoneEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"done\") return;\n // Flush any remaining text as a final text-segment\n ctx.flushTextSegment();\n ctx.setStatus(\"done\");\n ctx.setState(event.state);\n // Update messages with the new conversation history\n if (event.messages) {\n ctx.setMessages(event.messages);\n ctx.messagesRef.current = event.messages;\n }\n ctx.addEvent(event);\n };\n\n /**\n * Handle error events.\n * Flushes remaining text and marks pending tool calls as failed.\n */\n const handleErrorEvent = (\n event: DeepAgentEvent,\n ctx: EventHandlerContext\n ) => {\n if (event.type !== \"error\") return;\n // Flush any remaining text before showing error\n ctx.flushTextSegment();\n ctx.setStatus(\"error\");\n ctx.setError(event.error);\n // Mark any pending tool calls as failed\n for (const [id, tc] of ctx.pendingToolCallsRef.current) {\n tc.status = \"error\";\n ctx.toolCallsRef.current.push(tc);\n }\n ctx.pendingToolCallsRef.current.clear();\n ctx.setToolCalls([...ctx.toolCallsRef.current]);\n ctx.addEvent(event);\n };\n\n /**\n * Type-safe event handler function.\n */\n type EventHandler = (event: DeepAgentEvent, ctx: EventHandlerContext) => void;\n\n /**\n * Event handler map.\n * Maps event types to their handler functions.\n */\n const EVENT_HANDLERS: Record<string, EventHandler> = {\n \"text\": handleTextEvent,\n \"step-start\": handleStepStartEvent,\n \"tool-call\": handleToolCallEvent,\n \"tool-result\": handleToolResultEvent,\n \"todos-changed\": handleTodosChangedEvent,\n \"file-write-start\": handleFileWriteStartEvent,\n \"file-written\": handleFileWrittenEvent,\n \"file-edited\": handleFileEditedEvent,\n \"file-read\": handleFileReadEvent,\n \"ls\": handleLsEvent,\n \"glob\": handleGlobEvent,\n \"grep\": handleGrepEvent,\n \"web-search-start\": handleWebSearchStartEvent,\n \"web-search-finish\": handleWebSearchFinishEvent,\n \"http-request-start\": handleHttpRequestStartEvent,\n \"http-request-finish\": handleHttpRequestFinishEvent,\n \"fetch-url-start\": handleFetchUrlStartEvent,\n \"fetch-url-finish\": handleFetchUrlFinishEvent,\n \"subagent-start\": handleSubagentStartEvent,\n \"subagent-finish\": handleSubagentFinishEvent,\n \"approval-requested\": handleApprovalRequestedEvent,\n \"approval-response\": handleApprovalResponseEvent,\n \"done\": handleDoneEvent,\n \"error\": handleErrorEvent,\n };\n\n // ============================================================================\n // Main sendPrompt Function\n // ============================================================================\n\n const sendPrompt = useCallback(\n async (prompt: string): Promise<{ text: string; toolCalls: ToolCallData[] }> => {\n // Reset for new generation - but keep events for history\n setStatus(\"thinking\");\n setStreamingText(\"\");\n // Don't clear events - they serve as conversation history\n setToolCalls([]);\n setError(null);\n accumulatedTextRef.current = \"\";\n totalTextRef.current = \"\";\n toolCallsRef.current = [];\n pendingToolCallsRef.current.clear();\n\n // Add user message to events for history\n addEvent({ type: \"user-message\", content: prompt });\n\n // Sync messages ref with current state\n messagesRef.current = messages;\n\n // Create new abort controller\n abortControllerRef.current = new AbortController();\n\n // Build the input messages array for streamWithEvents\n // Append the new prompt to the conversation history (if any exists)\n const inputMessages = messagesRef.current.length > 0\n ? [\n ...messagesRef.current,\n { role: \"user\", content: prompt } as ModelMessage,\n ]\n : [{ role: \"user\", content: prompt } as ModelMessage]; // First message: just the prompt\n\n try {\n for await (const event of agentRef.current.streamWithEvents({\n messages: inputMessages, // Always use messages parameter (built with or without history)\n state,\n threadId: options.sessionId,\n abortSignal: abortControllerRef.current.signal,\n // Approval callback - auto-approve or prompt user\n onApprovalRequest: async (request) => {\n // If auto-approve is enabled, immediately approve\n if (autoApproveEnabled) {\n addEvent({ \n type: \"approval-requested\", \n ...request,\n });\n addEvent({ \n type: \"approval-response\", \n approvalId: request.approvalId, \n approved: true \n });\n return true;\n }\n \n // Otherwise, show approval UI and wait for user response\n setPendingApproval({\n approvalId: request.approvalId,\n toolName: request.toolName,\n args: request.args,\n });\n addEvent({ type: \"approval-requested\", ...request });\n \n // Return a promise that resolves when user responds\n return new Promise<boolean>((resolve) => {\n approvalResolverRef.current = resolve;\n });\n },\n })) {\n // Create event handler context\n const eventHandlerContext: EventHandlerContext = {\n setStatus,\n setState,\n setMessages,\n setToolCalls,\n setError,\n addEvent,\n flushTextSegment,\n accumulatedTextRef,\n totalTextRef,\n toolCallsRef,\n pendingToolCallsRef,\n messagesRef,\n };\n\n // Get the handler for this event type\n const handler = EVENT_HANDLERS[event.type];\n if (handler) {\n handler(event, eventHandlerContext);\n }\n }\n\n // Save the final text and tool calls before resetting\n const finalText = totalTextRef.current;\n const finalToolCalls = [...toolCallsRef.current];\n setLastCompletedText(finalText);\n setStatus(\"idle\");\n return { text: finalText, toolCalls: finalToolCalls };\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n // Flush remaining text before aborting\n flushTextSegment();\n setStatus(\"idle\");\n return { text: totalTextRef.current, toolCalls: toolCallsRef.current };\n } else {\n // Flush remaining text before showing error\n flushTextSegment();\n setStatus(\"error\");\n setError(err as Error);\n return { text: \"\", toolCalls: [] };\n }\n } finally {\n abortControllerRef.current = null;\n }\n },\n [state, messages, addEvent, flushTextSegment, autoApproveEnabled]\n );\n\n\n const abort = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n setStatus(\"idle\");\n }\n }, []);\n\n const clear = useCallback(() => {\n setEvents([]);\n setStreamingText(\"\");\n setLastCompletedText(\"\");\n setMessages([]);\n setToolCalls([]);\n messagesRef.current = [];\n toolCallsRef.current = [];\n pendingToolCallsRef.current.clear();\n setError(null);\n setStatus(\"idle\");\n }, []);\n\n const clearStreamingText = useCallback(() => {\n setStreamingText(\"\");\n setEvents([]);\n }, []);\n\n const clearEvents = useCallback(() => {\n setEvents([]);\n }, []);\n\n // Helper to recreate the agent with current settings\n const recreateAgent = useCallback(\n (overrides: {\n model?: string;\n promptCaching?: boolean;\n evictionLimit?: number;\n summarization?: SummarizationConfig;\n interruptOn?: InterruptOnConfig | null; // null means explicitly no interruptOn (auto-approve)\n } = {}) => {\n const newModel = overrides.model ?? currentModel;\n const newPromptCaching = overrides.promptCaching ?? promptCachingEnabled;\n const newEvictionLimit = overrides.evictionLimit ?? evictionLimit;\n const newSummarization = overrides.summarization ?? summarizationConfig;\n \n // Handle interruptOn: null = explicit no approval, undefined = use current state\n let newInterruptOn: InterruptOnConfig | undefined;\n if (overrides.interruptOn === null) {\n // Explicitly disable approval (auto-approve mode)\n newInterruptOn = undefined;\n } else if (overrides.interruptOn !== undefined) {\n // Use the provided config\n newInterruptOn = overrides.interruptOn;\n } else {\n // Use current state to determine\n newInterruptOn = autoApproveEnabled ? undefined : (options.interruptOn ?? DEFAULT_CLI_INTERRUPT_ON);\n }\n\n agentRef.current = createDeepAgent({\n model: parseModelString(newModel),\n maxSteps: options.maxSteps,\n systemPrompt: options.systemPrompt,\n backend: options.backend,\n enablePromptCaching: newPromptCaching,\n toolResultEvictionLimit: newEvictionLimit,\n summarization: newSummarization,\n interruptOn: newInterruptOn,\n });\n },\n [currentModel, promptCachingEnabled, evictionLimit, summarizationConfig, autoApproveEnabled, options.maxSteps, options.systemPrompt, options.backend, options.interruptOn]\n );\n\n const setModel = useCallback(\n (model: string) => {\n setCurrentModel(model);\n recreateAgent({ model });\n },\n [recreateAgent]\n );\n\n const setPromptCaching = useCallback(\n (enabled: boolean) => {\n setPromptCachingEnabled(enabled);\n recreateAgent({ promptCaching: enabled });\n },\n [recreateAgent]\n );\n\n const setEviction = useCallback(\n (enabled: boolean) => {\n const newLimit = enabled ? (options.toolResultEvictionLimit || 20000) : 0;\n setEvictionLimit(newLimit);\n recreateAgent({ evictionLimit: newLimit });\n },\n [recreateAgent, options.toolResultEvictionLimit]\n );\n\n const setSummarization = useCallback(\n (enabled: boolean) => {\n setSummarizationEnabled(enabled);\n const newConfig = enabled \n ? { enabled: true, tokenThreshold: options.summarization?.tokenThreshold, keepMessages: options.summarization?.keepMessages }\n : undefined;\n setSummarizationConfig(newConfig);\n recreateAgent({ summarization: newConfig });\n },\n [recreateAgent, options.summarization]\n );\n\n // Respond to approval request\n const respondToApproval = useCallback((approved: boolean) => {\n if (approvalResolverRef.current) {\n approvalResolverRef.current(approved);\n approvalResolverRef.current = null;\n const currentApproval = pendingApproval;\n setPendingApproval(null);\n if (currentApproval) {\n addEvent({ \n type: \"approval-response\", \n approvalId: currentApproval.approvalId, \n approved \n });\n }\n }\n }, [addEvent]);\n\n // Toggle auto-approve and recreate agent\n const setAutoApprove = useCallback((enabled: boolean) => {\n setAutoApproveEnabled(enabled);\n \n // When enabling auto-approve, immediately approve any pending request\n if (enabled && approvalResolverRef.current) {\n respondToApproval(true);\n }\n \n // Recreate agent with/without interruptOn config\n // Use null to explicitly disable approval, or the config to enable it\n recreateAgent({ \n interruptOn: enabled ? null : (options.interruptOn ?? DEFAULT_CLI_INTERRUPT_ON)\n });\n }, [recreateAgent, options.interruptOn, respondToApproval]);\n\n return {\n status,\n streamingText,\n lastCompletedText,\n events,\n state,\n messages,\n toolCalls,\n error,\n sendPrompt,\n abort,\n clear,\n clearStreamingText,\n clearEvents,\n setModel,\n currentModel,\n features,\n setPromptCaching,\n setEviction,\n setSummarization,\n pendingApproval,\n respondToApproval,\n autoApproveEnabled,\n setAutoApprove,\n };\n}\n\n","/**\n * Theme constants for the Ink CLI.\n * Colors, emoji, and styling values.\n */\n\n/**\n * Color palette for the CLI.\n * Uses chalk-compatible color names.\n */\nexport const colors = {\n // Primary colors\n primary: \"cyan\",\n secondary: \"magenta\",\n accent: \"yellow\",\n\n // Status colors\n success: \"green\",\n error: \"red\",\n warning: \"yellow\",\n info: \"blue\",\n\n // Text colors\n muted: \"gray\",\n highlight: \"white\",\n\n // Semantic colors\n tool: \"magenta\",\n file: \"blue\",\n user: \"cyan\",\n agent: \"green\",\n} as const;\n\n/**\n * Status emoji for todo items and events.\n */\nexport const emoji = {\n // Todo statuses\n pending: \"⏳\",\n in_progress: \"🔄\",\n completed: \"✅\",\n cancelled: \"❌\",\n\n // UI elements\n robot: \"🤖\",\n thinking: \"💭\",\n tool: \"🔧\",\n file: \"📁\",\n edit: \"✏️\",\n todo: \"📋\",\n done: \"🎉\",\n error: \"💥\",\n warning: \"⚠️\",\n info: \"ℹ️\",\n user: \"👤\",\n subagent: \"🤝\",\n key: \"🔑\",\n model: \"🧠\",\n} as const;\n\n/**\n * Box border styles for different UI elements.\n */\nexport const borders = {\n panel: \"round\",\n preview: \"single\",\n alert: \"double\",\n} as const;\n\n/**\n * Slash commands configuration.\n */\nexport interface SlashCommand {\n command: string;\n aliases: string[];\n description: string;\n}\n\nexport const SLASH_COMMANDS: SlashCommand[] = [\n {\n command: \"/todos\",\n aliases: [\"/t\", \"/todo\"],\n description: \"Show current todo list\",\n },\n {\n command: \"/files\",\n aliases: [\"/f\", \"/file\"],\n description: \"Show files in working directory\",\n },\n {\n command: \"/read\",\n aliases: [\"/r\"],\n description: \"Read a file (usage: /read <path>)\",\n },\n {\n command: \"/apikey\",\n aliases: [\"/key\", \"/api\"],\n description: \"Manage API keys (interactive)\",\n },\n {\n command: \"/model\",\n aliases: [],\n description: \"Show available models or change model (usage: /model [model-name])\",\n },\n {\n command: \"/features\",\n aliases: [\"/feat\"],\n description: \"Show enabled features (caching, eviction, summarization)\",\n },\n {\n command: \"/tokens\",\n aliases: [\"/tok\"],\n description: \"Show estimated token count for conversation\",\n },\n {\n command: \"/cache\",\n aliases: [],\n description: \"Toggle prompt caching (usage: /cache on|off)\",\n },\n {\n command: \"/eviction\",\n aliases: [\"/evict\"],\n description: \"Toggle tool result eviction (usage: /eviction on|off)\",\n },\n {\n command: \"/summarize\",\n aliases: [\"/sum\"],\n description: \"Toggle auto-summarization (usage: /summarize on|off)\",\n },\n {\n command: \"/approve\",\n aliases: [],\n description: \"Toggle auto-approve mode for tool executions\",\n },\n {\n command: \"/clear\",\n aliases: [\"/c\"],\n description: \"Clear chat history\",\n },\n {\n command: \"/sessions\",\n aliases: [\"/session-list\"],\n description: \"List saved sessions\",\n },\n {\n command: \"/session\",\n aliases: [],\n description: \"Session management (usage: /session clear)\",\n },\n {\n command: \"/help\",\n aliases: [\"/h\", \"/?\"],\n description: \"Show help\",\n },\n {\n command: \"/quit\",\n aliases: [\"/q\", \"/exit\"],\n description: \"Exit the CLI\",\n },\n];\n\n/**\n * Filter commands by prefix.\n */\nexport function filterCommands(prefix?: string): SlashCommand[] {\n if (!prefix) {\n return SLASH_COMMANDS;\n }\n\n const normalizedPrefix = prefix.startsWith(\"/\") ? prefix : `/${prefix}`;\n\n return SLASH_COMMANDS.filter((cmd) => {\n if (cmd.command.toLowerCase().startsWith(normalizedPrefix.toLowerCase())) {\n return true;\n }\n return cmd.aliases.some((alias) =>\n alias.toLowerCase().startsWith(normalizedPrefix.toLowerCase())\n );\n });\n}\n\n/**\n * Parse a slash command from input.\n */\nexport function parseCommand(input: string): {\n isCommand: boolean;\n command?: string;\n args?: string;\n} {\n const trimmed = input.trim();\n\n if (!trimmed.startsWith(\"/\")) {\n return { isCommand: false };\n }\n\n const parts = trimmed.slice(1).split(/\\s+/);\n const command = parts[0]?.toLowerCase();\n const args = parts.slice(1).join(\" \");\n\n return {\n isCommand: true,\n command,\n args: args || undefined,\n };\n}\n\n","/**\n * Welcome banner component for the CLI.\n * Clean, minimal design inspired by Claude Code and OpenAI Codex.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { colors } from \"../theme\";\n\ninterface WelcomeProps {\n /** Model name to display */\n model?: string;\n /** Working directory */\n workDir?: string;\n}\n\nexport function Welcome({ model, workDir }: WelcomeProps): React.ReactElement {\n const displayDir = workDir \n ? workDir.replace(process.env.HOME || \"\", \"~\")\n : process.cwd().replace(process.env.HOME || \"\", \"~\");\n \n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box>\n <Text bold color={colors.primary}>{\">\"}_</Text>\n <Text bold> Deep Agent</Text>\n </Box>\n <Box height={1} />\n <Box>\n <Text dimColor>model:</Text>\n <Text> {model || \"anthropic/claude-haiku-4-5-20251001\"}</Text>\n <Text dimColor> /model to change</Text>\n </Box>\n <Box>\n <Text dimColor>directory:</Text>\n <Text> {displayDir}</Text>\n </Box>\n </Box>\n );\n}\n\n/**\n * Compact help text shown below the welcome banner.\n */\nexport function WelcomeHint(): React.ReactElement {\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text dimColor>\n To get started, describe a task or try one of these commands:\n </Text>\n <Box height={1} />\n <Box flexDirection=\"column\">\n <Text>\n <Text color={colors.info}>/help</Text>\n <Text dimColor> - show available commands</Text>\n </Text>\n <Text>\n <Text color={colors.info}>/features</Text>\n <Text dimColor> - show enabled features</Text>\n </Text>\n <Text>\n <Text color={colors.info}>/model</Text>\n <Text dimColor> - change the model</Text>\n </Text>\n </Box>\n </Box>\n );\n}\n\n","/**\n * Slash command autocomplete menu component.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { colors, filterCommands, type SlashCommand } from \"../theme\";\n\ninterface SlashMenuProps {\n /** Current input value to filter commands */\n filter: string;\n /** Maximum number of items to show */\n maxItems?: number;\n}\n\nexport function SlashMenu({\n filter,\n maxItems = 8,\n}: SlashMenuProps): React.ReactElement | null {\n // Only show menu when input starts with /\n if (!filter.startsWith(\"/\")) {\n return null;\n }\n\n const filtered = filterCommands(filter);\n\n if (filtered.length === 0) {\n return (\n <Box paddingLeft={2} marginTop={1}>\n <Text dimColor>No matching commands</Text>\n </Box>\n );\n }\n\n const displayItems = filtered.slice(0, maxItems);\n const hasMore = filtered.length > maxItems;\n\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n {displayItems.map((cmd) => (\n <SlashMenuItem key={cmd.command} command={cmd} />\n ))}\n {hasMore && (\n <Text dimColor>... and {filtered.length - maxItems} more</Text>\n )}\n </Box>\n );\n}\n\ninterface SlashMenuItemProps {\n command: SlashCommand;\n}\n\nfunction SlashMenuItem({ command }: SlashMenuItemProps): React.ReactElement {\n const aliases =\n command.aliases.length > 0 ? ` (${command.aliases.join(\", \")})` : \"\";\n\n return (\n <Box>\n <Text color={colors.info}>{command.command}</Text>\n <Text dimColor>{aliases}</Text>\n <Text dimColor> - {command.description}</Text>\n </Box>\n );\n}\n\n/**\n * Full slash menu panel for /help command.\n */\nexport function SlashMenuPanel(): React.ReactElement {\n const commands = filterCommands();\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n Available Commands\n </Text>\n <Box height={1} />\n {commands.map((cmd) => (\n <Box key={cmd.command} flexDirection=\"column\" marginBottom={1}>\n <Box>\n <Text color={colors.info}>{cmd.command}</Text>\n {cmd.aliases.length > 0 && (\n <Text dimColor> ({cmd.aliases.join(\", \")})</Text>\n )}\n </Box>\n <Box paddingLeft={2}>\n <Text dimColor>{cmd.description}</Text>\n </Box>\n </Box>\n ))}\n </Box>\n );\n}\n\n","/**\n * Text input component with slash command suggestions.\n * Clean, minimal design inspired by Claude Code and OpenAI Codex.\n */\nimport React, { useState, useRef } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { colors } from \"../theme\";\nimport { SlashMenu } from \"./SlashMenu\";\n\ninterface InputProps {\n /** Called when user submits input */\n onSubmit: (value: string) => void;\n /** Whether input is disabled (e.g., during generation) */\n disabled?: boolean;\n /** Placeholder text */\n placeholder?: string;\n}\n\n// Module-level history storage to persist across re-renders\nconst inputHistory: string[] = [];\nconst MAX_HISTORY = 100;\n\nexport function Input({\n onSubmit,\n disabled = false,\n placeholder = \"Plan, search, build anything\",\n}: InputProps): React.ReactElement {\n const [value, setValue] = useState(\"\");\n const [cursorPos, setCursorPos] = useState(0);\n const showMenu = value.startsWith(\"/\") && !disabled;\n \n // History navigation state\n // -1 means we're at the current input (not browsing history)\n const [historyIndex, setHistoryIndex] = useState(-1);\n // Store the current input when user starts navigating history\n const savedInputRef = useRef(\"\");\n\n // Helper function to delete the previous word from cursor position\n const deleteWord = () => {\n if (cursorPos === 0) return;\n \n let end = cursorPos;\n // Skip trailing spaces\n while (end > 0 && value[end - 1] === \" \") {\n end--;\n }\n // Find start of current word\n while (end > 0 && value[end - 1] !== \" \") {\n end--;\n }\n \n const newValue = value.slice(0, end) + value.slice(cursorPos);\n setValue(newValue);\n setCursorPos(end);\n };\n\n useInput(\n (input, key) => {\n if (disabled) return;\n\n // Handle Enter - submit\n if (key.return) {\n if (value.trim()) {\n // Add to history (avoid duplicates of the last entry)\n if (inputHistory.length === 0 || inputHistory[0] !== value) {\n inputHistory.unshift(value);\n if (inputHistory.length > MAX_HISTORY) {\n inputHistory.pop();\n }\n }\n onSubmit(value);\n setValue(\"\");\n setCursorPos(0);\n setHistoryIndex(-1);\n savedInputRef.current = \"\";\n }\n return;\n }\n\n // Handle up arrow - navigate to older history\n if (key.upArrow) {\n if (inputHistory.length === 0) return;\n \n if (historyIndex === -1) {\n // Save current input before navigating history\n savedInputRef.current = value;\n }\n \n const newIndex = Math.min(historyIndex + 1, inputHistory.length - 1);\n if (newIndex !== historyIndex) {\n const historyValue = inputHistory[newIndex];\n if (historyValue !== undefined) {\n setHistoryIndex(newIndex);\n setValue(historyValue);\n setCursorPos(historyValue.length);\n }\n }\n return;\n }\n\n // Handle down arrow - navigate to newer history\n if (key.downArrow) {\n if (historyIndex === -1) return;\n \n const newIndex = historyIndex - 1;\n if (newIndex === -1) {\n // Return to saved current input\n setHistoryIndex(-1);\n setValue(savedInputRef.current);\n setCursorPos(savedInputRef.current.length);\n } else {\n const historyValue = inputHistory[newIndex];\n if (historyValue !== undefined) {\n setHistoryIndex(newIndex);\n setValue(historyValue);\n setCursorPos(historyValue.length);\n }\n }\n return;\n }\n\n // Handle left arrow - move cursor left\n if (key.leftArrow) {\n if (key.meta || key.ctrl) {\n // Option/Ctrl+Left: jump to start of previous word\n let pos = cursorPos;\n // Skip spaces\n while (pos > 0 && value[pos - 1] === \" \") {\n pos--;\n }\n // Skip word characters\n while (pos > 0 && value[pos - 1] !== \" \") {\n pos--;\n }\n setCursorPos(pos);\n } else {\n setCursorPos((prev) => Math.max(0, prev - 1));\n }\n return;\n }\n\n // Handle right arrow - move cursor right\n if (key.rightArrow) {\n if (key.meta || key.ctrl) {\n // Option/Ctrl+Right: jump to end of next word\n let pos = cursorPos;\n // Skip current word characters\n while (pos < value.length && value[pos] !== \" \") {\n pos++;\n }\n // Skip spaces\n while (pos < value.length && value[pos] === \" \") {\n pos++;\n }\n setCursorPos(pos);\n } else {\n setCursorPos((prev) => Math.min(value.length, prev + 1));\n }\n return;\n }\n\n // Handle Ctrl+A - move to start of line\n if (key.ctrl && input === \"a\") {\n setCursorPos(0);\n return;\n }\n\n // Handle Ctrl+E - move to end of line\n if (key.ctrl && input === \"e\") {\n setCursorPos(value.length);\n return;\n }\n\n // Handle Option+Backspace (Alt+Backspace) - delete previous word\n if ((key.backspace || key.delete) && key.meta) {\n deleteWord();\n return;\n }\n\n // Handle Ctrl+W - delete previous word (Unix-style)\n if (key.ctrl && input === \"w\") {\n deleteWord();\n return;\n }\n\n // Handle Ctrl+U - delete from start to cursor\n if (key.ctrl && input === \"u\") {\n setValue(value.slice(cursorPos));\n setCursorPos(0);\n return;\n }\n\n // Handle Ctrl+K - delete from cursor to end\n if (key.ctrl && input === \"k\") {\n setValue(value.slice(0, cursorPos));\n return;\n }\n\n // Handle Backspace/Delete - single character\n if (key.backspace || key.delete) {\n if (cursorPos > 0) {\n setValue((prev) => prev.slice(0, cursorPos - 1) + prev.slice(cursorPos));\n setCursorPos((prev) => prev - 1);\n }\n return;\n }\n\n // Tab for autocomplete - complete first matching command\n if (key.tab && value.startsWith(\"/\")) {\n return;\n }\n\n // Ignore other control keys\n if (key.ctrl || key.meta || key.escape || key.tab) {\n return;\n }\n\n // Handle pasted text or typed characters\n // Filter to only printable characters\n if (input) {\n const printable = input\n .split(\"\")\n .filter((char) => char >= \" \" || char === \"\\t\")\n .join(\"\");\n \n if (printable) {\n // Reset history navigation when user types\n if (historyIndex !== -1) {\n setHistoryIndex(-1);\n savedInputRef.current = \"\";\n }\n setValue((prev) => prev.slice(0, cursorPos) + printable + prev.slice(cursorPos));\n setCursorPos((prev) => prev + printable.length);\n }\n }\n },\n { isActive: !disabled }\n );\n\n // Render text with cursor at the correct position\n const renderTextWithCursor = () => {\n if (!value) {\n return (\n <Text>\n <Text color={colors.primary}>▌</Text>\n <Text dimColor>{placeholder}</Text>\n </Text>\n );\n }\n\n const beforeCursor = value.slice(0, cursorPos);\n const afterCursor = value.slice(cursorPos);\n\n return (\n <Text>\n {beforeCursor}\n <Text color={colors.primary}>▌</Text>\n {afterCursor}\n </Text>\n );\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color={colors.muted}>{\"→ \"}</Text>\n {disabled ? (\n <Text dimColor>...</Text>\n ) : (\n renderTextWithCursor()\n )}\n </Box>\n {showMenu && <SlashMenu filter={value} />}\n </Box>\n );\n}\n\n","/**\n * Todo list panel component.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Badge } from \"@inkjs/ui\";\nimport { emoji, colors } from \"../theme\";\nimport type { TodoItem } from \"../../types\";\n\ninterface TodoListProps {\n todos: TodoItem[];\n /** Whether to show as a full panel with border */\n showPanel?: boolean;\n}\n\nexport function TodoList({\n todos,\n showPanel = true,\n}: TodoListProps): React.ReactElement {\n const completed = todos.filter((t) => t.status === \"completed\").length;\n const inProgress = todos.filter((t) => t.status === \"in_progress\").length;\n const pending = todos.filter((t) => t.status === \"pending\").length;\n const total = todos.length;\n\n const content = (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold color={colors.info}>\n {emoji.todo} Todo List\n </Text>\n <Text dimColor>\n {\" \"}\n ({completed}/{total} done)\n </Text>\n </Box>\n\n {todos.length === 0 ? (\n <Box paddingLeft={2}>\n <Text dimColor>No todos yet.</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\">\n {todos.map((todo) => (\n <TodoItemRow key={todo.id} todo={todo} />\n ))}\n </Box>\n )}\n\n {todos.length > 0 && (\n <Box marginTop={1} gap={2}>\n {inProgress > 0 && (\n <Text color={colors.warning}>{inProgress} in progress</Text>\n )}\n {pending > 0 && <Text dimColor>{pending} pending</Text>}\n {completed > 0 && (\n <Text color={colors.success}>{completed} completed</Text>\n )}\n </Box>\n )}\n </Box>\n );\n\n if (!showPanel) {\n return content;\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n {content}\n </Box>\n );\n}\n\ninterface TodoItemRowProps {\n todo: TodoItem;\n}\n\nfunction TodoItemRow({ todo }: TodoItemRowProps): React.ReactElement {\n const statusEmoji = emoji[todo.status] || \"•\";\n const isFinished = todo.status === \"completed\" || todo.status === \"cancelled\";\n\n const badgeColor = {\n pending: \"gray\" as const,\n in_progress: \"yellow\" as const,\n completed: \"green\" as const,\n cancelled: \"red\" as const,\n }[todo.status];\n\n return (\n <Box paddingLeft={2}>\n <Text>{statusEmoji} </Text>\n <Badge color={badgeColor}>\n {todo.status.replace(\"_\", \" \")}\n </Badge>\n <Text> </Text>\n {isFinished ? (\n <Text strikethrough dimColor>\n {todo.content}\n </Text>\n ) : (\n <Text>{todo.content}</Text>\n )}\n </Box>\n );\n}\n\n/**\n * Compact todo change notification.\n */\ninterface TodosChangedProps {\n todos: TodoItem[];\n}\n\nexport function TodosChanged({ todos }: TodosChangedProps): React.ReactElement {\n const completed = todos.filter((t) => t.status === \"completed\").length;\n const total = todos.length;\n\n return (\n <Box marginY={1}>\n <Text color={colors.info}>\n {emoji.todo} Todos updated ({completed}/{total} done)\n </Text>\n </Box>\n );\n}\n\n","/**\n * File preview component with line numbers.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { emoji, colors } from \"../theme\";\nimport type { FileInfo } from \"../../types\";\n\ninterface FilePreviewProps {\n /** File path */\n path: string;\n /** File content */\n content: string;\n /** Maximum lines to show */\n maxLines?: number;\n /** Whether this is a write preview (vs read) */\n isWrite?: boolean;\n}\n\nexport function FilePreview({\n path,\n content,\n maxLines = 20,\n isWrite = false,\n}: FilePreviewProps): React.ReactElement {\n const lines = content.split(\"\\n\");\n const totalLines = lines.length;\n const displayLines = lines.slice(0, maxLines);\n const truncated = totalLines > maxLines;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n marginY={1}\n >\n {/* Header */}\n <Box paddingX={2} paddingY={1} borderBottom>\n <Text color={colors.info}>\n {emoji.file} {isWrite ? \"Writing:\" : \"Reading:\"}{\" \"}\n </Text>\n <Text color={colors.file}>{path}</Text>\n <Text dimColor> ({totalLines} lines)</Text>\n </Box>\n\n {/* Content with line numbers */}\n <Box flexDirection=\"column\" paddingX={2} paddingY={1}>\n {displayLines.map((line, index) => (\n <Box key={index}>\n <Text dimColor>{String(index + 1).padStart(4, \" \")} </Text>\n <Text>{truncateLine(line, 70)}</Text>\n </Box>\n ))}\n {truncated && (\n <Box marginTop={1}>\n <Text dimColor>\n ... {totalLines - maxLines} more lines ...\n </Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n}\n\n/**\n * Truncate a line if too long.\n */\nfunction truncateLine(line: string, maxLength: number): string {\n if (line.length <= maxLength) {\n return line;\n }\n return line.substring(0, maxLength - 3) + \"...\";\n}\n\n/**\n * Compact file written notification.\n */\ninterface FileWrittenProps {\n path: string;\n}\n\nexport function FileWritten({ path }: FileWrittenProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.success}>✓ Wrote: </Text>\n <Text color={colors.file}>{path}</Text>\n </Box>\n );\n}\n\n/**\n * Compact file edited notification.\n */\ninterface FileEditedProps {\n path: string;\n occurrences: number;\n}\n\nexport function FileEdited({\n path,\n occurrences,\n}: FileEditedProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.success}>{emoji.edit} Edited: </Text>\n <Text color={colors.file}>{path}</Text>\n <Text dimColor>\n {\" \"}\n ({occurrences} change{occurrences === 1 ? \"\" : \"s\"})\n </Text>\n </Box>\n );\n}\n\n/**\n * Compact file read notification.\n */\ninterface FileReadProps {\n path: string;\n lines: number;\n}\n\nexport function FileRead({ path, lines }: FileReadProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.info}>📖 Read: </Text>\n <Text color={colors.file}>{path}</Text>\n <Text dimColor> ({lines} lines)</Text>\n </Box>\n );\n}\n\n/**\n * Compact ls result notification.\n */\ninterface LsResultProps {\n path: string;\n count: number;\n}\n\nexport function LsResult({ path, count }: LsResultProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.info}>📂 Listed: </Text>\n <Text color={colors.file}>{path}</Text>\n <Text dimColor> ({count} item{count === 1 ? \"\" : \"s\"})</Text>\n </Box>\n );\n}\n\n/**\n * Compact glob result notification.\n */\ninterface GlobResultProps {\n pattern: string;\n count: number;\n}\n\nexport function GlobResult({ pattern, count }: GlobResultProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.info}>🔍 Glob: </Text>\n <Text color={colors.tool}>{pattern}</Text>\n <Text dimColor> ({count} match{count === 1 ? \"\" : \"es\"})</Text>\n </Box>\n );\n}\n\n/**\n * Compact grep result notification.\n */\ninterface GrepResultProps {\n pattern: string;\n count: number;\n}\n\nexport function GrepResult({ pattern, count }: GrepResultProps): React.ReactElement {\n return (\n <Box>\n <Text color={colors.info}>🔎 Grep: </Text>\n <Text color={colors.tool}>{pattern}</Text>\n <Text dimColor> ({count} match{count === 1 ? \"\" : \"es\"})</Text>\n </Box>\n );\n}\n\n/**\n * File list panel for /files command.\n */\ninterface FileListProps {\n files: FileInfo[];\n workDir?: string;\n}\n\nexport function FileList({\n files,\n workDir,\n}: FileListProps): React.ReactElement {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Box marginBottom={1}>\n <Text bold color={colors.info}>\n {emoji.file} Files\n </Text>\n {workDir && <Text dimColor> in {workDir}</Text>}\n </Box>\n\n {files.length === 0 ? (\n <Box paddingLeft={2}>\n <Text dimColor>No files found.</Text>\n </Box>\n ) : (\n <Box flexDirection=\"column\">\n {files.map((file) => (\n <Box key={file.path} paddingLeft={2}>\n <Text>{file.is_dir ? \"📁\" : \"📄\"} </Text>\n <Text color={colors.file}>{file.path}</Text>\n {file.size !== undefined && (\n <Text dimColor> ({file.size} bytes)</Text>\n )}\n </Box>\n ))}\n </Box>\n )}\n </Box>\n );\n}\n\n","/**\n * Tool call display component with spinner.\n * Clean, minimal design.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Spinner, StatusMessage } from \"@inkjs/ui\";\nimport { colors } from \"../theme\";\n\ninterface ToolCallProps {\n /** Tool name being called */\n toolName: string;\n /** Whether the tool is currently executing */\n isExecuting?: boolean;\n /** Tool arguments (optional, for display) */\n args?: unknown;\n}\n\nexport function ToolCall({\n toolName,\n isExecuting = true,\n}: ToolCallProps): React.ReactElement {\n if (isExecuting) {\n return (\n <Box>\n <Spinner label={toolName} />\n </Box>\n );\n }\n\n return (\n <Box>\n <Text color={colors.success}>✓</Text>\n <Text> {toolName}</Text>\n </Box>\n );\n}\n\n/**\n * Tool result display.\n */\ninterface ToolResultProps {\n toolName: string;\n result: unknown;\n maxLength?: number;\n}\n\nexport function ToolResult({\n toolName,\n result,\n maxLength = 100,\n}: ToolResultProps): React.ReactElement {\n let resultStr = String(result);\n if (resultStr.length > maxLength) {\n resultStr = resultStr.substring(0, maxLength) + \"...\";\n }\n\n return (\n <Box>\n <Text color={colors.success}>✓ </Text>\n <Text color={colors.tool}>{toolName}</Text>\n <Text dimColor> → {resultStr}</Text>\n </Box>\n );\n}\n\n/**\n * Step indicator for multi-step operations.\n */\ninterface StepIndicatorProps {\n stepNumber: number;\n}\n\nexport function StepIndicator({\n stepNumber,\n}: StepIndicatorProps): React.ReactElement {\n return (\n <Box>\n <Text dimColor>step {stepNumber}</Text>\n </Box>\n );\n}\n\n/**\n * Thinking indicator with animated spinner.\n */\nexport function ThinkingIndicator(): React.ReactElement {\n return (\n <Box>\n <Text color={colors.warning}>● </Text>\n <Spinner label=\"\" />\n </Box>\n );\n}\n\n/**\n * Done indicator.\n */\ninterface DoneIndicatorProps {\n todosCompleted: number;\n todosTotal: number;\n filesCount: number;\n}\n\nexport function DoneIndicator({\n todosCompleted,\n todosTotal,\n filesCount,\n}: DoneIndicatorProps): React.ReactElement {\n const hasTodos = todosTotal > 0;\n const hasFiles = filesCount > 0;\n \n if (!hasTodos && !hasFiles) {\n return <></>;\n }\n\n return (\n <Box>\n <Text dimColor>\n {hasTodos && `${todosCompleted}/${todosTotal} tasks`}\n {hasTodos && hasFiles && \" · \"}\n {hasFiles && `${filesCount} files`}\n </Text>\n </Box>\n );\n}\n\n/**\n * Error display.\n */\ninterface ErrorDisplayProps {\n error: Error | string;\n}\n\nexport function ErrorDisplay({ error }: ErrorDisplayProps): React.ReactElement {\n const message = error instanceof Error ? error.message : error;\n\n return (\n <Box>\n <Text color={colors.error}>✗ {message}</Text>\n </Box>\n );\n}\n\n","/**\n * Subagent status display components.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Spinner, StatusMessage } from \"@inkjs/ui\";\nimport { emoji, colors } from \"../theme\";\n\ninterface SubagentStartProps {\n /** Subagent name */\n name: string;\n /** Task description */\n task: string;\n /** Maximum task length to display */\n maxTaskLength?: number;\n}\n\nexport function SubagentStart({\n name,\n task,\n maxTaskLength = 60,\n}: SubagentStartProps): React.ReactElement {\n const shortTask =\n task.length > maxTaskLength\n ? task.substring(0, maxTaskLength) + \"...\"\n : task;\n\n return (\n <Box flexDirection=\"column\" marginY={1}>\n <Box>\n <Spinner\n label={`${emoji.subagent} Starting subagent: ${name}`}\n />\n </Box>\n <Box paddingLeft={4}>\n <Text dimColor>└─ {shortTask}</Text>\n </Box>\n </Box>\n );\n}\n\ninterface SubagentFinishProps {\n /** Subagent name */\n name: string;\n}\n\nexport function SubagentFinish({\n name,\n}: SubagentFinishProps): React.ReactElement {\n return (\n <Box marginY={1}>\n <StatusMessage variant=\"success\">\n {emoji.subagent} Subagent {name} completed\n </StatusMessage>\n </Box>\n );\n}\n\n/**\n * Subagent running indicator (for when a subagent is actively working).\n */\ninterface SubagentRunningProps {\n name: string;\n task: string;\n}\n\nexport function SubagentRunning({\n name,\n task,\n}: SubagentRunningProps): React.ReactElement {\n const shortTask = task.length > 50 ? task.substring(0, 50) + \"...\" : task;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.secondary}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Box>\n <Spinner label={`${emoji.subagent} ${name}`} />\n </Box>\n <Box paddingLeft={2}>\n <Text dimColor>{shortTask}</Text>\n </Box>\n </Box>\n );\n}\n\n","/**\n * Compact status bar component.\n * Clean, minimal design inspired by Claude Code and OpenAI Codex.\n */\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { colors } from \"../theme\";\n\ninterface FeatureFlags {\n promptCaching: boolean;\n eviction: boolean;\n summarization: boolean;\n}\n\ninterface StatusBarProps {\n /** Current working directory */\n workDir: string;\n /** Current model name */\n model: string;\n /** Optional status indicator (idle, generating, etc.) */\n status?: \"idle\" | \"thinking\" | \"streaming\" | \"tool-call\" | \"subagent\" | \"done\" | \"error\";\n /** Feature flags to display */\n features?: FeatureFlags;\n /** Whether auto-approve mode is enabled */\n autoApproveEnabled?: boolean;\n /** Current session ID if checkpointing is enabled */\n sessionId?: string;\n}\n\nexport function StatusBar({\n workDir,\n model,\n status = \"idle\",\n features,\n autoApproveEnabled = false,\n sessionId,\n}: StatusBarProps): React.ReactElement {\n // Get short model name\n const shortModel = model.split(\"/\").pop() || model;\n \n // Status indicator - minimal\n const getStatusDisplay = () => {\n switch (status) {\n case \"thinking\":\n return <Text color={colors.warning}>●</Text>;\n case \"streaming\":\n return <Text color={colors.success}>●</Text>;\n case \"tool-call\":\n return <Text color={colors.tool}>●</Text>;\n case \"subagent\":\n return <Text color={colors.secondary}>●</Text>;\n case \"error\":\n return <Text color={colors.error}>●</Text>;\n case \"done\":\n return <Text color={colors.success}>●</Text>;\n default:\n return <Text dimColor>○</Text>;\n }\n };\n\n // Feature badges - compact\n const featureBadges: string[] = [];\n if (features?.promptCaching) featureBadges.push(\"⚡\");\n if (features?.eviction) featureBadges.push(\"📦\");\n if (features?.summarization) featureBadges.push(\"📝\");\n\n return (\n <Box marginTop={1}>\n <Text dimColor>\n {getStatusDisplay()} {shortModel}\n {featureBadges.length > 0 && ` ${featureBadges.join(\" \")}`}\n {\" · \"}\n {autoApproveEnabled ? (\n <Text color={colors.success}>🟢 Auto-approve</Text>\n ) : (\n <Text color={colors.warning}>🔴 Safe mode</Text>\n )}\n {sessionId && (\n <>\n {\" · \"}\n <Text dimColor>Session: {sessionId}</Text>\n </>\n )}\n {\" · \"}? for shortcuts\n </Text>\n </Box>\n );\n}\n\n","/**\n * Utility to detect available API keys and fetch models from provider APIs.\n */\n\nexport interface AvailableModel {\n id: string;\n name: string;\n provider: \"anthropic\" | \"openai\";\n description?: string;\n createdAt?: string;\n}\n\nexport interface FetchModelsResult {\n models: AvailableModel[];\n error?: string;\n}\n\n// ============================================================================\n// Cache Implementation\n// ============================================================================\n\ninterface CacheEntry {\n models: AvailableModel[];\n timestamp: number;\n apiKeyHash: string;\n}\n\nconst modelCache: {\n anthropic?: CacheEntry;\n openai?: CacheEntry;\n} = {};\n\n// Cache TTL: 24 hours in milliseconds\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Simple hash function for API key to detect changes.\n */\nfunction hashApiKey(key: string | undefined): string {\n if (!key) return \"\";\n // Just use first 10 and last 4 chars as a simple fingerprint\n return `${key.substring(0, 10)}...${key.substring(key.length - 4)}`;\n}\n\n/**\n * Check if cache is valid for a provider.\n */\nfunction isCacheValid(provider: \"anthropic\" | \"openai\"): boolean {\n const entry = modelCache[provider];\n if (!entry) return false;\n\n const now = Date.now();\n if (now - entry.timestamp > CACHE_TTL_MS) return false;\n\n // Check if API key changed\n const currentKeyHash =\n provider === \"anthropic\"\n ? hashApiKey(process.env.ANTHROPIC_API_KEY)\n : hashApiKey(process.env.OPENAI_API_KEY);\n\n return entry.apiKeyHash === currentKeyHash;\n}\n\n/**\n * Get cached models for a provider.\n */\nfunction getCachedModels(provider: \"anthropic\" | \"openai\"): AvailableModel[] | null {\n if (isCacheValid(provider)) {\n return modelCache[provider]!.models;\n }\n return null;\n}\n\n/**\n * Set cached models for a provider.\n */\nfunction setCachedModels(provider: \"anthropic\" | \"openai\", models: AvailableModel[]): void {\n const apiKeyHash =\n provider === \"anthropic\"\n ? hashApiKey(process.env.ANTHROPIC_API_KEY)\n : hashApiKey(process.env.OPENAI_API_KEY);\n\n modelCache[provider] = {\n models,\n timestamp: Date.now(),\n apiKeyHash,\n };\n}\n\n/**\n * Clear cache for a specific provider or all providers.\n */\nexport function clearModelCache(provider?: \"anthropic\" | \"openai\"): void {\n if (provider) {\n delete modelCache[provider];\n } else {\n delete modelCache.anthropic;\n delete modelCache.openai;\n }\n}\n\n// ============================================================================\n// Provider Detection\n// ============================================================================\n\n/**\n * Detect which API keys are available in the environment.\n */\nexport function detectAvailableProviders(): {\n anthropic: boolean;\n openai: boolean;\n} {\n return {\n anthropic: !!process.env.ANTHROPIC_API_KEY,\n openai: !!process.env.OPENAI_API_KEY,\n };\n}\n\n// ============================================================================\n// Anthropic API\n// ============================================================================\n\ninterface AnthropicModelInfo {\n id: string;\n display_name: string;\n created_at: string;\n type: string;\n}\n\ninterface AnthropicModelsResponse {\n data: AnthropicModelInfo[];\n has_more: boolean;\n first_id: string;\n last_id: string;\n}\n\n/**\n * Fetch available models from Anthropic API.\n * Returns empty array if no API key is set.\n */\nexport async function fetchAnthropicModels(): Promise<FetchModelsResult> {\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n return { models: [], error: \"No Anthropic API key configured\" };\n }\n\n // Check cache first\n const cached = getCachedModels(\"anthropic\");\n if (cached) {\n return { models: cached };\n }\n\n try {\n const response = await fetch(\"https://api.anthropic.com/v1/models?limit=100\", {\n method: \"GET\",\n headers: {\n \"X-Api-Key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 401) {\n return { models: [], error: \"Invalid Anthropic API key\" };\n }\n return { models: [], error: `Anthropic API error: ${response.status} ${errorText}` };\n }\n\n const data = (await response.json()) as AnthropicModelsResponse;\n\n const models: AvailableModel[] = data.data.map((model) => ({\n id: `anthropic/${model.id}`,\n name: model.id,\n provider: \"anthropic\" as const,\n description: model.display_name,\n createdAt: model.created_at,\n }));\n\n // Sort by created_at descending (newest first)\n models.sort((a, b) => {\n if (!a.createdAt || !b.createdAt) return 0;\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n // Cache the results\n setCachedModels(\"anthropic\", models);\n\n return { models };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { models: [], error: `Failed to fetch Anthropic models: ${message}` };\n }\n}\n\n// ============================================================================\n// OpenAI API\n// ============================================================================\n\ninterface OpenAIModelInfo {\n id: string;\n object: string;\n created: number;\n owned_by: string;\n}\n\ninterface OpenAIModelsResponse {\n object: string;\n data: OpenAIModelInfo[];\n}\n\n/**\n * Fetch available models from OpenAI API.\n * Returns empty array if no API key is set.\n */\nexport async function fetchOpenAIModels(): Promise<FetchModelsResult> {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n return { models: [], error: \"No OpenAI API key configured\" };\n }\n\n // Check cache first\n const cached = getCachedModels(\"openai\");\n if (cached) {\n return { models: cached };\n }\n\n try {\n const response = await fetch(\"https://api.openai.com/v1/models\", {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 401) {\n return { models: [], error: \"Invalid OpenAI API key\" };\n }\n return { models: [], error: `OpenAI API error: ${response.status} ${errorText}` };\n }\n\n const data = (await response.json()) as OpenAIModelsResponse;\n\n // Filter to only include chat models (gpt-*)\n const chatModels = data.data.filter(\n (model) =>\n model.id.startsWith(\"gpt-\") ||\n model.id.startsWith(\"o1\") ||\n model.id.startsWith(\"o3\") ||\n model.id.includes(\"chatgpt\")\n );\n\n const models: AvailableModel[] = chatModels.map((model) => ({\n id: `openai/${model.id}`,\n name: model.id,\n provider: \"openai\" as const,\n description: getOpenAIModelDescription(model.id),\n createdAt: new Date(model.created * 1000).toISOString(),\n }));\n\n // Sort by created descending (newest first)\n models.sort((a, b) => {\n if (!a.createdAt || !b.createdAt) return 0;\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n // Cache the results\n setCachedModels(\"openai\", models);\n\n return { models };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { models: [], error: `Failed to fetch OpenAI models: ${message}` };\n }\n}\n\n/**\n * Generate a description for OpenAI models based on their ID.\n */\nfunction getOpenAIModelDescription(modelId: string): string {\n if (modelId.includes(\"gpt-4o-mini\")) return \"Fast and affordable GPT-4 variant\";\n if (modelId.includes(\"gpt-4o\")) return \"Latest GPT-4 optimized model\";\n if (modelId.includes(\"gpt-4-turbo\")) return \"GPT-4 Turbo\";\n if (modelId.includes(\"gpt-4\")) return \"GPT-4\";\n if (modelId.includes(\"gpt-3.5-turbo\")) return \"Fast and affordable\";\n if (modelId.startsWith(\"o1\")) return \"OpenAI o1 reasoning model\";\n if (modelId.startsWith(\"o3\")) return \"OpenAI o3 reasoning model\";\n return \"\";\n}\n\n// ============================================================================\n// Combined Functions\n// ============================================================================\n\nexport interface GetModelsResult {\n models: AvailableModel[];\n errors: { provider: string; error: string }[];\n loading: boolean;\n}\n\n/**\n * Get list of available models from all configured providers.\n * Only fetches from providers that have API keys configured.\n */\nexport async function getAvailableModels(): Promise<GetModelsResult> {\n const providers = detectAvailableProviders();\n const allModels: AvailableModel[] = [];\n const errors: { provider: string; error: string }[] = [];\n\n // Fetch from both providers in parallel\n const promises: Promise<void>[] = [];\n\n if (providers.anthropic) {\n promises.push(\n fetchAnthropicModels().then((result) => {\n allModels.push(...result.models);\n if (result.error) {\n errors.push({ provider: \"Anthropic\", error: result.error });\n }\n })\n );\n }\n\n if (providers.openai) {\n promises.push(\n fetchOpenAIModels().then((result) => {\n allModels.push(...result.models);\n if (result.error) {\n errors.push({ provider: \"OpenAI\", error: result.error });\n }\n })\n );\n }\n\n await Promise.all(promises);\n\n return { models: allModels, errors, loading: false };\n}\n\n/**\n * Get models grouped by provider.\n */\nexport async function getModelsByProvider(): Promise<{\n anthropic?: AvailableModel[];\n openai?: AvailableModel[];\n errors: { provider: string; error: string }[];\n}> {\n const result = await getAvailableModels();\n const grouped: {\n anthropic?: AvailableModel[];\n openai?: AvailableModel[];\n errors: { provider: string; error: string }[];\n } = { errors: result.errors };\n\n for (const model of result.models) {\n if (!grouped[model.provider]) {\n grouped[model.provider] = [];\n }\n grouped[model.provider]!.push(model);\n }\n\n return grouped;\n}\n","/**\n * Model Selection Panel - Interactive model selection with arrow keys.\n */\n\nimport React, { useState, useEffect, useMemo } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { Spinner } from \"@inkjs/ui\";\nimport { colors, emoji } from \"../theme\";\nimport {\n getModelsByProvider,\n detectAvailableProviders,\n type AvailableModel,\n} from \"../utils/model-list\";\n\ninterface ModelSelectionPanelProps {\n currentModel?: string;\n /** Callback when a model is selected */\n onModelSelect?: (modelId: string) => void;\n /** Callback to close the panel */\n onClose?: () => void;\n}\n\ninterface LoadingState {\n loading: boolean;\n anthropicModels: AvailableModel[];\n openaiModels: AvailableModel[];\n errors: { provider: string; error: string }[];\n}\n\nexport function ModelSelectionPanel({\n currentModel,\n onModelSelect,\n onClose,\n}: ModelSelectionPanelProps): React.ReactElement {\n const providers = detectAvailableProviders();\n const hasAnyKey = providers.anthropic || providers.openai;\n\n const [state, setState] = useState<LoadingState>({\n loading: true,\n anthropicModels: [],\n openaiModels: [],\n errors: [],\n });\n\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n // Combine all models into a flat list for navigation\n const allModels = useMemo(() => {\n const models: AvailableModel[] = [];\n if (state.anthropicModels.length > 0) {\n models.push(...state.anthropicModels);\n }\n if (state.openaiModels.length > 0) {\n models.push(...state.openaiModels);\n }\n return models;\n }, [state.anthropicModels, state.openaiModels]);\n\n // Find current model index to set initial selection\n useEffect(() => {\n if (allModels.length > 0 && currentModel) {\n const currentIndex = allModels.findIndex((m) => isCurrentModel(currentModel, m));\n if (currentIndex >= 0) {\n setSelectedIndex(currentIndex);\n }\n }\n }, [allModels, currentModel]);\n\n // Handle keyboard input\n useInput((input, key) => {\n if (state.loading) return;\n\n if (key.upArrow) {\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : allModels.length - 1));\n } else if (key.downArrow) {\n setSelectedIndex((prev) => (prev < allModels.length - 1 ? prev + 1 : 0));\n } else if (key.return) {\n const selectedModel = allModels[selectedIndex];\n if (selectedModel) {\n onModelSelect?.(selectedModel.id);\n onClose?.();\n }\n } else if (key.escape) {\n onClose?.();\n }\n });\n\n // Fetch models on mount\n useEffect(() => {\n if (!hasAnyKey) {\n setState({ loading: false, anthropicModels: [], openaiModels: [], errors: [] });\n return;\n }\n\n let cancelled = false;\n\n async function loadModels() {\n try {\n const result = await getModelsByProvider();\n if (!cancelled) {\n setState({\n loading: false,\n anthropicModels: result.anthropic || [],\n openaiModels: result.openai || [],\n errors: result.errors,\n });\n }\n } catch (error) {\n if (!cancelled) {\n setState({\n loading: false,\n anthropicModels: [],\n openaiModels: [],\n errors: [{ provider: \"Unknown\", error: String(error) }],\n });\n }\n }\n }\n\n loadModels();\n\n return () => {\n cancelled = true;\n };\n }, [hasAnyKey]);\n\n // No API keys configured\n if (!hasAnyKey) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.warning}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.warning}>\n ⚠️ No API Keys Found\n </Text>\n <Box height={1} />\n <Text>Add an API key first to see available models.</Text>\n <Box height={1} />\n <Text color={colors.primary}>Run /apikey to add your API key</Text>\n <Box height={1} />\n <Text dimColor>Supported providers:</Text>\n <Text dimColor> • Anthropic (Claude)</Text>\n <Text dimColor> • OpenAI (GPT)</Text>\n </Box>\n );\n }\n\n // Loading state\n if (state.loading) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n {emoji.model} Select Model\n </Text>\n <Box height={1} />\n <Box>\n <Spinner label=\"Fetching models from API...\" />\n </Box>\n </Box>\n );\n }\n\n // Check if we have any models\n const hasModels = allModels.length > 0;\n\n // No models found (API errors)\n if (!hasModels && state.errors.length > 0) {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.error}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.error}>\n {emoji.error} Failed to Fetch Models\n </Text>\n <Box height={1} />\n {state.errors.map((err, i) => (\n <Text key={i} color={colors.error}>\n {err.provider}: {err.error}\n </Text>\n ))}\n <Box height={1} />\n <Text dimColor>Check your API key and try again with /apikey</Text>\n </Box>\n );\n }\n\n // Calculate the offset for each provider section\n let anthropicOffset = 0;\n let openaiOffset = state.anthropicModels.length;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.primary}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n {emoji.model} Select Model\n </Text>\n <Box height={1} />\n\n {/* Show any errors */}\n {state.errors.length > 0 && (\n <>\n {state.errors.map((err, i) => (\n <Text key={i} color={colors.warning}>\n {emoji.warning} {err.provider}: {err.error}\n </Text>\n ))}\n <Box height={1} />\n </>\n )}\n\n {/* Anthropic Models */}\n {state.anthropicModels.length > 0 && (\n <>\n <Text bold color={colors.primary}>\n Anthropic Claude\n </Text>\n {state.anthropicModels.map((model, index) => {\n const globalIndex = anthropicOffset + index;\n const isSelected = globalIndex === selectedIndex;\n const isCurrent = isCurrentModel(currentModel, model);\n return (\n <ModelItem\n key={model.id}\n model={model}\n isSelected={isSelected}\n isCurrent={isCurrent}\n />\n );\n })}\n <Box height={1} />\n </>\n )}\n\n {/* OpenAI Models */}\n {state.openaiModels.length > 0 && (\n <>\n <Text bold color={colors.primary}>\n OpenAI GPT\n </Text>\n {state.openaiModels.map((model, index) => {\n const globalIndex = openaiOffset + index;\n const isSelected = globalIndex === selectedIndex;\n const isCurrent = isCurrentModel(currentModel, model);\n return (\n <ModelItem\n key={model.id}\n model={model}\n isSelected={isSelected}\n isCurrent={isCurrent}\n />\n );\n })}\n <Box height={1} />\n </>\n )}\n\n {/* Navigation hint */}\n <Text dimColor>↑/↓ Navigate • Enter Select • Esc Cancel</Text>\n </Box>\n );\n}\n\n/**\n * Check if a model matches the current model.\n */\nfunction isCurrentModel(currentModel: string | undefined, model: AvailableModel): boolean {\n if (!currentModel) return false;\n return (\n currentModel === model.id ||\n currentModel === model.name ||\n currentModel === `${model.provider}/${model.name}` ||\n (currentModel.startsWith(`${model.provider}/`) && currentModel === model.id)\n );\n}\n\ninterface ModelItemProps {\n model: AvailableModel;\n isSelected: boolean;\n isCurrent: boolean;\n}\n\nfunction ModelItem({ model, isSelected, isCurrent }: ModelItemProps): React.ReactElement {\n // Determine the indicator\n let indicator = \" \";\n let textColor: string | undefined = undefined;\n let isBold = false;\n\n if (isSelected) {\n indicator = \"▸ \";\n textColor = colors.primary;\n isBold = true;\n }\n\n if (isCurrent) {\n indicator = isSelected ? \"▸✓\" : \" ✓\";\n textColor = isSelected ? colors.primary : colors.success;\n }\n\n return (\n <Box marginLeft={1}>\n <Text color={isSelected ? colors.primary : isCurrent ? colors.success : undefined}>\n {indicator}\n </Text>\n <Text color={textColor} bold={isBold}>\n {model.id}\n </Text>\n {model.description && (\n <>\n <Text dimColor> - </Text>\n <Text dimColor>{model.description}</Text>\n </>\n )}\n </Box>\n );\n}\n","/**\n * API Key Input Panel - Interactive provider selection and key input.\n * Shows current status and allows adding/updating keys.\n */\n\nimport React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport { colors, emoji } from \"../theme\";\n\ntype Provider = \"anthropic\" | \"openai\";\n\ninterface ApiKeyInputPanelProps {\n /** Callback when API key is saved */\n onKeySaved?: (provider: Provider, key: string) => void;\n /** Callback to close the panel */\n onClose?: () => void;\n}\n\ntype Step = \"select-provider\" | \"enter-key\" | \"success\";\n\nexport function ApiKeyInputPanel({\n onKeySaved,\n onClose,\n}: ApiKeyInputPanelProps): React.ReactElement {\n const [step, setStep] = useState<Step>(\"select-provider\");\n const [selectedProvider, setSelectedProvider] = useState<Provider | null>(null);\n const [apiKey, setApiKey] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n\n // Get current API keys\n const anthropicKey = process.env.ANTHROPIC_API_KEY;\n const openaiKey = process.env.OPENAI_API_KEY;\n\n const maskKey = (key: string | undefined) => {\n if (!key) return null;\n if (key.length <= 8) return \"•\".repeat(key.length);\n return key.substring(0, 10) + \"...\" + key.substring(key.length - 4);\n };\n\n // Handle keyboard input\n useInput((input, key) => {\n if (step === \"select-provider\") {\n if (input === \"1\" || input.toLowerCase() === \"a\") {\n setSelectedProvider(\"anthropic\");\n setStep(\"enter-key\");\n setError(null);\n // Pre-fill existing key if available\n if (anthropicKey) {\n setApiKey(anthropicKey);\n }\n } else if (input === \"2\" || input.toLowerCase() === \"o\") {\n setSelectedProvider(\"openai\");\n setStep(\"enter-key\");\n setError(null);\n // Pre-fill existing key if available\n if (openaiKey) {\n setApiKey(openaiKey);\n }\n } else if (key.escape) {\n onClose?.();\n }\n } else if (step === \"enter-key\") {\n if (key.escape) {\n // Go back to provider selection\n setStep(\"select-provider\");\n setApiKey(\"\");\n setSelectedProvider(null);\n setError(null);\n } else if (key.return) {\n // Validate and save\n if (!apiKey.trim()) {\n setError(\"API key cannot be empty\");\n return;\n }\n\n // Basic validation\n if (selectedProvider === \"anthropic\" && !apiKey.startsWith(\"sk-ant-\")) {\n setError(\"Anthropic API keys typically start with 'sk-ant-'\");\n return;\n }\n if (selectedProvider === \"openai\" && !apiKey.startsWith(\"sk-\")) {\n setError(\"OpenAI API keys typically start with 'sk-'\");\n return;\n }\n\n // Save to environment\n if (selectedProvider === \"anthropic\") {\n process.env.ANTHROPIC_API_KEY = apiKey.trim();\n } else if (selectedProvider === \"openai\") {\n process.env.OPENAI_API_KEY = apiKey.trim();\n }\n\n setStep(\"success\");\n onKeySaved?.(selectedProvider!, apiKey.trim());\n\n // Auto-return to provider selection after success\n setTimeout(() => {\n setStep(\"select-provider\");\n setApiKey(\"\");\n setSelectedProvider(null);\n }, 1500);\n } else if (key.backspace || key.delete) {\n setApiKey((prev) => prev.slice(0, -1));\n setError(null);\n } else if (input && !key.ctrl && !key.meta) {\n setApiKey((prev) => prev + input);\n setError(null);\n }\n } else if (step === \"success\") {\n if (key.return || key.escape) {\n // Return to provider selection\n setStep(\"select-provider\");\n setApiKey(\"\");\n setSelectedProvider(null);\n }\n }\n });\n\n const maskKeyForInput = (key: string): string => {\n if (key.length <= 8) return \"•\".repeat(key.length);\n return key.substring(0, 7) + \"•\".repeat(Math.min(key.length - 11, 20)) + key.substring(key.length - 4);\n };\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.primary}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n {emoji.key} API Key Management\n </Text>\n <Box height={1} />\n\n {/* Always show current status */}\n <Text bold>Current Status:</Text>\n <Box height={1} />\n <Box marginLeft={2}>\n {anthropicKey ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>Anthropic: </Text>\n <Text dimColor>{maskKey(anthropicKey)}</Text>\n </>\n ) : (\n <>\n <Text color={colors.warning}>✗ </Text>\n <Text>Anthropic: </Text>\n <Text dimColor>not set</Text>\n </>\n )}\n </Box>\n <Box marginLeft={2}>\n {openaiKey ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>OpenAI: </Text>\n <Text dimColor>{maskKey(openaiKey)}</Text>\n </>\n ) : (\n <>\n <Text color={colors.warning}>✗ </Text>\n <Text>OpenAI: </Text>\n <Text dimColor>not set</Text>\n </>\n )}\n </Box>\n <Box height={1} />\n\n {step === \"select-provider\" && (\n <>\n <Text bold>Add or Update Key:</Text>\n <Box height={1} />\n <Box marginLeft={2}>\n <Text color={colors.primary}>[1]</Text>\n <Text> Anthropic (Claude)</Text>\n {anthropicKey && <Text dimColor> (overwrite)</Text>}\n </Box>\n <Box marginLeft={2}>\n <Text color={colors.primary}>[2]</Text>\n <Text> OpenAI (GPT)</Text>\n {openaiKey && <Text dimColor> (overwrite)</Text>}\n </Box>\n <Box height={1} />\n <Text dimColor>Press 1 or 2 to select, Esc to close</Text>\n </>\n )}\n\n {step === \"enter-key\" && selectedProvider && (\n <>\n <Text>\n Enter your{\" \"}\n <Text color={colors.primary}>\n {selectedProvider === \"anthropic\" ? \"Anthropic\" : \"OpenAI\"}\n </Text>{\" \"}\n API key:\n {selectedProvider === \"anthropic\" && anthropicKey && (\n <Text dimColor> (current: {maskKey(anthropicKey)})</Text>\n )}\n {selectedProvider === \"openai\" && openaiKey && (\n <Text dimColor> (current: {maskKey(openaiKey)})</Text>\n )}\n </Text>\n <Box height={1} />\n <Box>\n <Text dimColor>{\">\"} </Text>\n <Text>{apiKey ? maskKeyForInput(apiKey) : <Text dimColor>Paste your API key here...</Text>}</Text>\n <Text color={colors.primary}>█</Text>\n </Box>\n {error && (\n <>\n <Box height={1} />\n <Text color={colors.error}>{emoji.warning} {error}</Text>\n </>\n )}\n <Box height={1} />\n <Text dimColor>Press Enter to save, Esc to go back</Text>\n </>\n )}\n\n {step === \"success\" && selectedProvider && (\n <>\n <Text color={colors.success}>\n {emoji.completed} API key saved for{\" \"}\n {selectedProvider === \"anthropic\" ? \"Anthropic\" : \"OpenAI\"}!\n </Text>\n <Box height={1} />\n <Text dimColor>Press Enter or Esc to return to menu</Text>\n </>\n )}\n </Box>\n );\n}\n\n/**\n * Simple API Key Status display (read-only).\n */\nexport function ApiKeyStatus(): React.ReactElement {\n const anthropicKey = process.env.ANTHROPIC_API_KEY;\n const openaiKey = process.env.OPENAI_API_KEY;\n\n const maskKey = (key: string | undefined) => {\n if (!key) return null;\n return key.substring(0, 10) + \"...\" + key.substring(key.length - 4);\n };\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n {emoji.key} API Keys\n </Text>\n <Box height={1} />\n <Box>\n {anthropicKey ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>Anthropic: </Text>\n <Text dimColor>{maskKey(anthropicKey)}</Text>\n </>\n ) : (\n <>\n <Text color={colors.warning}>✗ </Text>\n <Text>Anthropic: </Text>\n <Text dimColor>not set</Text>\n </>\n )}\n </Box>\n <Box>\n {openaiKey ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>OpenAI: </Text>\n <Text dimColor>{maskKey(openaiKey)}</Text>\n </>\n ) : (\n <>\n <Text color={colors.warning}>✗ </Text>\n <Text>OpenAI: </Text>\n <Text dimColor>not set</Text>\n </>\n )}\n </Box>\n <Box height={1} />\n <Text dimColor>Use /apikey set to add or update keys</Text>\n </Box>\n );\n}\n\n\n\n","/**\n * Tool approval component for interactive approval flow.\n */\nimport React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\ninterface ToolApprovalProps {\n toolName: string;\n args: unknown;\n onApprove: () => void;\n onDeny: () => void;\n onApproveAll?: () => void;\n}\n\nexport function ToolApproval({\n toolName,\n args,\n onApprove,\n onDeny,\n onApproveAll,\n}: ToolApprovalProps): React.ReactElement {\n useInput((input, key) => {\n if (input === \"y\" || input === \"Y\") {\n onApprove();\n } else if (input === \"n\" || input === \"N\" || key.escape) {\n onDeny();\n } else if ((input === \"a\" || input === \"A\") && onApproveAll) {\n onApproveAll();\n }\n });\n\n // Format args for display (truncate if too long)\n const argsDisplay = JSON.stringify(args, null, 2);\n const truncatedArgs =\n argsDisplay.length > 500\n ? argsDisplay.slice(0, 500) + \"\\n... (truncated)\"\n : argsDisplay;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"yellow\"\n paddingX={1}\n marginY={1}\n >\n <Text bold color=\"yellow\">\n 🛑 Tool Approval Required\n </Text>\n <Text>\n Tool: <Text bold>{toolName}</Text>\n </Text>\n <Box marginTop={1}>\n <Text dimColor>Arguments:</Text>\n </Box>\n <Text>{truncatedArgs}</Text>\n <Box marginTop={1}>\n <Text>\n Press <Text bold color=\"green\">[Y]</Text> to approve,{\" \"}\n <Text bold color=\"red\">[N]</Text> to deny\n {onApproveAll && (\n <>\n , <Text bold color=\"blue\">[A]</Text> to approve all (enable auto-approve)\n </>\n )}\n </Text>\n </Box>\n </Box>\n );\n}\n","#!/usr/bin/env bun\n/**\n * Deep Agent CLI - Interactive terminal interface using Ink.\n *\n * Usage:\n * ANTHROPIC_API_KEY=xxx bunx deep-agent-ink\n * ANTHROPIC_API_KEY=xxx bun src/cli-ink/index.tsx\n *\n * Or with options:\n * ANTHROPIC_API_KEY=xxx bunx deep-agent-ink --model anthropic/claude-sonnet-4-20250514\n */\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport { render, useApp, useInput, Box, Text, Static } from \"ink\";\nimport { LocalSandbox } from \"../backends/local-sandbox\";\nimport {\n DEFAULT_EVICTION_TOKEN_LIMIT,\n DEFAULT_SUMMARIZATION_THRESHOLD,\n DEFAULT_KEEP_MESSAGES,\n CONTEXT_WINDOW,\n} from \"../constants/limits\";\nimport { FileSaver } from \"../checkpointer/file-saver\";\nimport { useAgent, type AgentEventLog } from \"./hooks/useAgent\";\nimport {\n Welcome,\n WelcomeHint,\n Input,\n SlashMenuPanel,\n Message,\n StreamingMessage,\n TodoList,\n FilePreview,\n FileWritten,\n FileEdited,\n FileRead,\n LsResult,\n GlobResult,\n GrepResult,\n FileList,\n ToolCall,\n StepIndicator,\n ThinkingIndicator,\n DoneIndicator,\n ErrorDisplay,\n SubagentStart,\n SubagentFinish,\n StatusBar,\n ModelSelectionPanel,\n ApiKeyInputPanel,\n ToolApproval,\n type MessageData,\n} from \"./components/index\";\nimport { parseCommand, colors, SLASH_COMMANDS } from \"./theme\";\nimport type { FileInfo } from \"../types\";\nimport { estimateMessagesTokens } from \"../utils/summarization\";\n\n// ============================================================================\n// CLI Arguments\n// ============================================================================\n\ninterface CLIOptions {\n model?: string;\n maxSteps?: number;\n systemPrompt?: string;\n workDir?: string;\n session?: string;\n // New feature flags\n enablePromptCaching?: boolean;\n toolResultEvictionLimit?: number;\n enableSummarization?: boolean;\n summarizationThreshold?: number;\n summarizationKeepMessages?: number;\n}\n\n// Default values for features (enabled by default)\nconst DEFAULT_PROMPT_CACHING = true;\nconst DEFAULT_EVICTION_LIMIT = DEFAULT_EVICTION_TOKEN_LIMIT;\nconst DEFAULT_SUMMARIZATION = true;\nconst DEFAULT_SUMMARIZATION_THRESHOLD_VALUE = DEFAULT_SUMMARIZATION_THRESHOLD;\nconst DEFAULT_SUMMARIZATION_KEEP = DEFAULT_KEEP_MESSAGES;\n\nfunction parseArgs(): CLIOptions {\n const args = process.argv.slice(2);\n // Start with defaults enabled\n const options: CLIOptions = {\n enablePromptCaching: DEFAULT_PROMPT_CACHING,\n toolResultEvictionLimit: DEFAULT_EVICTION_LIMIT,\n enableSummarization: DEFAULT_SUMMARIZATION,\n summarizationThreshold: DEFAULT_SUMMARIZATION_THRESHOLD_VALUE,\n summarizationKeepMessages: DEFAULT_SUMMARIZATION_KEEP,\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === \"--model\" || arg === \"-m\") {\n options.model = args[++i];\n } else if (arg === \"--max-steps\" || arg === \"-s\") {\n const val = args[++i];\n if (val) options.maxSteps = parseInt(val, 10);\n } else if (arg === \"--prompt\" || arg === \"-p\") {\n options.systemPrompt = args[++i];\n } else if (arg === \"--dir\" || arg === \"-d\") {\n options.workDir = args[++i];\n } else if (arg === \"--cache\" || arg === \"--prompt-caching\") {\n options.enablePromptCaching = true;\n } else if (arg === \"--no-cache\" || arg === \"--no-prompt-caching\") {\n options.enablePromptCaching = false;\n } else if (arg === \"--eviction-limit\" || arg === \"-e\") {\n const val = args[++i];\n if (val) options.toolResultEvictionLimit = parseInt(val, 10);\n } else if (arg === \"--no-eviction\") {\n options.toolResultEvictionLimit = 0;\n } else if (arg === \"--summarize\" || arg === \"--auto-summarize\") {\n options.enableSummarization = true;\n } else if (arg === \"--no-summarize\" || arg === \"--no-auto-summarize\") {\n options.enableSummarization = false;\n } else if (arg === \"--summarize-threshold\") {\n const val = args[++i];\n if (val) {\n options.summarizationThreshold = parseInt(val, 10);\n options.enableSummarization = true;\n }\n } else if (arg === \"--summarize-keep\") {\n const val = args[++i];\n if (val) {\n options.summarizationKeepMessages = parseInt(val, 10);\n options.enableSummarization = true;\n }\n } else if (arg === \"--session\") {\n const val = args[++i];\n if (val) options.session = val;\n } else if (arg && arg.startsWith(\"--session=\")) {\n const sessionVal = arg.split(\"=\")[1];\n if (sessionVal) options.session = sessionVal;\n } else if (arg === \"--help\" || arg === \"-h\") {\n printHelp();\n process.exit(0);\n }\n }\n\n return options;\n}\n\nconst DEEP_AGENTS_ASCII = `\n █████╗ ██╗ ███████╗ ██████╗ ██╗ ██╗\n ██╔══██╗ ██║ ██╔════╝ ██╔══██╗ ██║ ██╔╝\n ███████║ ██║█████╗███████╗ ██║ ██║ █████╔╝\n ██╔══██║ ██║╚════╝╚════██║ ██║ ██║ ██╔═██╗\n ██║ ██║ ██║ ███████║ ██████╔╝ ██║ ██╗\n ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝\n\n ██████╗ ███████╗ ███████╗ ██████╗\n ██╔══██╗ ██╔════╝ ██╔════╝ ██╔══██╗\n ██║ ██║ █████╗ █████╗ ██████╔╝\n ██║ ██║ ██╔══╝ ██╔══╝ ██╔═══╝\n ██████╔╝ ███████╗ ███████╗ ██║\n ╚═════╝ ╚══════╝ ╚══════╝ ╚═╝\n\n █████╗ ██████╗ ███████╗ ███╗ ██╗ ████████╗\n ██╔══██╗ ██╔════╝ ██╔════╝ ████╗ ██║ ╚══██╔══╝\n ███████║ ██║ ███╗ █████╗ ██╔██╗ ██║ ██║\n ██╔══██║ ██║ ██║ ██╔══╝ ██║╚██╗██║ ██║\n ██║ ██║ ╚██████╔╝ ███████╗ ██║ ╚████║ ██║\n ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═══╝ ╚═╝\n`;\n\n\nfunction printHelp(): void {\n console.log(`\n${DEEP_AGENTS_ASCII}\n\nUsage:\n bun src/cli-ink/index.tsx [options]\n\nOptions:\n --model, -m <model> Model to use (default: anthropic/claude-haiku-4-5-20251001)\n --max-steps, -s <number> Maximum steps per generation (default: 100)\n --prompt, -p <prompt> Custom system prompt\n --dir, -d <directory> Working directory for file operations (default: current dir)\n --help, -h Show this help\n\nPerformance & Memory (all enabled by default):\n --no-cache Disable prompt caching (enabled by default for Anthropic)\n --no-eviction Disable tool result eviction (enabled by default: 20k tokens)\n --eviction-limit, -e <n> Set custom eviction token limit\n --no-summarize Disable auto-summarization (enabled by default)\n --summarize-threshold <n> Token threshold to trigger summarization (default: 170000)\n --summarize-keep <n> Number of recent messages to keep intact (default: 6)\n\nRuntime Commands:\n /cache on|off Toggle prompt caching\n /eviction on|off Toggle tool result eviction\n /summarize on|off Toggle auto-summarization\n /features Show current feature status\n\nAPI Keys:\n The CLI automatically loads API keys from:\n 1. Environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY, TAVILY_API_KEY)\n 2. .env or .env.local file in the working directory\n\n Example .env file:\n ANTHROPIC_API_KEY=sk-ant-...\n OPENAI_API_KEY=sk-...\n TAVILY_API_KEY=tvly-... # For web_search tool\n\nExamples:\n bun src/cli-ink/index.tsx # uses .env file\n bun src/cli-ink/index.tsx --dir ./my-project # loads .env from ./my-project\n ANTHROPIC_API_KEY=xxx bun src/cli-ink/index.tsx # env var takes precedence\n bun src/cli-ink/index.tsx --model anthropic/claude-sonnet-4-20250514\n`);\n}\n\n// ============================================================================\n// Main App Component\n// ============================================================================\n\ninterface AppProps {\n options: CLIOptions;\n backend: LocalSandbox;\n}\n\ntype PanelView = \"none\" | \"help\" | \"todos\" | \"files\" | \"file-content\" | \"apikey-input\" | \"features\" | \"tokens\" | \"models\";\n\ninterface PanelState {\n view: PanelView;\n fileContent?: string;\n filePath?: string;\n files?: FileInfo[];\n tokenCount?: number;\n}\n\nfunction App({ options, backend }: AppProps): React.ReactElement {\n const { exit } = useApp();\n\n // Build summarization config if enabled\n const summarizationConfig = options.enableSummarization\n ? {\n enabled: true,\n tokenThreshold: options.summarizationThreshold,\n keepMessages: options.summarizationKeepMessages,\n }\n : undefined;\n\n // Create checkpointer if session is provided\n const checkpointer = options.session\n ? new FileSaver({ dir: \"./.checkpoints\" })\n : undefined;\n\n // Agent hook with new feature options\n const agent = useAgent({\n model: options.model || \"anthropic/claude-haiku-4-5-20251001\",\n maxSteps: options.maxSteps || 100,\n systemPrompt: options.systemPrompt,\n backend,\n enablePromptCaching: options.enablePromptCaching,\n toolResultEvictionLimit: options.toolResultEvictionLimit,\n summarization: summarizationConfig,\n sessionId: options.session,\n checkpointer,\n // Default interruptOn config for CLI - safe defaults\n interruptOn: {\n execute: true,\n write_file: true,\n edit_file: true,\n },\n });\n\n // UI state\n const [messages, setMessages] = useState<MessageData[]>([]);\n const [showWelcome, setShowWelcome] = useState(true);\n const [panel, setPanel] = useState<PanelState>({ view: \"none\" });\n\n // Handle Ctrl+C to abort generation\n useInput((input, key) => {\n if (key.ctrl && input === \"c\") {\n if (agent.status !== \"idle\") {\n agent.abort();\n } else {\n exit();\n }\n }\n if (key.ctrl && input === \"d\") {\n exit();\n }\n });\n\n // Handle input submission\n const handleSubmit = useCallback(\n async (input: string) => {\n const trimmed = input.trim();\n if (!trimmed) return;\n\n // Hide welcome on first input\n if (showWelcome) {\n setShowWelcome(false);\n }\n\n // Check for commands\n const { isCommand, command, args } = parseCommand(trimmed);\n\n if (isCommand) {\n await handleCommand(command, args);\n return;\n }\n\n // Clear any panel\n setPanel({ view: \"none\" });\n\n // Send to agent - user message is added to events by useAgent hook\n // Events serve as the conversation history with proper formatting\n await agent.sendPrompt(trimmed);\n },\n [showWelcome, agent]\n );\n\n // Handle slash commands\n const handleCommand = async (command?: string, args?: string) => {\n // Show slash menu if just \"/\"\n if (!command || command === \"\") {\n setPanel({ view: \"help\" });\n return;\n }\n\n switch (command) {\n case \"todos\":\n case \"todo\":\n case \"t\":\n setPanel({ view: \"todos\" });\n break;\n\n case \"files\":\n case \"file\":\n case \"f\":\n try {\n const files = await backend.lsInfo(\".\");\n setPanel({ view: \"files\", files });\n } catch (err) {\n // Handle error\n }\n break;\n\n case \"read\":\n case \"r\":\n if (!args) {\n // Show usage\n return;\n }\n try {\n const content = await backend.read(args);\n setPanel({ view: \"file-content\", filePath: args, fileContent: content });\n } catch (err) {\n // Handle error\n }\n break;\n\n case \"apikey\":\n case \"key\":\n case \"api\":\n // Always show interactive API key panel\n setPanel({ view: \"apikey-input\" });\n break;\n\n case \"model\":\n if (args) {\n agent.setModel(args.trim());\n } else {\n // Show available models if no args provided\n setPanel({ view: \"models\" });\n }\n break;\n\n case \"features\":\n case \"feat\":\n setPanel({ view: \"features\" });\n break;\n\n case \"tokens\":\n case \"tok\":\n const tokenCount = estimateMessagesTokens(agent.messages);\n setPanel({ view: \"tokens\", tokenCount });\n break;\n\n case \"sessions\":\n case \"session-list\":\n if (checkpointer) {\n const sessions = await checkpointer.list();\n if (sessions.length > 0) {\n // Show sessions list\n const sessionList = sessions.map(s => ` - ${s}`).join('\\n');\n setMessages((prev) => [\n ...prev,\n {\n id: `session-list-${Date.now()}`,\n role: \"assistant\",\n content: `Saved sessions:\\n${sessionList}`,\n timestamp: new Date(),\n },\n ]);\n } else {\n setMessages((prev) => [\n ...prev,\n {\n id: `session-list-empty-${Date.now()}`,\n role: \"assistant\",\n content: \"No saved sessions\",\n timestamp: new Date(),\n },\n ]);\n }\n } else {\n setMessages((prev) => [\n ...prev,\n {\n id: `session-error-${Date.now()}`,\n role: \"assistant\",\n content: \"Checkpointing not enabled. Use --session to enable.\",\n timestamp: new Date(),\n },\n ]);\n }\n break;\n\n case \"session\":\n if (!args) {\n setMessages((prev) => [\n ...prev,\n {\n id: `session-usage-${Date.now()}`,\n role: \"assistant\",\n content: \"Usage: /session clear\",\n timestamp: new Date(),\n },\n ]);\n return;\n }\n if (args.trim() === \"clear\" && options.session && checkpointer) {\n await checkpointer.delete(options.session);\n setMessages([]);\n agent.clear();\n setShowWelcome(true);\n setPanel({ view: \"none\" });\n setMessages((prev) => [\n ...prev,\n {\n id: `session-cleared-${Date.now()}`,\n role: \"assistant\",\n content: \"Session cleared.\",\n timestamp: new Date(),\n },\n ]);\n }\n break;\n\n case \"clear\":\n case \"c\":\n setMessages([]);\n agent.clear();\n setShowWelcome(true);\n setPanel({ view: \"none\" });\n break;\n\n case \"cache\":\n if (args === \"on\" || args === \"true\" || args === \"1\") {\n agent.setPromptCaching(true);\n } else if (args === \"off\" || args === \"false\" || args === \"0\") {\n agent.setPromptCaching(false);\n } else {\n // Toggle if no arg\n agent.setPromptCaching(!agent.features.promptCaching);\n }\n setPanel({ view: \"features\" });\n break;\n\n case \"eviction\":\n case \"evict\":\n if (args === \"on\" || args === \"true\" || args === \"1\") {\n agent.setEviction(true);\n } else if (args === \"off\" || args === \"false\" || args === \"0\") {\n agent.setEviction(false);\n } else {\n // Toggle if no arg\n agent.setEviction(!agent.features.eviction);\n }\n setPanel({ view: \"features\" });\n break;\n\n case \"summarize\":\n case \"sum\":\n if (args === \"on\" || args === \"true\" || args === \"1\") {\n agent.setSummarization(true);\n } else if (args === \"off\" || args === \"false\" || args === \"0\") {\n agent.setSummarization(false);\n } else {\n // Toggle if no arg\n agent.setSummarization(!agent.features.summarization);\n }\n setPanel({ view: \"features\" });\n break;\n\n case \"approve\":\n const newValue = !agent.autoApproveEnabled;\n agent.setAutoApprove(newValue);\n // Show a brief message (could be improved with a toast/notification)\n return;\n\n case \"help\":\n case \"h\":\n case \"?\":\n setPanel({ view: \"help\" });\n break;\n\n case \"quit\":\n case \"exit\":\n case \"q\":\n exit();\n break;\n\n case \"state\":\n // Debug command\n console.log(JSON.stringify(agent.state, null, 2));\n break;\n }\n };\n\n const isGenerating = agent.status !== \"idle\" && agent.status !== \"done\" && agent.status !== \"error\";\n \n // Disable input when in interactive panels that capture keyboard input\n const isInteractivePanel = panel.view === \"apikey-input\" || panel.view === \"models\";\n const isInputDisabled = isGenerating || isInteractivePanel;\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n {/* Welcome banner */}\n {showWelcome && (\n <>\n <Welcome model={agent.currentModel} workDir={options.workDir || process.cwd()} />\n <WelcomeHint />\n </>\n )}\n\n {/* Panel views */}\n {panel.view === \"help\" && <SlashMenuPanel />}\n {panel.view === \"todos\" && <TodoList todos={agent.state.todos} />}\n {panel.view === \"files\" && panel.files && <FileList files={panel.files} />}\n {panel.view === \"file-content\" && panel.filePath && panel.fileContent && (\n <FilePreview path={panel.filePath} content={panel.fileContent} />\n )}\n {panel.view === \"apikey-input\" && (\n <ApiKeyInputPanel\n onKeySaved={() => {\n // Key saved, returns to provider selection automatically\n }}\n onClose={() => setPanel({ view: \"none\" })}\n />\n )}\n {panel.view === \"features\" && <FeaturesPanel features={agent.features} options={options} />}\n {panel.view === \"tokens\" && <TokensPanel tokenCount={panel.tokenCount || 0} messageCount={agent.messages.length} />}\n {panel.view === \"models\" && (\n <ModelSelectionPanel\n currentModel={agent.currentModel}\n onModelSelect={(modelId) => {\n agent.setModel(modelId);\n }}\n onClose={() => setPanel({ view: \"none\" })}\n />\n )}\n\n {/* Agent events in chronological order (includes text-segments) */}\n {/* Always show events - they persist after generation completes */}\n {agent.events.length > 0 && (\n <Box flexDirection=\"column\">\n {agent.events.map((event) => (\n <EventRenderer key={event.id} event={event} />\n ))}\n </Box>\n )}\n\n {/* Current generation indicators */}\n {isGenerating && (\n <Box flexDirection=\"column\">\n {/* Currently streaming text (not yet flushed to a text-segment) */}\n {agent.streamingText && (\n <Box marginY={1}>\n <Box>\n <Text color={colors.success}>{\"● \"}</Text>\n <Text>\n {agent.streamingText}\n <Text color={colors.muted}>▌</Text>\n </Text>\n </Box>\n </Box>\n )}\n\n {/* Loading indicator when thinking or executing tools */}\n {(agent.status === \"thinking\" || agent.status === \"tool-call\") && !agent.streamingText && (\n <Box marginY={1}>\n <ThinkingIndicator />\n </Box>\n )}\n </Box>\n )}\n\n {/* Error display */}\n {agent.error && <ErrorDisplay error={agent.error} />}\n\n {/* Approval UI - show when pending and not in auto-approve mode */}\n {agent.pendingApproval && !agent.autoApproveEnabled && (\n <ToolApproval\n toolName={agent.pendingApproval.toolName}\n args={agent.pendingApproval.args}\n onApprove={() => agent.respondToApproval(true)}\n onDeny={() => agent.respondToApproval(false)}\n onApproveAll={() => {\n agent.setAutoApprove(true);\n agent.respondToApproval(true);\n }}\n />\n )}\n\n {/* Input - hidden when interactive panels are active */}\n {!isInteractivePanel && (\n <Box marginTop={1}>\n <Input onSubmit={handleSubmit} disabled={isGenerating} />\n </Box>\n )}\n\n {/* Compact status bar at bottom */}\n <StatusBar\n workDir={options.workDir || process.cwd()}\n model={agent.currentModel}\n status={agent.status}\n features={agent.features}\n autoApproveEnabled={agent.autoApproveEnabled}\n sessionId={options.session}\n />\n </Box>\n );\n}\n\n// ============================================================================\n// Event Renderer\n// ============================================================================\n\ninterface EventRendererProps {\n event: AgentEventLog;\n}\n\n// Tools that have their own specific events - don't show generic tool-call for these\nconst TOOLS_WITH_SPECIFIC_EVENTS = new Set([\n \"read_file\",\n \"ls\",\n \"glob\",\n \"grep\",\n \"write_file\",\n \"edit_file\",\n \"write_todos\",\n \"web_search\",\n \"http_request\",\n \"fetch_url\",\n]);\n\nfunction EventRenderer({ event }: EventRendererProps): React.ReactElement | null {\n const e = event.event;\n\n switch (e.type) {\n case \"user-message\":\n // Render user message in history\n return (\n <Box marginBottom={1}>\n <Text color={colors.muted} bold>{\"> \"}</Text>\n <Text bold>{e.content}</Text>\n </Box>\n );\n\n case \"text-segment\":\n // Render accumulated text segment\n if (!e.text.trim()) return null;\n return (\n <Box marginY={1}>\n <Box>\n <Text color={colors.success}>{\"● \"}</Text>\n <Text>{e.text}</Text>\n </Box>\n </Box>\n );\n\n case \"step-start\":\n return (\n <Box marginTop={1}>\n <Text color={colors.muted}>─── step {e.stepNumber} ───</Text>\n </Box>\n );\n\n case \"tool-call\":\n // Skip generic tool-call display for tools that have specific events\n if (TOOLS_WITH_SPECIFIC_EVENTS.has(e.toolName)) {\n return null;\n }\n return <ToolCall toolName={e.toolName} isExecuting={true} />;\n\n case \"todos-changed\":\n return (\n <Box>\n <Text color={colors.info}>📋 Todos: </Text>\n <Text dimColor>\n {e.todos.filter((t) => t.status === \"completed\").length}/{e.todos.length} completed\n </Text>\n </Box>\n );\n\n case \"file-write-start\":\n return <FilePreview path={e.path} content={e.content} isWrite={true} maxLines={10} />;\n\n case \"file-written\":\n return <FileWritten path={e.path} />;\n\n case \"file-edited\":\n return <FileEdited path={e.path} occurrences={e.occurrences} />;\n\n case \"file-read\":\n return <FileRead path={e.path} lines={e.lines} />;\n\n case \"ls\":\n return <LsResult path={e.path} count={e.count} />;\n\n case \"glob\":\n return <GlobResult pattern={e.pattern} count={e.count} />;\n\n case \"grep\":\n return <GrepResult pattern={e.pattern} count={e.count} />;\n\n case \"web-search-start\":\n return (\n <Box>\n <Text color={colors.info}>🔍 </Text>\n <Text>Searching web: </Text>\n <Text color={colors.muted}>{e.query}</Text>\n </Box>\n );\n\n case \"web-search-finish\":\n return (\n <Box>\n <Text color={colors.success}>✓ </Text>\n <Text>Found </Text>\n <Text color={colors.info}>{e.resultCount}</Text>\n <Text> results</Text>\n </Box>\n );\n\n case \"http-request-start\":\n return (\n <Box>\n <Text color={colors.info}>🌐 </Text>\n <Text>{e.method} </Text>\n <Text color={colors.muted}>{e.url}</Text>\n </Box>\n );\n\n case \"http-request-finish\":\n return (\n <Box>\n <Text color={e.statusCode >= 200 && e.statusCode < 300 ? colors.success : colors.error}>\n {e.statusCode >= 200 && e.statusCode < 300 ? \"✓\" : \"✗\"}{\" \"}\n </Text>\n <Text>Status: </Text>\n <Text color={e.statusCode >= 200 && e.statusCode < 300 ? colors.success : colors.error}>\n {e.statusCode}\n </Text>\n </Box>\n );\n\n case \"fetch-url-start\":\n return (\n <Box>\n <Text color={colors.info}>📄 </Text>\n <Text>Fetching: </Text>\n <Text color={colors.muted}>{e.url}</Text>\n </Box>\n );\n\n case \"fetch-url-finish\":\n return (\n <Box>\n <Text color={e.success ? colors.success : colors.error}>\n {e.success ? \"✓\" : \"✗\"}{\" \"}\n </Text>\n <Text>{e.success ? \"Content fetched\" : \"Failed to fetch\"}</Text>\n </Box>\n );\n\n case \"subagent-start\":\n return <SubagentStart name={e.name} task={e.task} />;\n\n case \"subagent-finish\":\n return <SubagentFinish name={e.name} />;\n\n case \"done\":\n return (\n <DoneIndicator\n todosCompleted={e.state.todos.filter((t) => t.status === \"completed\").length}\n todosTotal={e.state.todos.length}\n filesCount={Object.keys(e.state.files).length}\n />\n );\n\n case \"error\":\n return <ErrorDisplay error={e.error} />;\n\n default:\n return null;\n }\n}\n\n// ============================================================================\n// Features Panel\n// ============================================================================\n\ninterface FeaturesPanelProps {\n features: {\n promptCaching: boolean;\n eviction: boolean;\n summarization: boolean;\n };\n options: CLIOptions;\n}\n\nfunction FeaturesPanel({ features, options }: FeaturesPanelProps): React.ReactElement {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n ⚙️ Feature Status\n </Text>\n <Box height={1} />\n <Box>\n {features.promptCaching ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>Prompt Caching: </Text>\n <Text color={colors.success}>enabled</Text>\n </>\n ) : (\n <>\n <Text dimColor>✗ </Text>\n <Text>Prompt Caching: </Text>\n <Text dimColor>disabled</Text>\n </>\n )}\n </Box>\n <Box>\n {features.eviction ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>Tool Eviction: </Text>\n <Text color={colors.success}>enabled ({options.toolResultEvictionLimit} tokens)</Text>\n </>\n ) : (\n <>\n <Text dimColor>✗ </Text>\n <Text>Tool Eviction: </Text>\n <Text dimColor>disabled</Text>\n </>\n )}\n </Box>\n <Box>\n {features.summarization ? (\n <>\n <Text color={colors.success}>✓ </Text>\n <Text>Auto-Summarization: </Text>\n <Text color={colors.success}>\n enabled ({options.summarizationThreshold || DEFAULT_SUMMARIZATION_THRESHOLD} tokens, keep {options.summarizationKeepMessages || DEFAULT_KEEP_MESSAGES} msgs)\n </Text>\n </>\n ) : (\n <>\n <Text dimColor>✗ </Text>\n <Text>Auto-Summarization: </Text>\n <Text dimColor>disabled</Text>\n </>\n )}\n </Box>\n <Box height={1} />\n <Text dimColor>Enable with: --cache --eviction-limit {DEFAULT_EVICTION_LIMIT} --summarize</Text>\n </Box>\n );\n}\n\n// ============================================================================\n// Tokens Panel\n// ============================================================================\n\ninterface TokensPanelProps {\n tokenCount: number;\n messageCount: number;\n}\n\nfunction TokensPanel({ tokenCount, messageCount }: TokensPanelProps): React.ReactElement {\n const formatNumber = (n: number) => n.toLocaleString();\n\n // Estimate percentage of typical context window\n const percentage = Math.round((tokenCount / CONTEXT_WINDOW) * 100);\n \n // Color based on usage\n let usageColor: string = colors.success;\n if (percentage > 80) {\n usageColor = colors.error;\n } else if (percentage > 50) {\n usageColor = colors.warning;\n }\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderColor={colors.muted}\n paddingX={2}\n paddingY={1}\n marginY={1}\n >\n <Text bold color={colors.info}>\n 📊 Token Usage\n </Text>\n <Box height={1} />\n <Box>\n <Text>Messages: </Text>\n <Text color={colors.primary}>{messageCount}</Text>\n </Box>\n <Box>\n <Text>Estimated Tokens: </Text>\n <Text color={usageColor}>{formatNumber(tokenCount)}</Text>\n </Box>\n <Box>\n <Text>Context Usage: </Text>\n <Text color={usageColor}>{percentage}%</Text>\n <Text dimColor> (of ~200k)</Text>\n </Box>\n <Box height={1} />\n {percentage > 50 && (\n <Text color={colors.warning}>\n ⚠️ Consider enabling --summarize to manage context\n </Text>\n )}\n </Box>\n );\n}\n\n// ============================================================================\n// Environment Variable Loading\n// ============================================================================\n\ninterface EnvLoadResult {\n loaded: boolean;\n path?: string;\n keysFound: string[];\n}\n\n/**\n * Load environment variables from .env file in the working directory.\n * Bun automatically loads .env from cwd, but we want to also check the\n * specified working directory if different.\n */\nasync function loadEnvFile(workDir: string): Promise<EnvLoadResult> {\n const envPaths = [\n `${workDir}/.env`,\n `${workDir}/.env.local`,\n ];\n \n const keysToCheck = ['ANTHROPIC_API_KEY', 'OPENAI_API_KEY'];\n const result: EnvLoadResult = { loaded: false, keysFound: [] };\n \n for (const envPath of envPaths) {\n try {\n const file = Bun.file(envPath);\n const exists = await file.exists();\n \n if (exists) {\n const content = await file.text();\n const lines = content.split('\\n');\n \n for (const line of lines) {\n const trimmed = line.trim();\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith('#')) continue;\n \n // Parse KEY=VALUE format\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);\n if (match) {\n const key = match[1];\n const rawValue = match[2];\n if (!key || rawValue === undefined) continue;\n \n // Remove quotes if present\n let value = rawValue.trim();\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n \n // Only set if not already set (env vars take precedence)\n if (!process.env[key] && value) {\n process.env[key] = value;\n if (keysToCheck.includes(key)) {\n result.keysFound.push(key);\n }\n }\n }\n }\n \n result.loaded = true;\n result.path = envPath;\n break; // Stop after first .env file found\n }\n } catch {\n // File doesn't exist or can't be read, continue\n }\n }\n \n // Check which keys are now available (from env or .env file)\n for (const key of keysToCheck) {\n if (process.env[key] && !result.keysFound.includes(key)) {\n // Key was already in environment\n }\n }\n \n return result;\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\nasync function main() {\n const options = parseArgs();\n const workDir = options.workDir || process.cwd();\n\n // Load .env file from working directory\n const envResult = await loadEnvFile(workDir);\n \n // Show env loading info\n if (envResult.loaded && envResult.keysFound.length > 0) {\n console.log(`\\x1b[32m✓\\x1b[0m Loaded API keys from ${envResult.path}: ${envResult.keysFound.join(', ')}`);\n }\n \n // Warn if no API keys found\n if (!process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) {\n console.log(`\\x1b[33m⚠\\x1b[0m No API keys found. Set ANTHROPIC_API_KEY or OPENAI_API_KEY in environment or .env file.`);\n }\n\n const backend = new LocalSandbox({\n cwd: workDir,\n });\n\n render(<App options={options} backend={backend} />);\n}\n\nmain();\n\n"],"mappings":"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"}